Update rvv_idle signal to include frontend and fix mpause dispatch. Change-Id: I98c613ccf3609cbb4d8dccca7bd2c86a4d85c85f
diff --git a/hdl/chisel/src/kelvin/scalar/Decode.scala b/hdl/chisel/src/kelvin/scalar/Decode.scala index 828666c..5553453 100644 --- a/hdl/chisel/src/kelvin/scalar/Decode.scala +++ b/hdl/chisel/src/kelvin/scalar/Decode.scala
@@ -205,6 +205,12 @@ def isVector(): Bool = { vld || vst || viop || getvl || getmaxvl } def isFency(): Bool = { fencei || ebreak || wfi || mpause || flushat || flushall } + // Instructions that should dispatch out of slot 0, with no other instructions + // dispatched on the same cycle. + def forceSlot0Only(): Bool = { + isFency() || isCsr() + } + // Checks if an instruction is a jump or changes context switch. Instructions // after these should not be executed on the same cycle. def isJump(): Bool = { @@ -422,12 +428,12 @@ val fence = decodedInsts.map(x => x.isFency() && (io.mactive || io.lsuActive)) // --------------------------------------------------------------------------- - // Csr interlock - val csrInterlock = (0 until p.instructionLanes).map(i => + // Slot 0 interlock + val slot0Interlock = (0 until p.instructionLanes).map(i => if (i == 0) { true.B } else { - !decodedInsts(0).isCsr() + !decodedInsts(0).forceSlot0Only() && !decodedInsts(i).forceSlot0Only() } ) @@ -518,6 +524,10 @@ !io.single_step.getOrElse(false.B) || ((i == 0).B && coreIdle)) // --------------------------------------------------------------------------- + // MPAUSE + val mpauseInterlock = decodedInsts.map(x => (!x.mpause || coreIdle)) + + // --------------------------------------------------------------------------- // Combine above rules. This variable represents which instructions can be // dispatched before in-orderness and back-pressure are considered. val canDispatch = (0 until p.instructionLanes).map(i => @@ -531,7 +541,7 @@ !floatWriteAfterWrite(i) && // Avoid WAW hazards !branchInterlock(i) && // Only branch/alu can be dispatched after a branch !fence(i) && // Don't dispatch if fence interlocked - csrInterlock(i) && + slot0Interlock(i) && // Special instructions execute out of slot 0 only rvvConfigInterlock(i) && // Rvv interlock rules rvvReductionInterlock(i) && // Don't dispatch reduction if vstart != 0 // rvvLsuInterlock(i) && // Dispatch only one Rvv LsuOp @@ -539,7 +549,8 @@ rvvInterlock(i) && // Ensure rvv instructions can be dispatched into queue !undefInterlock(i) && // Ensure undef is only dispatched from first slot io.retirement_buffer_nSpace.map(x => i.U < x).getOrElse(true.B) && // Retirement buffer needs space for our slot - singleStepInterlock(i) + singleStepInterlock(i) && + mpauseInterlock(i) ) // ---------------------------------------------------------------------------
diff --git a/hdl/verilog/rvv/design/RvvCore.sv b/hdl/verilog/rvv/design/RvvCore.sv index f7f1642..fdd885a 100644 --- a/hdl/verilog/rvv/design/RvvCore.sv +++ b/hdl/verilog/rvv/design/RvvCore.sv
@@ -192,6 +192,8 @@ assign rd_rob2rt_o = rd_rob2rt; logic [`ISSUE_LANE-1:0] insts_ready_cq2rvs; + logic rvv_backend_idle; + assign rvv_idle = rvv_backend_idle && (frontend_cmd_valid == 0); rvv_backend backend( .clk(clk), .rst_n(rstn), @@ -219,7 +221,7 @@ .vcsr_valid(vcsr_valid), .vector_csr(vector_csr), .vcsr_ready(vcsr_ready), - .rvv_idle(rvv_idle), + .rvv_idle(rvv_backend_idle), .rd_rob2rt_o(rd_rob2rt) );