1c6d43980SLemover/*************************************************************************************** 2c6d43980SLemover* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences 3f320e0f0SYinan Xu* Copyright (c) 2020-2021 Peng Cheng Laboratory 4c6d43980SLemover* 5c6d43980SLemover* XiangShan is licensed under Mulan PSL v2. 6c6d43980SLemover* You can use this software according to the terms and conditions of the Mulan PSL v2. 7c6d43980SLemover* You may obtain a copy of Mulan PSL v2 at: 8c6d43980SLemover* http://license.coscl.org.cn/MulanPSL2 9c6d43980SLemover* 10c6d43980SLemover* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 11c6d43980SLemover* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 12c6d43980SLemover* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 13c6d43980SLemover* 14c6d43980SLemover* See the Mulan PSL v2 for more details. 15c6d43980SLemover***************************************************************************************/ 16c6d43980SLemover 17e18c367fSLinJiaweipackage xiangshan.backend.fu 182f99f1bbSAllen 198891a219SYinan Xuimport org.chipsalliance.cde.config.Parameters 202f99f1bbSAllenimport chisel3._ 212f99f1bbSAllenimport chisel3.util._ 222f99f1bbSAllenimport xiangshan._ 232f99f1bbSAllenimport utils._ 243c02ee8fSwakafaimport utility._ 25*d0de7e4aSpeixiaokunimport xiangshan.ExceptionNO.{illegalInstr, virtualInstr} 262f99f1bbSAllen 272225d46eSJiawei Linclass FenceToSbuffer extends Bundle { 282fdc488aSLinJiawei val flushSb = Output(Bool()) 292fdc488aSLinJiawei val sbIsEmpty = Input(Bool()) 302fdc488aSLinJiawei} 312fdc488aSLinJiawei 326ab6918fSYinan Xuclass Fence(implicit p: Parameters) extends FunctionUnit { 332fdc488aSLinJiawei 342fdc488aSLinJiawei val sfence = IO(Output(new SfenceBundle)) 352fdc488aSLinJiawei val fencei = IO(Output(Bool())) 362fdc488aSLinJiawei val toSbuffer = IO(new FenceToSbuffer) 37b37cea47SLemover val disableSfence = IO(Input(Bool())) 38*d0de7e4aSpeixiaokun val disableHfenceg = IO(Input(Bool())) 39*d0de7e4aSpeixiaokun val disableHfencev = IO(Input(Bool())) 40*d0de7e4aSpeixiaokun val virtMode = IO(Input(Bool())) 41af2f7849Shappy-lx val (valid, src1) = ( 42af2f7849Shappy-lx io.in.valid, 43af2f7849Shappy-lx io.in.bits.src(0) 44af2f7849Shappy-lx ) 45af2f7849Shappy-lx 46af2f7849Shappy-lx val s_idle :: s_wait :: s_tlb :: s_icache :: s_fence :: s_nofence :: Nil = Enum(6) 47af2f7849Shappy-lx 48de39f54aSZhangZifei val state = RegInit(s_idle) 49de39f54aSZhangZifei /* fsm 50de39f54aSZhangZifei * s_idle : init state, send sbflush 51de39f54aSZhangZifei * s_wait : send sbflush, wait for sbEmpty 52de39f54aSZhangZifei * s_tlb : flush tlb, just hold one cycle 53de39f54aSZhangZifei * s_icache: flush icache, just hold one cycle 54de39f54aSZhangZifei * s_fence : do nothing, for timing optimiaztion 55af2f7849Shappy-lx * s_nofence: do nothing , for Svinval extension 56de39f54aSZhangZifei */ 572f99f1bbSAllen 582fdc488aSLinJiawei val sbuffer = toSbuffer.flushSb 592fdc488aSLinJiawei val sbEmpty = toSbuffer.sbIsEmpty 60935edac4STang Haojin val uop = RegEnable(io.in.bits.uop, io.in.fire) 61de39f54aSZhangZifei val func = uop.ctrl.fuOpType 622fdc488aSLinJiawei 63b8f08ca0SZhangZifei // NOTE: icache & tlb & sbuffer must receive flush signal at any time 64b37cea47SLemover sbuffer := state === s_wait && !(func === FenceOpType.sfence && disableSfence) 65de39f54aSZhangZifei fencei := state === s_icache 66*d0de7e4aSpeixiaokun sfence.valid := state === s_tlb && ((!disableSfence && func === FenceOpType.sfence) || (!disableHfencev && func === FenceOpType.hfence_v) || (!disableHfenceg && func === FenceOpType.hfence_g)) 67a020ce37SYinan Xu sfence.bits.rs1 := uop.ctrl.imm(4, 0) === 0.U 68a020ce37SYinan Xu sfence.bits.rs2 := uop.ctrl.imm(9, 5) === 0.U 69f1fe8698SLemover sfence.bits.flushPipe := uop.ctrl.flushPipe 70*d0de7e4aSpeixiaokun sfence.bits.hv := !disableHfencev && func === FenceOpType.hfence_v 71*d0de7e4aSpeixiaokun sfence.bits.hg := !disableHfenceg && func === FenceOpType.hfence_g 72a020ce37SYinan Xu XSError(sfence.valid && uop.ctrl.lsrc(0) =/= uop.ctrl.imm(4, 0), "lsrc0 is passed by imm\n") 73a020ce37SYinan Xu XSError(sfence.valid && uop.ctrl.lsrc(1) =/= uop.ctrl.imm(9, 5), "lsrc1 is passed by imm\n") 74935edac4STang Haojin sfence.bits.addr := RegEnable(io.in.bits.src(0), io.in.fire) 75935edac4STang Haojin sfence.bits.asid := RegEnable(io.in.bits.src(1), io.in.fire) 76b8f08ca0SZhangZifei 77a020ce37SYinan Xu when (state === s_idle && io.in.valid) { state := s_wait } 78de39f54aSZhangZifei when (state === s_wait && func === FenceOpType.fencei && sbEmpty) { state := s_icache } 79*d0de7e4aSpeixiaokun when (state === s_wait && ((func === FenceOpType.sfence && (sbEmpty || disableSfence)) 80*d0de7e4aSpeixiaokun || (func === FenceOpType.hfence_g && (sbEmpty || disableHfenceg)) 81*d0de7e4aSpeixiaokun || (func === FenceOpType.hfence_v && (sbEmpty || disableHfencev)))) { state := s_tlb } 82de39f54aSZhangZifei when (state === s_wait && func === FenceOpType.fence && sbEmpty) { state := s_fence } 83af2f7849Shappy-lx when (state === s_wait && func === FenceOpType.nofence && sbEmpty) { state := s_nofence } 84de39f54aSZhangZifei when (state =/= s_idle && state =/= s_wait) { state := s_idle } 85de39f54aSZhangZifei 86de39f54aSZhangZifei io.in.ready := state === s_idle 87de39f54aSZhangZifei io.out.valid := state =/= s_idle && state =/= s_wait 88de39f54aSZhangZifei io.out.bits.data := DontCare 89de39f54aSZhangZifei io.out.bits.uop := uop 90*d0de7e4aSpeixiaokun val illegalsfence = func === FenceOpType.sfence && disableSfence 91*d0de7e4aSpeixiaokun val illegalhfenceg = func === FenceOpType.hfence_g && disableHfenceg 92*d0de7e4aSpeixiaokun val illegalhfencev = func === FenceOpType.hfence_v && disableHfencev 93*d0de7e4aSpeixiaokun io.out.bits.uop.cf.exceptionVec(illegalInstr) := (illegalsfence || illegalhfenceg || illegalhfencev) && !virtMode 94*d0de7e4aSpeixiaokun io.out.bits.uop.cf.exceptionVec(virtualInstr) := (illegalsfence || illegalhfenceg || illegalhfencev) && virtMode 95de39f54aSZhangZifei 96a020ce37SYinan Xu XSDebug(io.in.valid, p"In(${io.in.valid} ${io.in.ready}) state:${state} Inpc:0x${Hexadecimal(io.in.bits.uop.cf.pc)} InrobIdx:${io.in.bits.uop.robIdx}\n") 97de39f54aSZhangZifei XSDebug(state =/= s_idle, p"state:${state} sbuffer(flush:${sbuffer} empty:${sbEmpty}) fencei:${fencei} sfence:${sfence}\n") 989aca92b9SYinan Xu XSDebug(io.out.valid, p" Out(${io.out.valid} ${io.out.ready}) state:${state} Outpc:0x${Hexadecimal(io.out.bits.uop.cf.pc)} OutrobIdx:${io.out.bits.uop.robIdx}\n") 992f99f1bbSAllen 100b8f08ca0SZhangZifei assert(!(io.out.valid && io.out.bits.uop.ctrl.rfWen)) 101de39f54aSZhangZifei assert(!io.out.valid || io.out.ready, "when fence is out valid, out ready should always be true") 1022f99f1bbSAllen} 103