package BACK import chisel3._ import chisel3.util._ class SMUnitIO extends Bundle { val maxLen = Input(UInt(11.W)) val enq = Flipped(Decoupled(UInt(8.W))) val deq = Decoupled(UInt(8.W)) } abstract class SMUnitBase extends Module { val io: SMUnitIO = IO(new SMUnitIO) val enqCnt = Reg(UInt(11.W)) val deqCnt = Reg(UInt(11.W)) val dataBuf = for ( _ <- until 4 ) yield { Module( new Queue(UInt(8.W), 2048, useSyncReadMem = true) ) } val wPtr = RegInit(0.U((2+1).W)) val rPtr = RegInit(0.U((2+1).W)) val isFull = ( wPtr.extract(2) =/= rPtr.extract(2) ) & ( wPtr(1,0) === rPtr(1,0) ) val isEmpty = ( wPtr === rPtr ) when( io.enq.fire ){ when( enqCnt === io.maxLen ){ enqCnt := 0.U } .otherwise{ enqCnt := enqCnt + 1.U } } when( io.deq.fire ){ when( deqCnt === io.maxLen ){ deqCnt := 0.U } .otherwise{ deqCnt := deqCnt + 1.U } } when( io.enq.fire & enqCnt === io.maxLen ){ wPtr := wPtr + 1.U } when( io.deq.fire & deqCnt === io.maxLen ){ rPtr := rPtr + 1.U } when( wPtr === 0.U & ~isFull ){ dataBuf(0).io.enq.valid := io.enq.valid dataBuf(0).io.enq.bits := io.enq.bits io.enq.ready := dataBuf(0).io.enq.ready dataBuf(1).io.enq.valid := false.B dataBuf(1).io.enq.bits := 0.U dataBuf(2).io.enq.valid := false.B dataBuf(2).io.enq.bits := 0.U dataBuf(3).io.enq.valid := false.B dataBuf(3).io.enq.bits := 0.U } .elsewhen( wPtr === 1.U & ~isFull ){ dataBuf(1).io.enq.valid := io.enq.valid dataBuf(1).io.enq.bits := io.enq.bits io.enq.ready := dataBuf(1).io.enq.ready dataBuf(0).io.enq.valid := false.B dataBuf(0).io.enq.bits := 0.U dataBuf(2).io.enq.valid := false.B dataBuf(2).io.enq.bits := 0.U dataBuf(3).io.enq.valid := false.B dataBuf(3).io.enq.bits := 0.U } .elsewhen( wPtr === 2.U & ~isFull ){ dataBuf(2).io.enq.valid := io.enq.valid dataBuf(2).io.enq.bits := io.enq.bits io.enq.ready := dataBuf(2).io.enq.ready dataBuf(0).io.enq.valid := false.B dataBuf(0).io.enq.bits := 0.U dataBuf(1).io.enq.valid := false.B dataBuf(1).io.enq.bits := 0.U dataBuf(3).io.enq.valid := false.B dataBuf(3).io.enq.bits := 0.U } .elsewhen( wPtr === 3.U & ~isFull ){ dataBuf(3).io.enq.valid := io.enq.valid dataBuf(3).io.enq.bits := io.enq.bits io.enq.ready := dataBuf(3).io.enq.ready dataBuf(0).io.enq.valid := false.B dataBuf(0).io.enq.bits := 0.U dataBuf(1).io.enq.valid := false.B dataBuf(1).io.enq.bits := 0.U dataBuf(2).io.enq.valid := false.B dataBuf(2).io.enq.bits := 0.U } .otherwise{ io.enq.ready := false.B dataBuf(0).io.enq.valid := false.B dataBuf(0).io.enq.bits := 0.U dataBuf(1).io.enq.valid := false.B dataBuf(1).io.enq.bits := 0.U dataBuf(2).io.enq.valid := false.B dataBuf(2).io.enq.bits := 0.U dataBuf(3).io.enq.valid := false.B dataBuf(3).io.enq.bits := 0.U } when( rPtr === 0.U & ~isEmpty){ io.deq.valid := dataBuf(0).io.deq.valid io.deq.bits := dataBuf(0).io.deq.bits dataBuf(0).io.deq.ready := io.deq.ready dataBuf(1).io.deq.ready := false.B dataBuf(2).io.deq.ready := false.B dataBuf(3).io.deq.ready := false.B } .elsewhen( rPtr === 1.U & ~isEmpty){ io.deq.valid := dataBuf(1).io.deq.valid io.deq.bits := dataBuf(1).io.deq.bits dataBuf(0).io.deq.ready := false.B dataBuf(1).io.deq.ready := io.deq.ready dataBuf(2).io.deq.ready := false.B dataBuf(3).io.deq.ready := false.B } .elsewhen( rPtr === 2.U & ~isEmpty){ io.deq.valid := dataBuf(2).io.deq.valid io.deq.bits := dataBuf(2).io.deq.bits dataBuf(0).io.deq.ready := false.B dataBuf(1).io.deq.ready := false.B dataBuf(2).io.deq.ready := io.deq.ready dataBuf(3).io.deq.ready := false.B } .elsewhen( rPtr === 3.U & ~isEmpty){ io.deq.valid := dataBuf(3).io.deq.valid io.deq.bits := dataBuf(3).io.deq.bits dataBuf(0).io.deq.ready := false.B dataBuf(1).io.deq.ready := false.B dataBuf(2).io.deq.ready := false.B dataBuf(3).io.deq.ready := io.deq.ready } .otherwise{ io.deq.valid := false.B io.deq.bits := 0.U dataBuf(0).io.deq.ready := false.B dataBuf(1).io.deq.ready := false.B dataBuf(2).io.deq.ready := false.B dataBuf(3).io.deq.ready := io.deq.ready } } class SMUnit extends SMUnitBase { }