1package xiangshan.backend.fu 2 3import chisel3._ 4import chisel3.util._ 5import xiangshan._ 6import utils._ 7import xiangshan.backend.FenceOpType 8 9class FenceToSbuffer extends XSBundle { 10 val flushSb = Output(Bool()) 11 val sbIsEmpty = Input(Bool()) 12} 13 14// class Fence extends FunctionUnit(FuConfig( 15 // /*FuType.fence, 1, 0, writeIntRf = false, writeFpRf = false, hasRedirect = false,*/ latency = UncertainLatency() 16// )){ 17class Fence extends FunctionUnit{ // TODO: check it 18 19 val sfence = IO(Output(new SfenceBundle)) 20 val fencei = IO(Output(Bool())) 21 val toSbuffer = IO(new FenceToSbuffer) 22 23 val (valid, src1) = ( 24 io.in.valid, 25 io.in.bits.src(0) 26 ) 27 28 val s_idle :: s_wait :: s_tlb :: s_icache :: s_fence :: Nil = Enum(5) 29 val state = RegInit(s_idle) 30 /* fsm 31 * s_idle : init state, send sbflush 32 * s_wait : send sbflush, wait for sbEmpty 33 * s_tlb : flush tlb, just hold one cycle 34 * s_icache: flush icache, just hold one cycle 35 * s_fence : do nothing, for timing optimiaztion 36 */ 37 38 val sbuffer = toSbuffer.flushSb 39 val sbEmpty = toSbuffer.sbIsEmpty 40 val uop = RegEnable(io.in.bits.uop, io.in.fire()) 41 val func = uop.ctrl.fuOpType 42 val lsrc1 = uop.ctrl.lsrc1 43 val lsrc2 = uop.ctrl.lsrc2 44 45 // NOTE: icache & tlb & sbuffer must receive flush signal at any time 46 sbuffer := state === s_wait 47 fencei := state === s_icache 48 sfence.valid := state === s_tlb 49 sfence.bits.rs1 := lsrc1 === 0.U 50 sfence.bits.rs2 := lsrc2 === 0.U 51 sfence.bits.addr := RegEnable(src1, io.in.fire()) 52 53 when (state === s_idle && valid) { state := s_wait } 54 when (state === s_wait && func === FenceOpType.fencei && sbEmpty) { state := s_icache } 55 when (state === s_wait && func === FenceOpType.sfence && sbEmpty) { state := s_tlb } 56 when (state === s_wait && func === FenceOpType.fence && sbEmpty) { state := s_fence } 57 when (state =/= s_idle && state =/= s_wait) { state := s_idle } 58 59 io.in.ready := state === s_idle 60 io.out.valid := state =/= s_idle && state =/= s_wait 61 io.out.bits.data := DontCare 62 io.out.bits.uop := uop 63 64 XSDebug(valid, p"In(${io.in.valid} ${io.in.ready}) state:${state} Inpc:0x${Hexadecimal(io.in.bits.uop.cf.pc)} InroqIdx:${io.in.bits.uop.roqIdx}\n") 65 XSDebug(state =/= s_idle, p"state:${state} sbuffer(flush:${sbuffer} empty:${sbEmpty}) fencei:${fencei} sfence:${sfence}\n") 66 XSDebug(io.out.valid, p" Out(${io.out.valid} ${io.out.ready}) state:${state} Outpc:0x${Hexadecimal(io.out.bits.uop.cf.pc)} OutroqIdx:${io.out.bits.uop.roqIdx}\n") 67 68 assert(!(io.out.valid && io.out.bits.uop.ctrl.rfWen)) 69 assert(!io.out.valid || io.out.ready, "when fence is out valid, out ready should always be true") 70}