diff --git a/src/main/scala/rocket/CSR.scala b/src/main/scala/rocket/CSR.scala index 39ad32147ec..64c1c164cb1 100644 --- a/src/main/scala/rocket/CSR.scala +++ b/src/main/scala/rocket/CSR.scala @@ -268,7 +268,8 @@ class CSRFileIO(implicit p: Parameters) extends CoreBundle val decode = Vec(decodeWidth, new CSRDecodeIO) - val csr_stall = Output(Bool()) + val csr_stall = Output(Bool()) // stall retire for wfi + val rw_stall = Output(Bool()) // stall rw, rw will have no effect while rw_stall val eret = Output(Bool()) val singleStep = Output(Bool()) @@ -378,10 +379,12 @@ class CSRFile( extends CoreModule()(p) with HasCoreParameters { val io = IO(new CSRFileIO { - val customCSRs = Output(Vec(CSRFile.this.customCSRs.size, new CustomCSRIO)) - val roccCSRs = Output(Vec(CSRFile.this.roccCSRs.size, new CustomCSRIO)) + val customCSRs = Vec(CSRFile.this.customCSRs.size, new CustomCSRIO) + val roccCSRs = Vec(CSRFile.this.roccCSRs.size, new CustomCSRIO) }) + io.rw_stall := false.B + val reset_mstatus = WireDefault(0.U.asTypeOf(new MStatus())) reset_mstatus.mpp := PRV.M.U reset_mstatus.prv := PRV.M.U @@ -782,15 +785,18 @@ class CSRFile( } // implementation-defined CSRs - def generateCustomCSR(csr: CustomCSR) = { + def generateCustomCSR(csr: CustomCSR, csr_io: CustomCSRIO) = { require(csr.mask >= 0 && csr.mask.bitLength <= xLen) require(!read_mapping.contains(csr.id)) val reg = csr.init.map(init => RegInit(init.U(xLen.W))).getOrElse(Reg(UInt(xLen.W))) + val read = io.rw.cmd =/= CSR.N && io.rw.addr === csr.id.U + csr_io.ren := read + when (read && csr_io.stall) { io.rw_stall := true.B } read_mapping += csr.id -> reg reg } - val reg_custom = customCSRs.map(generateCustomCSR(_)) - val reg_rocc = roccCSRs.map(generateCustomCSR(_)) + val reg_custom = customCSRs.zip(io.customCSRs).map(t => generateCustomCSR(t._1, t._2)) + val reg_rocc = roccCSRs.zip(io.roccCSRs).map(t => generateCustomCSR(t._1, t._2)) if (usingHypervisor) { read_mapping += CSRs.mtinst -> 0.U @@ -1195,7 +1201,7 @@ class CSRFile( } } - val csr_wen = io.rw.cmd.isOneOf(CSR.S, CSR.C, CSR.W) + val csr_wen = io.rw.cmd.isOneOf(CSR.S, CSR.C, CSR.W) && !io.rw_stall io.csrw_counter := Mux(coreParams.haveBasicCounters.B && csr_wen && (io.rw.addr.inRange(CSRs.mcycle.U, (CSRs.mcycle + CSR.nCtr).U) || io.rw.addr.inRange(CSRs.mcycleh.U, (CSRs.mcycleh + CSR.nCtr).U)), UIntToOH(io.rw.addr(log2Ceil(CSR.nCtr+nPerfCounters)-1, 0)), 0.U) when (csr_wen) { val scause_mask = ((BigInt(1) << (xLen-1)) + 31).U /* only implement 5 LSBs and MSB */ @@ -1497,6 +1503,19 @@ class CSRFile( } } + def setCustomCSR(io: CustomCSRIO, csr: CustomCSR, reg: UInt) = { + val mask = csr.mask.U(xLen.W) + when (io.set) { + reg := (io.sdata & mask) | (reg & ~mask) + } + } + for ((io, csr, reg) <- (io.customCSRs, customCSRs, reg_custom).zipped) { + setCustomCSR(io, csr, reg) + } + for ((io, csr, reg) <- (io.roccCSRs, roccCSRs, reg_rocc).zipped) { + setCustomCSR(io, csr, reg) + } + io.vector.map { vio => when (vio.set_vconfig.valid) { // user of CSRFile is responsible for set_vs_dirty in this case diff --git a/src/main/scala/rocket/PTW.scala b/src/main/scala/rocket/PTW.scala index 7c36bdbf377..b8c5f08a80e 100644 --- a/src/main/scala/rocket/PTW.scala +++ b/src/main/scala/rocket/PTW.scala @@ -79,7 +79,7 @@ class TLBPTWIO(implicit p: Parameters) extends CoreBundle()(p) val hstatus = Input(new HStatus()) val gstatus = Input(new MStatus()) val pmp = Input(Vec(nPMPs, new PMP)) - val customCSRs = Input(coreParams.customCSRs) + val customCSRs = Flipped(coreParams.customCSRs) } /** PTW performance statistics */ class PTWPerfEvents extends Bundle { @@ -106,7 +106,7 @@ class DatapathPTWIO(implicit p: Parameters) extends CoreBundle()(p) val gstatus = Input(new MStatus()) val pmp = Input(Vec(nPMPs, new PMP)) val perf = Output(new PTWPerfEvents()) - val customCSRs = Input(coreParams.customCSRs) + val customCSRs = Flipped(coreParams.customCSRs) /** enable clock generated by ptw */ val clock_enabled = Output(Bool()) } @@ -570,7 +570,7 @@ class PTW(n: Int)(implicit edge: TLEdgeOut, p: Parameters) extends CoreModule()( io.requestor(i).ptbr := io.dpath.ptbr io.requestor(i).hgatp := io.dpath.hgatp io.requestor(i).vsatp := io.dpath.vsatp - io.requestor(i).customCSRs := io.dpath.customCSRs + io.requestor(i).customCSRs <> io.dpath.customCSRs io.requestor(i).status := io.dpath.status io.requestor(i).hstatus := io.dpath.hstatus io.requestor(i).gstatus := io.dpath.gstatus diff --git a/src/main/scala/rocket/RocketCore.scala b/src/main/scala/rocket/RocketCore.scala index 68b3c90e054..43a5ab8db0a 100644 --- a/src/main/scala/rocket/RocketCore.scala +++ b/src/main/scala/rocket/RocketCore.scala @@ -729,7 +729,8 @@ class Rocket(tile: RocketTile)(implicit p: Parameters) extends CoreModule()(p) val wb_set_sboard = wb_ctrl.div || wb_dcache_miss || wb_ctrl.rocc val replay_wb_common = io.dmem.s2_nack || wb_reg_replay val replay_wb_rocc = wb_reg_valid && wb_ctrl.rocc && !io.rocc.cmd.ready - val replay_wb = replay_wb_common || replay_wb_rocc + val replay_wb_csr: Bool = wb_reg_valid && csr.io.rw_stall + val replay_wb = replay_wb_common || replay_wb_rocc || replay_wb_csr take_pc_wb := replay_wb || wb_xcpt || csr.io.eret || wb_reg_flush_pipe // writeback arbitration @@ -806,7 +807,7 @@ class Rocket(tile: RocketTile)(implicit p: Parameters) extends CoreModule()(p) io.ptw.ptbr := csr.io.ptbr io.ptw.hgatp := csr.io.hgatp io.ptw.vsatp := csr.io.vsatp - (io.ptw.customCSRs.csrs zip csr.io.customCSRs).map { case (lhs, rhs) => lhs := rhs } + (io.ptw.customCSRs.csrs zip csr.io.customCSRs).map { case (lhs, rhs) => lhs <> rhs } io.ptw.status := csr.io.status io.ptw.hstatus := csr.io.hstatus io.ptw.gstatus := csr.io.gstatus @@ -814,9 +815,9 @@ class Rocket(tile: RocketTile)(implicit p: Parameters) extends CoreModule()(p) csr.io.rw.addr := wb_reg_inst(31,20) csr.io.rw.cmd := CSR.maskCmd(wb_reg_valid, wb_ctrl.csr) csr.io.rw.wdata := wb_reg_wdata - io.trace.insns := csr.io.trace + io.rocc.csrs <> csr.io.roccCSRs io.trace.time := csr.io.time - io.rocc.csrs := csr.io.roccCSRs + io.trace.insns := csr.io.trace if (rocketParams.debugROB) { val csr_trace_with_wdata = WireInit(csr.io.trace(0)) csr_trace_with_wdata.wdata.get := rf_wdata diff --git a/src/main/scala/tile/CustomCSRs.scala b/src/main/scala/tile/CustomCSRs.scala index a4508348ae8..5d9be4eade4 100644 --- a/src/main/scala/tile/CustomCSRs.scala +++ b/src/main/scala/tile/CustomCSRs.scala @@ -13,9 +13,15 @@ object CustomCSR { } class CustomCSRIO(implicit p: Parameters) extends CoreBundle { - val wen = Bool() - val wdata = UInt(xLen.W) - val value = UInt(xLen.W) + val ren = Output(Bool()) // set by CSRFile, indicates an instruction is reading the CSR + val wen = Output(Bool()) // set by CSRFile, indicates an instruction is writing the CSR + val wdata = Output(UInt(xLen.W)) // wdata provided by instruction writing CSR + val value = Output(UInt(xLen.W)) // current value of CSR in CSRFile + + val stall = Input(Bool()) // reads and writes to this CSR should stall (must be bounded) + + val set = Input(Bool()) // set/sdata enables external agents to set the value of this CSR + val sdata = Input(UInt(xLen.W)) } class CustomCSRs(implicit p: Parameters) extends CoreBundle { diff --git a/src/main/scala/tile/LazyRoCC.scala b/src/main/scala/tile/LazyRoCC.scala index 1c8c0d1e998..171832d0e1d 100644 --- a/src/main/scala/tile/LazyRoCC.scala +++ b/src/main/scala/tile/LazyRoCC.scala @@ -45,7 +45,7 @@ class RoCCCoreIO(val nRoCCCSRs: Int = 0)(implicit p: Parameters) extends CoreBun val busy = Output(Bool()) val interrupt = Output(Bool()) val exception = Input(Bool()) - val csrs = Input(Vec(nRoCCCSRs, new CustomCSRIO)) + val csrs = Flipped(Vec(nRoCCCSRs, new CustomCSRIO)) } class RoCCIO(val nPTWPorts: Int, nRoCCCSRs: Int)(implicit p: Parameters) extends RoCCCoreIO(nRoCCCSRs)(p) {