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 192f99f1bbSAllenimport chisel3._ 202f99f1bbSAllenimport chisel3.util._ 21b6262ab3SXuan Huimport org.chipsalliance.cde.config.Parameters 22b6262ab3SXuan Huimport utility.XSDebug 23d0de7e4aSpeixiaokunimport xiangshan.ExceptionNO.{illegalInstr, virtualInstr} 243b739f49SXuan Huimport xiangshan._ 252f99f1bbSAllen 26124bf66aSXuan Huclass FenceIO(implicit p: Parameters) extends XSBundle { 27124bf66aSXuan Hu val sfence = Output(new SfenceBundle) 28124bf66aSXuan Hu val fencei = Output(Bool()) 29124bf66aSXuan Hu val sbuffer = new FenceToSbuffer 30124bf66aSXuan Hu} 31124bf66aSXuan Hu 322225d46eSJiawei Linclass FenceToSbuffer extends Bundle { 332fdc488aSLinJiawei val flushSb = Output(Bool()) 342fdc488aSLinJiawei val sbIsEmpty = Input(Bool()) 352fdc488aSLinJiawei} 362fdc488aSLinJiawei 373b739f49SXuan Huclass Fence(cfg: FuConfig)(implicit p: Parameters) extends FuncUnit(cfg) { 382fdc488aSLinJiawei 393b739f49SXuan Hu val sfence = io.fenceio.get.sfence 403b739f49SXuan Hu val fencei = io.fenceio.get.fencei 413b739f49SXuan Hu val toSbuffer = io.fenceio.get.sbuffer 42af2f7849Shappy-lx val (valid, src1) = ( 43af2f7849Shappy-lx io.in.valid, 446a35d972SXuan Hu io.in.bits.data.src(0) 45af2f7849Shappy-lx ) 46af2f7849Shappy-lx 47af2f7849Shappy-lx val s_idle :: s_wait :: s_tlb :: s_icache :: s_fence :: s_nofence :: Nil = Enum(6) 48af2f7849Shappy-lx 49de39f54aSZhangZifei val state = RegInit(s_idle) 50de39f54aSZhangZifei /* fsm 51de39f54aSZhangZifei * s_idle : init state, send sbflush 52de39f54aSZhangZifei * s_wait : send sbflush, wait for sbEmpty 53de39f54aSZhangZifei * s_tlb : flush tlb, just hold one cycle 54de39f54aSZhangZifei * s_icache: flush icache, just hold one cycle 55de39f54aSZhangZifei * s_fence : do nothing, for timing optimiaztion 56af2f7849Shappy-lx * s_nofence: do nothing , for Svinval extension 57de39f54aSZhangZifei */ 582f99f1bbSAllen 592fdc488aSLinJiawei val sbuffer = toSbuffer.flushSb 602fdc488aSLinJiawei val sbEmpty = toSbuffer.sbIsEmpty 613b739f49SXuan Hu val uop = RegEnable(io.in.bits, io.in.fire) 626a35d972SXuan Hu val func = uop.ctrl.fuOpType 632fdc488aSLinJiawei 64b8f08ca0SZhangZifei // NOTE: icache & tlb & sbuffer must receive flush signal at any time 652d3ae4b4SsinceforYy sbuffer := state === s_wait 66de39f54aSZhangZifei fencei := state === s_icache 672d3ae4b4SsinceforYy sfence.valid := state === s_tlb && (func === FenceOpType.sfence || func === FenceOpType.hfence_v || func === FenceOpType.hfence_g) 686a35d972SXuan Hu sfence.bits.rs1 := uop.data.imm(4, 0) === 0.U 696a35d972SXuan Hu sfence.bits.rs2 := uop.data.imm(9, 5) === 0.U 706a35d972SXuan Hu sfence.bits.flushPipe := uop.ctrl.flushPipe.get 712d3ae4b4SsinceforYy sfence.bits.hv := func === FenceOpType.hfence_v 722d3ae4b4SsinceforYy sfence.bits.hg := func === FenceOpType.hfence_g 734b0d80d8SXuan Hu sfence.bits.addr := RegEnable(io.in.bits.data.src(0), io.in.fire) 74e25e4d90SXuan Hu sfence.bits.id := RegEnable(io.in.bits.data.src(1), io.in.fire) 75b8f08ca0SZhangZifei 76a020ce37SYinan Xu when (state === s_idle && io.in.valid) { state := s_wait } 77de39f54aSZhangZifei when (state === s_wait && func === FenceOpType.fencei && sbEmpty) { state := s_icache } 782d3ae4b4SsinceforYy when (state === s_wait && ((func === FenceOpType.sfence || func === FenceOpType.hfence_g || func === FenceOpType.hfence_v) && sbEmpty)) { state := s_tlb } 79de39f54aSZhangZifei when (state === s_wait && func === FenceOpType.fence && sbEmpty) { state := s_fence } 80af2f7849Shappy-lx when (state === s_wait && func === FenceOpType.nofence && sbEmpty) { state := s_nofence } 81de39f54aSZhangZifei when (state =/= s_idle && state =/= s_wait) { state := s_idle } 82de39f54aSZhangZifei 83de39f54aSZhangZifei io.in.ready := state === s_idle 84de39f54aSZhangZifei io.out.valid := state =/= s_idle && state =/= s_wait 856a35d972SXuan Hu io.out.bits.res.data := 0.U 866a35d972SXuan Hu io.out.bits.ctrl.robIdx := uop.ctrl.robIdx 876a35d972SXuan Hu io.out.bits.ctrl.pdest := uop.ctrl.pdest 886a35d972SXuan Hu io.out.bits.ctrl.flushPipe.get := uop.ctrl.flushPipe.get 896a35d972SXuan Hu io.out.bits.ctrl.exceptionVec.get := 0.U.asTypeOf(io.out.bits.ctrl.exceptionVec.get) 9096e858baSXuan Hu io.out.bits.perfDebugInfo := io.in.bits.perfDebugInfo 91*1592abd1SYan Xu io.out.bits.debug_seqNum := io.in.bits.debug_seqNum 92de39f54aSZhangZifei 93c37914a4Sxiaofeibao XSDebug(io.in.valid, p"In(${io.in.valid} ${io.in.ready}) state:${state} InrobIdx:${io.in.bits.ctrl.robIdx}\n") 94de39f54aSZhangZifei XSDebug(state =/= s_idle, p"state:${state} sbuffer(flush:${sbuffer} empty:${sbEmpty}) fencei:${fencei} sfence:${sfence}\n") 95c37914a4Sxiaofeibao XSDebug(io.out.valid, p" Out(${io.out.valid} ${io.out.ready}) state:${state} OutrobIdx:${io.out.bits.ctrl.robIdx}\n") 962f99f1bbSAllen 97de39f54aSZhangZifei assert(!io.out.valid || io.out.ready, "when fence is out valid, out ready should always be true") 982f99f1bbSAllen} 99