1package xiangshan.backend.exu 2 3import chisel3._ 4import chisel3.util._ 5import xiangshan._ 6import utils._ 7import chisel3.util.experimental.BoringUtils 8 9import xiangshan.backend.MDUOpType 10 11class FenceExeUnit extends Exu(Exu.fenceExeUnitCfg) { 12 val (valid, src1, src2, uop, func, lsrc1, lsrc2) = 13 (io.in.valid, io.in.bits.src1, io.in.bits.src2, io.in.bits.uop, io.in.bits.uop.ctrl.fuOpType, io.in.bits.uop.ctrl.lsrc1, io.in.bits.uop.ctrl.lsrc2) 14 15 val s_req :: s_resp :: Nil = Enum(2) 16 val state = RegInit(s_req) 17 18 val sfence = WireInit(0.U.asTypeOf(new SfenceBundle)) 19 val sbuffer = WireInit(false.B) 20 val fencei = WireInit(false.B) 21 val sbEmpty = WireInit(false.B) 22 BoringUtils.addSource(sbuffer, "FenceUnitSbufferFlush") 23 BoringUtils.addSource(sfence, "SfenceBundle") 24 // BoringUtils.addSource(fencei, "FenceI") // TODO: uncomment it when merge icache 25 BoringUtils.addSink(sbEmpty, "SBufferEmpty") 26 // NOTE: icache & tlb & sbuffer must receive flush signal at any time 27 sbuffer := valid && state === s_req && !sbEmpty 28 fencei := valid && state === s_req && func === MDUOpType.fencei 29 sfence.valid := valid && state === s_req && func === MDUOpType.sfence 30 sfence.bits.rs1 := lsrc1 === 0.U 31 sfence.bits.rs2 := lsrc2 === 0.U 32 sfence.bits.addr := src1 33 34 switch (state) { 35 is (s_req) { // send all the flush at s_req 36 when (valid && (!sbEmpty || !io.out.ready)) { state := s_resp } 37 } 38 is (s_resp) { // wait for sbEmpty if send flush to sbuffer 39 when (sbEmpty && io.out.ready) { state := s_req } 40 } 41 } 42 43 assert(!(io.out.valid && io.out.bits.uop.ctrl.rfWen)) 44 io.in.ready := state === s_req 45 io.out.valid := (state === s_resp && sbEmpty) || (state === s_req && sbEmpty && valid) 46 io.out.bits.data := DontCare 47 io.out.bits.uop := Mux(state === s_req, uop, RegEnable(uop, io.in.fire())) 48 io.out.bits.redirect <> DontCare 49 io.out.bits.redirectValid := false.B 50 io.out.bits.debug <> DontCare 51 52 XSDebug(valid || state=/=s_resp, p"In(${io.in.valid} ${io.in.ready}) Out(${io.out.valid} ${io.out.ready}) sbuffer(flush:${sbuffer} empty:${sbEmpty}) fencei:${fencei} sfence:${sfence} Inpc:0x${Hexadecimal(io.in.bits.uop.cf.pc)} InroqIdx:${io.in.bits.uop.roqIdx} Outpc:0x${Hexadecimal(io.out.bits.uop.cf.pc)} OutroqIdx:${io.out.bits.uop.roqIdx}\n") 53}