diff --git a/RocketChip_Technical_Charter_8-23-2024.pdf b/RocketChip_Technical_Charter_8-23-2024.pdf new file mode 100644 index 00000000000..2e5ed34ee5f Binary files /dev/null and b/RocketChip_Technical_Charter_8-23-2024.pdf differ diff --git a/build.sc b/build.sc index b63c6ae7900..cf602b2a8ab 100644 --- a/build.sc +++ b/build.sc @@ -185,6 +185,35 @@ trait Emulator extends Cross.Module2[String, String] { } } + object litexgenerate extends Module { + def compile = T { + os.proc("firtool", + generator.chirrtl().path, + s"--annotation-file=${generator.chiselAnno().path}", + "--disable-annotation-unknown", + "-dedup", + "-O=debug", + "--split-verilog", + "--preserve-values=named", + "--output-annotation-file=mfc.anno.json", + "--lowering-options=disallowLocalVariables", + s"-o=${T.dest}" + ).call(T.dest) + PathRef(T.dest) + } + + def rtls = T { + os.read(compile().path / "filelist.f").split("\n").map(str => + try { + os.Path(str) + } catch { + case e: IllegalArgumentException if e.getMessage.contains("is not an absolute path") => + compile().path / str.stripPrefix("./") + } + ).filter(p => p.ext == "v" || p.ext == "sv").map(PathRef(_)).toSeq + } + } + object mfccompiler extends Module { def compile = T { os.proc("firtool", @@ -233,7 +262,7 @@ trait Emulator extends Cross.Module2[String, String] { "debug_rob.cc", "emulator.cc", "remote_bitbang.cc", - ).map(c => PathRef(csrcDir().path / c)) + ).map(c => PathRef(csrcDir().path / c)) } def CMakeListsString = T { @@ -347,6 +376,39 @@ object emulator extends Cross[Emulator]( ("freechips.rocketchip.system.TestHarness", "freechips.rocketchip.system.DefaultBConfig"), ("freechips.rocketchip.system.TestHarness", "freechips.rocketchip.system.DefaultRV32BConfig"), + // Litex + ("freechips.rocketchip.system.TestHarness", "freechips.rocketchip.system.LitexConfigSmall1x1"), + ("freechips.rocketchip.system.TestHarness", "freechips.rocketchip.system.LitexConfigSmall1x2"), + ("freechips.rocketchip.system.TestHarness", "freechips.rocketchip.system.LitexConfigSmall1x4"), + ("freechips.rocketchip.system.TestHarness", "freechips.rocketchip.system.LitexConfigSmall1x8"), + ("freechips.rocketchip.system.TestHarness", "freechips.rocketchip.system.LitexConfigSmall2x1"), + ("freechips.rocketchip.system.TestHarness", "freechips.rocketchip.system.LitexConfigSmall2x2"), + ("freechips.rocketchip.system.TestHarness", "freechips.rocketchip.system.LitexConfigSmall2x4"), + ("freechips.rocketchip.system.TestHarness", "freechips.rocketchip.system.LitexConfigSmall2x8"), + ("freechips.rocketchip.system.TestHarness", "freechips.rocketchip.system.LitexConfigSmall4x1"), + ("freechips.rocketchip.system.TestHarness", "freechips.rocketchip.system.LitexConfigSmall4x2"), + ("freechips.rocketchip.system.TestHarness", "freechips.rocketchip.system.LitexConfigSmall4x4"), + ("freechips.rocketchip.system.TestHarness", "freechips.rocketchip.system.LitexConfigSmall4x8"), + ("freechips.rocketchip.system.TestHarness", "freechips.rocketchip.system.LitexConfigSmall8x1"), + ("freechips.rocketchip.system.TestHarness", "freechips.rocketchip.system.LitexConfigSmall8x2"), + ("freechips.rocketchip.system.TestHarness", "freechips.rocketchip.system.LitexConfigSmall8x4"), + ("freechips.rocketchip.system.TestHarness", "freechips.rocketchip.system.LitexConfigSmall8x8"), + ("freechips.rocketchip.system.TestHarness", "freechips.rocketchip.system.LitexConfigBig1x1"), + ("freechips.rocketchip.system.TestHarness", "freechips.rocketchip.system.LitexConfigBig1x2"), + ("freechips.rocketchip.system.TestHarness", "freechips.rocketchip.system.LitexConfigBig1x4"), + ("freechips.rocketchip.system.TestHarness", "freechips.rocketchip.system.LitexConfigBig1x8"), + ("freechips.rocketchip.system.TestHarness", "freechips.rocketchip.system.LitexConfigBig2x1"), + ("freechips.rocketchip.system.TestHarness", "freechips.rocketchip.system.LitexConfigBig2x2"), + ("freechips.rocketchip.system.TestHarness", "freechips.rocketchip.system.LitexConfigBig2x4"), + ("freechips.rocketchip.system.TestHarness", "freechips.rocketchip.system.LitexConfigBig2x8"), + ("freechips.rocketchip.system.TestHarness", "freechips.rocketchip.system.LitexConfigBig4x1"), + ("freechips.rocketchip.system.TestHarness", "freechips.rocketchip.system.LitexConfigBig4x2"), + ("freechips.rocketchip.system.TestHarness", "freechips.rocketchip.system.LitexConfigBig4x4"), + ("freechips.rocketchip.system.TestHarness", "freechips.rocketchip.system.LitexConfigBig4x8"), + ("freechips.rocketchip.system.TestHarness", "freechips.rocketchip.system.LitexConfigBig8x1"), + ("freechips.rocketchip.system.TestHarness", "freechips.rocketchip.system.LitexConfigBig8x2"), + ("freechips.rocketchip.system.TestHarness", "freechips.rocketchip.system.LitexConfigBig8x4"), + ("freechips.rocketchip.system.TestHarness", "freechips.rocketchip.system.LitexConfigBig8x8"), ) object `runnable-riscv-test` extends mill.Cross[RiscvTest]( diff --git a/src/main/resources/vsrc/TraceSinkMonitor.v b/src/main/resources/vsrc/TraceSinkMonitor.v new file mode 100644 index 00000000000..a0de8903bd2 --- /dev/null +++ b/src/main/resources/vsrc/TraceSinkMonitor.v @@ -0,0 +1,36 @@ +module TraceSinkMonitor +#( + parameter FILE_NAME = "trace_sink_monitor.txt" +) +( + input clk, + input reset, + input in_fire, + input[7:0] in_byte +); + +`ifndef SYNTHESIS + +integer file; + +initial begin + file = $fopen(FILE_NAME, "w"); + if (file == 0) begin + $display("Failed to open %s", FILE_NAME); + $finish; + end +end + +always @(posedge clk) begin + if (in_fire & ~reset) begin + $fwrite(file, "%c", in_byte); + end +end + +final begin + $fclose(file); +end + +`endif + +endmodule \ No newline at end of file diff --git a/src/main/scala/devices/debug/Debug.scala b/src/main/scala/devices/debug/Debug.scala index efaf345fb5f..7c6716b0e2d 100755 --- a/src/main/scala/devices/debug/Debug.scala +++ b/src/main/scala/devices/debug/Debug.scala @@ -660,7 +660,7 @@ class TLDebugModuleOuter(device: Device)(implicit p: Parameters) extends LazyMod val hartResetReg = RegNext(next=hartResetNxt, init=0.U.asTypeOf(hartResetNxt)) for (component <- 0 until nComponents) { - hartResetNxt(component) := DMCONTROLReg.hartreset & hartSelected(component) + hartResetNxt(component) := DMCONTROLNxt.hartreset & hartSelected(component) io.hartResetReq.get(component) := hartResetReg(component) } } diff --git a/src/main/scala/rocket/ALU.scala b/src/main/scala/rocket/ALU.scala index 96cbc98aa58..ca8a11067b1 100644 --- a/src/main/scala/rocket/ALU.scala +++ b/src/main/scala/rocket/ALU.scala @@ -81,6 +81,8 @@ abstract class AbstractALU(implicit p: Parameters) extends CoreModule()(p) { } class ALU(implicit p: Parameters) extends AbstractALU()(p) { + override def desiredName = "RocketALU" + // ADD, SUB val in2_inv = Mux(isSub(io.fn), ~io.in2, io.in2) val in1_xor_in2 = io.in1 ^ in2_inv diff --git a/src/main/scala/rocket/BitManipCrypto.scala b/src/main/scala/rocket/BitManipCrypto.scala deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/src/main/scala/rocket/CSR.scala b/src/main/scala/rocket/CSR.scala index 2658f0f17cc..a608c57938e 100644 --- a/src/main/scala/rocket/CSR.scala +++ b/src/main/scala/rocket/CSR.scala @@ -149,7 +149,7 @@ class PTBR(implicit p: Parameters) extends CoreBundle()(p) { case 32 => (1, 9) case 64 => (4, 16) } - require(modeBits + maxASIdBits + maxPAddrBits - pgIdxBits == xLen) + require(!usingVM || modeBits + maxASIdBits + maxPAddrBits - pgIdxBits == xLen) val mode = UInt(modeBits.W) val asid = UInt(maxASIdBits.W) @@ -272,8 +272,8 @@ class CSRFileIO(hasBeu: Boolean)(implicit p: Parameters) extends CoreBundle 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 trap_return = Output(Bool()) val singleStep = Output(Bool()) - val status = Output(new MStatus()) val hstatus = Output(new HStatus()) val gstatus = Output(new MStatus()) @@ -998,6 +998,7 @@ class CSRFile( io.hgatp := reg_hgatp io.vsatp := reg_vsatp io.eret := insn_call || insn_break || insn_ret + io.trap_return := insn_ret io.singleStep := reg_dcsr.step && !reg_debug io.status := reg_mstatus io.status.sd := io.status.fs.andR || io.status.xs.andR || io.status.vs.andR diff --git a/src/main/scala/rocket/CryptoNIST.scala b/src/main/scala/rocket/CryptoNIST.scala deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/src/main/scala/rocket/Instructions.scala b/src/main/scala/rocket/Instructions.scala index adf1183388f..dabf5365691 100644 --- a/src/main/scala/rocket/Instructions.scala +++ b/src/main/scala/rocket/Instructions.scala @@ -582,8 +582,8 @@ object Instructions { def VMADC_VXM = BitPat("b0100010??????????100?????1010111") def VMADD_VV = BitPat("b101001???????????010?????1010111") def VMADD_VX = BitPat("b101001???????????110?????1010111") - def VMAND_MM = BitPat("b011001???????????010?????1010111") - def VMANDN_MM = BitPat("b011000???????????010?????1010111") + def VMAND_MM = BitPat("b0110011??????????010?????1010111") + def VMANDN_MM = BitPat("b0110001??????????010?????1010111") def VMAX_VV = BitPat("b000111???????????000?????1010111") def VMAX_VX = BitPat("b000111???????????100?????1010111") def VMAXU_VV = BitPat("b000110???????????000?????1010111") @@ -605,10 +605,10 @@ object Instructions { def VMIN_VX = BitPat("b000101???????????100?????1010111") def VMINU_VV = BitPat("b000100???????????000?????1010111") def VMINU_VX = BitPat("b000100???????????100?????1010111") - def VMNAND_MM = BitPat("b011101???????????010?????1010111") - def VMNOR_MM = BitPat("b011110???????????010?????1010111") - def VMOR_MM = BitPat("b011010???????????010?????1010111") - def VMORN_MM = BitPat("b011100???????????010?????1010111") + def VMNAND_MM = BitPat("b0111011??????????010?????1010111") + def VMNOR_MM = BitPat("b0111101??????????010?????1010111") + def VMOR_MM = BitPat("b0110101??????????010?????1010111") + def VMORN_MM = BitPat("b0111001??????????010?????1010111") def VMSBC_VV = BitPat("b0100111??????????000?????1010111") def VMSBC_VVM = BitPat("b0100110??????????000?????1010111") def VMSBC_VX = BitPat("b0100111??????????100?????1010111") @@ -653,8 +653,8 @@ object Instructions { def VMV_V_V = BitPat("b010111100000?????000?????1010111") def VMV_V_X = BitPat("b010111100000?????100?????1010111") def VMV_X_S = BitPat("b0100001?????00000010?????1010111") - def VMXNOR_MM = BitPat("b011111???????????010?????1010111") - def VMXOR_MM = BitPat("b011011???????????010?????1010111") + def VMXNOR_MM = BitPat("b0111111??????????010?????1010111") + def VMXOR_MM = BitPat("b0110111??????????010?????1010111") def VNCLIP_WI = BitPat("b101111???????????011?????1010111") def VNCLIP_WV = BitPat("b101111???????????000?????1010111") def VNCLIP_WX = BitPat("b101111???????????100?????1010111") diff --git a/src/main/scala/rocket/PTW.scala b/src/main/scala/rocket/PTW.scala index 872b143e24c..04dd994efe3 100644 --- a/src/main/scala/rocket/PTW.scala +++ b/src/main/scala/rocket/PTW.scala @@ -303,7 +303,7 @@ class PTW(n: Int)(implicit edge: TLEdgeOut, p: Parameters) extends CoreModule()( val (pte, invalid_paddr, invalid_gpa) = { val tmp = mem_resp_data.asTypeOf(new PTE()) val res = WireDefault(tmp) - res.ppn := Mux(do_both_stages && !stage2, tmp.ppn(vpnBits.min(tmp.ppn.getWidth)-1, 0), tmp.ppn(ppnBits-1, 0)) + res.ppn := Mux(do_both_stages && !stage2, tmp.ppn(vpnBits.min(tmp.ppn.getWidth)-1, 0), tmp.ppn(ppnBits.min(tmp.ppn.getWidth)-1, 0)) when (tmp.r || tmp.w || tmp.x) { // for superpage mappings, make sure PPN LSBs are zero for (i <- 0 until pgLevels-1) diff --git a/src/main/scala/rocket/RocketCore.scala b/src/main/scala/rocket/RocketCore.scala index 7a8c0d95003..cc5ab6fccda 100644 --- a/src/main/scala/rocket/RocketCore.scala +++ b/src/main/scala/rocket/RocketCore.scala @@ -11,6 +11,7 @@ import freechips.rocketchip.tile._ import freechips.rocketchip.util._ import freechips.rocketchip.util.property import scala.collection.mutable.ArrayBuffer +import freechips.rocketchip.trace._ case class RocketCoreParams( xLen: Int = 64, @@ -56,7 +57,8 @@ case class RocketCoreParams( debugROB: Option[DebugROBParams] = None, // if size < 1, SW ROB, else HW ROB haveCease: Boolean = true, // non-standard CEASE instruction haveSimTimeout: Boolean = true, // add plusarg for simulation timeout - vector: Option[RocketCoreVectorParams] = None + vector: Option[RocketCoreVectorParams] = None, + enableTraceCoreIngress: Boolean = false ) extends CoreParams { val lgPauseCycles = 5 val haveFSDirty = false @@ -131,6 +133,8 @@ class CoreInterrupts(val hasBeu: Boolean)(implicit p: Parameters) extends TileIn trait HasRocketCoreIO extends HasRocketCoreParameters { implicit val p: Parameters def nTotalRoCCCSRs: Int + def traceIngressParams = TraceCoreParams(nGroups = 1, iretireWidth = coreParams.retireWidth, + xlen = coreParams.xLen, iaddrWidth = coreParams.xLen) val io = IO(new CoreBundle()(p) { val hartid = Input(UInt(hartIdLen.W)) val reset_vector = Input(UInt(resetVectorLen.W)) @@ -146,6 +150,7 @@ trait HasRocketCoreIO extends HasRocketCoreParameters { val wfi = Output(Bool()) val traceStall = Input(Bool()) val vector = if (usingVector) Some(Flipped(new VectorCoreIO)) else None + val trace_core_ingress = if (rocketParams.enableTraceCoreIngress) Some(Output(new TraceCoreInterface(traceIngressParams))) else None }) } @@ -301,6 +306,7 @@ class Rocket(tile: RocketTile)(implicit p: Parameters) extends CoreModule()(p) val wb_reg_raw_inst = Reg(UInt()) val wb_reg_wdata = Reg(Bits()) val wb_reg_rs2 = Reg(Bits()) + val wb_reg_br_taken = Reg(Bool()) val take_pc_wb = Wire(Bool()) val wb_reg_wphit = Reg(Vec(nBreakpoints, Bool())) @@ -723,6 +729,7 @@ class Rocket(tile: RocketTile)(implicit p: Parameters) extends CoreModule()(p) wb_reg_hfence_v := mem_ctrl.mem_cmd === M_HFENCEV wb_reg_hfence_g := mem_ctrl.mem_cmd === M_HFENCEG wb_reg_pc := mem_reg_pc + wb_reg_br_taken := mem_br_taken wb_reg_wphit := mem_reg_wphit | bpu.io.bpwatch.map { bpw => (bpw.rvalid(0) && mem_reg_load) || (bpw.wvalid(0) && mem_reg_store) } wb_reg_set_vconfig := mem_reg_set_vconfig } @@ -825,6 +832,27 @@ class Rocket(tile: RocketTile)(implicit p: Parameters) extends CoreModule()(p) wb_reg_wdata)))) when (rf_wen) { rf.write(rf_waddr, rf_wdata) } + if (rocketParams.enableTraceCoreIngress) { + val trace_ingress = Module(new TraceCoreIngress(traceIngressParams)) + trace_ingress.io.in.valid := wb_valid || wb_xcpt + trace_ingress.io.in.taken := wb_reg_br_taken + trace_ingress.io.in.is_branch := wb_ctrl.branch + trace_ingress.io.in.is_jal := wb_ctrl.jal + trace_ingress.io.in.is_jalr := wb_ctrl.jalr + trace_ingress.io.in.insn := wb_reg_inst + trace_ingress.io.in.pc := wb_reg_pc + trace_ingress.io.in.is_compressed := !wb_reg_raw_inst(1, 0).andR // 2'b11 is uncompressed, everything else is compressed + trace_ingress.io.in.interrupt := csr.io.trace(0).interrupt && csr.io.trace(0).exception + trace_ingress.io.in.exception := !csr.io.trace(0).interrupt && csr.io.trace(0).exception + trace_ingress.io.in.trap_return := csr.io.trap_return + + io.trace_core_ingress.get.group(0) <> trace_ingress.io.out + io.trace_core_ingress.get.priv := csr.io.trace(0).priv + io.trace_core_ingress.get.tval := csr.io.tval + io.trace_core_ingress.get.cause := csr.io.cause + io.trace_core_ingress.get.time := csr.io.time + } + // hook up control/status regfile csr.io.ungated_clock := clock csr.io.decode(0).inst := id_inst(0) @@ -1176,6 +1204,7 @@ class Rocket(tile: RocketTile)(implicit p: Parameters) extends CoreModule()(p) !div.io.req.ready || // mul/div in flight usingFPU.B && !io.fpu.fcsr_rdy || // long-latency FPU in flight io.dmem.replay_next || // long-latency load replaying + id_rocc_busy || // RoCC command in flight (!long_latency_stall && (ibuf.io.inst(0).valid || io.imem.resp.valid)) // instruction pending assert(!(ex_pc_valid || mem_pc_valid || wb_pc_valid) || clock_en) diff --git a/src/main/scala/rocket/TLB.scala b/src/main/scala/rocket/TLB.scala index 8cc4a2c67c9..4f2d09c9e45 100644 --- a/src/main/scala/rocket/TLB.scala +++ b/src/main/scala/rocket/TLB.scala @@ -403,7 +403,7 @@ class TLB(instruction: Boolean, lgMaxSize: Int, cfg: TLBConfig)(implicit edge: T val vsatp_mode_mismatch = priv_v && (vstage1_en =/= v_entries_use_stage1) && !io.req.bits.passthrough // share a single physical memory attribute checker (unshare if critical path) - val refill_ppn = io.ptw.resp.bits.pte.ppn(ppnBits-1, 0) + val refill_ppn = if (usingVM) io.ptw.resp.bits.pte.ppn(ppnBits-1, 0) else 0.U /** refill signal */ val do_refill = usingVM.B && io.ptw.resp.valid /** sfence invalidate refill */ diff --git a/src/main/scala/subsystem/Cluster.scala b/src/main/scala/subsystem/Cluster.scala index 9d82ad616ca..f4419fa9efd 100644 --- a/src/main/scala/subsystem/Cluster.scala +++ b/src/main/scala/subsystem/Cluster.scala @@ -13,7 +13,7 @@ import freechips.rocketchip.interrupts.{IntIdentityNode, IntSyncIdentityNode, Nu import freechips.rocketchip.prci.{ClockCrossingType, NoCrossing, ClockSinkParameters, ClockGroupIdentityNode, BundleBridgeBlockDuringReset} import freechips.rocketchip.tile.{RocketTile, NMI, TraceBundle} import freechips.rocketchip.tilelink.TLWidthWidget -import freechips.rocketchip.util.TraceCoreInterface +import freechips.rocketchip.trace.TraceCoreInterface import scala.collection.immutable.SortedMap diff --git a/src/main/scala/subsystem/HasHierarchicalElements.scala b/src/main/scala/subsystem/HasHierarchicalElements.scala index d026395a417..56659d2d301 100644 --- a/src/main/scala/subsystem/HasHierarchicalElements.scala +++ b/src/main/scala/subsystem/HasHierarchicalElements.scala @@ -18,7 +18,7 @@ import freechips.rocketchip.tile.{TileParams, TilePRCIDomain, BaseTile, NMI, Tra import freechips.rocketchip.tilelink.{TLNode, TLBuffer, TLCacheCork, TLTempNode, TLFragmenter} import freechips.rocketchip.prci.{ClockCrossingType, ClockGroup, ResetCrossingType, ClockGroupNode, ClockDomain} import freechips.rocketchip.rocket.TracedInstruction -import freechips.rocketchip.util.TraceCoreInterface +import freechips.rocketchip.trace.TraceCoreInterface import scala.collection.immutable.SortedMap diff --git a/src/main/scala/subsystem/HasTiles.scala b/src/main/scala/subsystem/HasTiles.scala index ea1f34f7e7b..5a0f0b856c6 100644 --- a/src/main/scala/subsystem/HasTiles.scala +++ b/src/main/scala/subsystem/HasTiles.scala @@ -15,7 +15,7 @@ import freechips.rocketchip.tile.{MaxHartIdBits, BaseTile, InstantiableTileParam import freechips.rocketchip.tilelink.TLWidthWidget import freechips.rocketchip.prci.{ClockGroup, BundleBridgeBlockDuringReset, NoCrossing, SynchronousCrossing, CreditedCrossing, RationalCrossing, AsynchronousCrossing} import freechips.rocketchip.rocket.TracedInstruction -import freechips.rocketchip.util.TraceCoreInterface +import freechips.rocketchip.trace.TraceCoreInterface import scala.collection.immutable.SortedMap diff --git a/src/main/scala/subsystem/HierarchicalElementPRCIDomain.scala b/src/main/scala/subsystem/HierarchicalElementPRCIDomain.scala index b38f208701e..8c234cd4e75 100644 --- a/src/main/scala/subsystem/HierarchicalElementPRCIDomain.scala +++ b/src/main/scala/subsystem/HierarchicalElementPRCIDomain.scala @@ -12,7 +12,7 @@ import freechips.rocketchip.interrupts.{IntInwardNode, IntOutwardNode} import freechips.rocketchip.prci.{ClockCrossingType, ResetCrossingType, ResetDomain, ClockSinkNode, ClockSinkParameters, ClockIdentityNode, FixedClockBroadcast, ClockDomain} import freechips.rocketchip.tile.{RocketTile, TraceBundle} import freechips.rocketchip.tilelink.{TLInwardNode, TLOutwardNode} -import freechips.rocketchip.util.TraceCoreInterface +import freechips.rocketchip.trace.TraceCoreInterface import freechips.rocketchip.tilelink.TLClockDomainCrossing import freechips.rocketchip.tilelink.TLResetDomainCrossing diff --git a/src/main/scala/subsystem/Litex.scala b/src/main/scala/subsystem/Litex.scala new file mode 100644 index 00000000000..7e8e1888d94 --- /dev/null +++ b/src/main/scala/subsystem/Litex.scala @@ -0,0 +1,53 @@ +// See LICENSE.SiFive for license details. +// See LICENSE.Berkeley for license details. + +package freechips.rocketchip.subsystem + +import chisel3.util._ + +import org.chipsalliance.cde.config._ +import org.chipsalliance.diplomacy.lazymodule._ + +import freechips.rocketchip.devices.debug.{DebugModuleKey, DefaultDebugModuleParams, ExportDebug, JTAG, APB} +import freechips.rocketchip.devices.tilelink.{ + BuiltInErrorDeviceParams, BootROMLocated, BootROMParams, CLINTKey, DevNullDevice, CLINTParams, PLICKey, PLICParams, DevNullParams +} +import freechips.rocketchip.prci.{SynchronousCrossing, AsynchronousCrossing, RationalCrossing, ClockCrossingType} +import freechips.rocketchip.diplomacy.{ + AddressSet, MonitorsEnabled, +} +import freechips.rocketchip.resources.{ + DTSModel, DTSCompat, DTSTimebase, BigIntHexContext +} +import freechips.rocketchip.tile.{ + MaxHartIdBits, RocketTileParams, BuildRoCC, AccumulatorExample, OpcodeSet, TranslatorExample, CharacterCountExample, BlackBoxExample +} +import freechips.rocketchip.util.ClockGateModelFile +import scala.reflect.ClassTag + +class WithLitexMemPort extends Config((site, here, up) => { + case ExtMem => Some(MemoryPortParams(MasterPortParams( + base = x"8000_0000", + size = x"8000_0000", + beatBytes = site(MemoryBusKey).beatBytes, + idBits = 4), 1)) +}) + +class WithLitexMMIOPort extends Config((site, here, up) => { + case ExtBus => Some(MasterPortParams( + base = x"1000_0000", + size = x"7000_0000", + beatBytes = site(SystemBusKey).beatBytes, + idBits = 4)) +}) + +class WithLitexSlavePort extends Config((site, here, up) => { + case ExtIn => Some(SlavePortParams( + beatBytes = site(SystemBusKey).beatBytes, + idBits = 8, + sourceBits = 4)) +}) + +class WithNBitMemoryBus(dataBits: Int) extends Config((site, here, up) => { + case MemoryBusKey => up(MemoryBusKey, site).copy(beatBytes = dataBits/8) +}) diff --git a/src/main/scala/system/Litex.scala b/src/main/scala/system/Litex.scala new file mode 100644 index 00000000000..4ffad24fe27 --- /dev/null +++ b/src/main/scala/system/Litex.scala @@ -0,0 +1,209 @@ +// See LICENSE.SiFive for license details. +// See LICENSE.Berkeley for license details. + +package freechips.rocketchip.system + +import org.chipsalliance.cde.config.Config +import freechips.rocketchip.subsystem._ +import freechips.rocketchip.rocket.{WithNBigCores, WithNMedCores, WithNSmallCores, WithRV32, WithFP16, WithHypervisor, With1TinyCore, WithScratchpadsOnly, WithCloneRocketTiles, WithB} + +class BaseLitexConfig extends Config( + new WithLitexMemPort() ++ + new WithLitexMMIOPort() ++ + new WithLitexSlavePort ++ + new WithNExtTopInterrupts(8) ++ + new WithCoherentBusTopology ++ + new BaseConfig +) + +class LitexConfigSmall1x1 extends Config( + new WithNSmallCores(1) ++ + new WithNBitMemoryBus(64) ++ + new BaseLitexConfig +) + +class LitexConfigSmall1x2 extends Config( + new WithNSmallCores(1) ++ + new WithNBitMemoryBus(128) ++ + new BaseLitexConfig +) + +class LitexConfigSmall1x4 extends Config( + new WithNSmallCores(1) ++ + new WithNBitMemoryBus(256) ++ + new BaseLitexConfig +) + +class LitexConfigSmall1x8 extends Config( + new WithNSmallCores(1) ++ + new WithNBitMemoryBus(512) ++ + new BaseLitexConfig +) + +class LitexConfigSmall2x1 extends Config( + new WithNSmallCores(2) ++ + new WithNBitMemoryBus(64) ++ + new BaseLitexConfig +) + +class LitexConfigSmall2x2 extends Config( + new WithNSmallCores(2) ++ + new WithNBitMemoryBus(128) ++ + new BaseLitexConfig +) + +class LitexConfigSmall2x4 extends Config( + new WithNSmallCores(2) ++ + new WithNBitMemoryBus(256) ++ + new BaseLitexConfig +) + +class LitexConfigSmall2x8 extends Config( + new WithNSmallCores(2) ++ + new WithNBitMemoryBus(512) ++ + new BaseLitexConfig +) + +class LitexConfigSmall4x1 extends Config( + new WithNSmallCores(4) ++ + new WithNBitMemoryBus(64) ++ + new BaseLitexConfig +) + +class LitexConfigSmall4x2 extends Config( + new WithNSmallCores(4) ++ + new WithNBitMemoryBus(128) ++ + new BaseLitexConfig +) + +class LitexConfigSmall4x4 extends Config( + new WithNSmallCores(4) ++ + new WithNBitMemoryBus(256) ++ + new BaseLitexConfig +) + +class LitexConfigSmall4x8 extends Config( + new WithNSmallCores(4) ++ + new WithNBitMemoryBus(512) ++ + new BaseLitexConfig +) + +class LitexConfigSmall8x1 extends Config( + new WithNSmallCores(8) ++ + new WithNBitMemoryBus(64) ++ + new BaseLitexConfig +) + +class LitexConfigSmall8x2 extends Config( + new WithNSmallCores(8) ++ + new WithNBitMemoryBus(128) ++ + new BaseLitexConfig +) + +class LitexConfigSmall8x4 extends Config( + new WithNSmallCores(8) ++ + new WithNBitMemoryBus(256) ++ + new BaseLitexConfig +) + +class LitexConfigSmall8x8 extends Config( + new WithNSmallCores(8) ++ + new WithNBitMemoryBus(512) ++ + new BaseLitexConfig +) + +class LitexConfigBig1x1 extends Config( + new WithNBigCores(1) ++ + new WithNBitMemoryBus(64) ++ + new BaseLitexConfig +) + +class LitexConfigBig1x2 extends Config( + new WithNBigCores(1) ++ + new WithNBitMemoryBus(128) ++ + new BaseLitexConfig +) + +class LitexConfigBig1x4 extends Config( + new WithNBigCores(1) ++ + new WithNBitMemoryBus(256) ++ + new BaseLitexConfig +) + +class LitexConfigBig1x8 extends Config( + new WithNBigCores(1) ++ + new WithNBitMemoryBus(512) ++ + new BaseLitexConfig +) + +class LitexConfigBig2x1 extends Config( + new WithNBigCores(2) ++ + new WithNBitMemoryBus(64) ++ + new BaseLitexConfig +) + +class LitexConfigBig2x2 extends Config( + new WithNBigCores(2) ++ + new WithNBitMemoryBus(128) ++ + new BaseLitexConfig +) + +class LitexConfigBig2x4 extends Config( + new WithNBigCores(2) ++ + new WithNBitMemoryBus(256) ++ + new BaseLitexConfig +) + +class LitexConfigBig2x8 extends Config( + new WithNBigCores(2) ++ + new WithNBitMemoryBus(512) ++ + new BaseLitexConfig +) + +class LitexConfigBig4x1 extends Config( + new WithNBigCores(4) ++ + new WithNBitMemoryBus(64) ++ + new BaseLitexConfig +) + +class LitexConfigBig4x2 extends Config( + new WithNBigCores(4) ++ + new WithNBitMemoryBus(128) ++ + new BaseLitexConfig +) + +class LitexConfigBig4x4 extends Config( + new WithNBigCores(4) ++ + new WithNBitMemoryBus(256) ++ + new BaseLitexConfig +) + +class LitexConfigBig4x8 extends Config( + new WithNBigCores(4) ++ + new WithNBitMemoryBus(512) ++ + new BaseLitexConfig +) + +class LitexConfigBig8x1 extends Config( + new WithNBigCores(8) ++ + new WithNBitMemoryBus(64) ++ + new BaseLitexConfig +) + +class LitexConfigBig8x2 extends Config( + new WithNBigCores(8) ++ + new WithNBitMemoryBus(128) ++ + new BaseLitexConfig +) + +class LitexConfigBig8x4 extends Config( + new WithNBigCores(8) ++ + new WithNBitMemoryBus(256) ++ + new BaseLitexConfig +) + +class LitexConfigBig8x8 extends Config( + new WithNBigCores(8) ++ + new WithNBitMemoryBus(512) ++ + new BaseLitexConfig +) diff --git a/src/main/scala/tile/BaseTile.scala b/src/main/scala/tile/BaseTile.scala index 263b73c69a8..e25ce6f323d 100644 --- a/src/main/scala/tile/BaseTile.scala +++ b/src/main/scala/tile/BaseTile.scala @@ -19,11 +19,13 @@ import freechips.rocketchip.subsystem.{ } import freechips.rocketchip.tilelink.{TLEphemeralNode, TLOutwardNode, TLNode, TLFragmenter, EarlyAck, TLWidthWidget, TLManagerParameters, ManagerUnification} import freechips.rocketchip.prci.{ClockCrossingType, ClockSinkParameters} -import freechips.rocketchip.util.{TraceCoreParams, TraceCoreInterface} +import freechips.rocketchip.trace.{TraceCoreParams, TraceCoreInterface} import freechips.rocketchip.resources.{BigIntToProperty, IntToProperty, StringToProperty} import freechips.rocketchip.util.BooleanToAugmentedBoolean +import freechips.rocketchip.tilelink.TLIdentityNode + case object TileVisibilityNodeKey extends Field[TLEphemeralNode] case object TileKey extends Field[TileParams] case object LookupByHartId extends Field[LookupByHartIdImpl] @@ -83,7 +85,11 @@ trait HasNonDiplomaticTileParameters { def vmIdBits: Int = p(VMIdBits) lazy val maxPAddrBits: Int = { require(xLen == 32 || xLen == 64, s"Only XLENs of 32 or 64 are supported, but got $xLen") - xLen match { case 32 => 34; case 64 => 56 } + ((xLen, usingVM): @unchecked) match { + case (_, false) => xLen + case (32, true) => 34 + case (64, true) => 56 + } } def tileId: Int = tileParams.tileId diff --git a/src/main/scala/tile/RocketTile.scala b/src/main/scala/tile/RocketTile.scala index 619e7d836ca..4ec2211358b 100644 --- a/src/main/scala/tile/RocketTile.scala +++ b/src/main/scala/tile/RocketTile.scala @@ -25,6 +25,8 @@ import freechips.rocketchip.rocket.{ import freechips.rocketchip.subsystem.HierarchicalElementCrossingParamsLike import freechips.rocketchip.prci.{ClockSinkParameters, RationalCrossing, ClockCrossingType} import freechips.rocketchip.util.{Annotated, InOrderArbiter} +import freechips.rocketchip.trace.{TraceEncoderParams,TraceEncoderController, TraceSinkArbiter} +import freechips.rocketchip.subsystem._ import freechips.rocketchip.util.BooleanToAugmentedBoolean @@ -40,7 +42,8 @@ case class RocketTileParams( beuAddr: Option[BigInt] = None, blockerCtrlAddr: Option[BigInt] = None, clockSinkParams: ClockSinkParameters = ClockSinkParameters(), - boundaryBuffers: Option[RocketTileBoundaryBufferParams] = None + boundaryBuffers: Option[RocketTileBoundaryBufferParams] = None, + traceParams: Option[TraceEncoderParams] = None ) extends InstantiableTileParams[RocketTile] { require(icache.isDefined) require(dcache.isDefined) @@ -83,6 +86,27 @@ class RocketTile private( beu } + /** + * A Centralized Trace encoder controller, + * controlling enable/disable of trace encoder + * and selecting trace sink + */ + val trace_encoder_controller = rocketParams.traceParams.map { t => + val trace_encoder_controller = LazyModule(new TraceEncoderController(t.encoderBaseAddr, xBytes)) + connectTLSlave(trace_encoder_controller.node, xBytes) + trace_encoder_controller + } + + val trace_encoder = rocketParams.traceParams match { + case Some(t) => Some(t.buildEncoder(p)) + case None => None + } + + val (trace_sinks, traceSinkIds) = rocketParams.traceParams match { + case Some(t) => t.buildSinks.map {_(p)}.unzip + case None => (Nil, Nil) + } + val tile_master_blocker = tileParams.blockerCtrlAddr .map(BasicBusBlockerParams(_, xBytes, masterPortBeatBytes, deadlock = true)) @@ -153,6 +177,30 @@ class RocketTileModuleImp(outer: RocketTile) extends BaseTileModuleImp(outer) // reset vector is connected in the Frontend to s2_pc core.io.reset_vector := DontCare + if (outer.rocketParams.traceParams.isDefined) { + core.io.trace_core_ingress.get <> outer.trace_encoder.get.module.io.in + outer.trace_encoder_controller.foreach { lm => + outer.trace_encoder.get.module.io.control <> lm.module.io.control + } + + val trace_sink_arbiter = Module(new TraceSinkArbiter(outer.traceSinkIds, + use_monitor = outer.rocketParams.traceParams.get.useArbiterMonitor, + monitor_name = outer.rocketParams.uniqueName)) + + trace_sink_arbiter.io.target := outer.trace_encoder.get.module.io.control.target + trace_sink_arbiter.io.in <> outer.trace_encoder.get.module.io.out + + + core.io.traceStall := outer.traceAuxSinkNode.bundle.stall || outer.trace_encoder.get.module.io.stall + + outer.trace_sinks.zip(outer.traceSinkIds).foreach { case (sink, id) => + val index = outer.traceSinkIds.indexOf(id) + sink.module.io.trace_in <> trace_sink_arbiter.io.out(index) + } + } else { + core.io.traceStall := outer.traceAuxSinkNode.bundle.stall + } + // Report unrecoverable error conditions; for now the only cause is cache ECC errors outer.reportHalt(List(outer.dcache.module.io.errors)) @@ -177,7 +225,7 @@ class RocketTileModuleImp(outer: RocketTile) extends BaseTileModuleImp(outer) // Pass through various external constants and reports that were bundle-bridged into the tile outer.traceSourceNode.bundle <> core.io.trace - core.io.traceStall := outer.traceAuxSinkNode.bundle.stall + outer.bpwatchSourceNode.bundle <> core.io.bpwatch core.io.hartid := outer.hartIdSinkNode.bundle require(core.io.hartid.getWidth >= outer.hartIdSinkNode.bundle.getWidth, diff --git a/src/main/scala/tile/TilePRCIDomain.scala b/src/main/scala/tile/TilePRCIDomain.scala index 80c31f5a4d7..a46e6a0aa8d 100644 --- a/src/main/scala/tile/TilePRCIDomain.scala +++ b/src/main/scala/tile/TilePRCIDomain.scala @@ -9,7 +9,7 @@ import org.chipsalliance.cde.config._ import freechips.rocketchip.prci.ClockSinkParameters import freechips.rocketchip.rocket.TracedInstruction import freechips.rocketchip.subsystem.{HierarchicalElementCrossingParamsLike, HierarchicalElementPRCIDomain} -import freechips.rocketchip.util.TraceCoreInterface +import freechips.rocketchip.trace.TraceCoreInterface /** A wrapper containing all logic necessary to safely place a tile diff --git a/src/main/scala/trace/TraceCoreIngress.scala b/src/main/scala/trace/TraceCoreIngress.scala new file mode 100644 index 00000000000..ce4b021feab --- /dev/null +++ b/src/main/scala/trace/TraceCoreIngress.scala @@ -0,0 +1,52 @@ +// See LICENSE.Berkeley for license details. +// See LICENSE.SiFive for license details. + +package freechips.rocketchip.trace + +import chisel3._ + +class TraceCoreIngress(val params: TraceCoreParams) extends Module { + val io = IO(new Bundle { + val in = new Bundle { + val valid = Input(Bool()) + val taken = Input(Bool()) + val is_branch = Input(Bool()) + val is_jal = Input(Bool()) + val is_jalr = Input(Bool()) + val is_compressed = Input(Bool()) + val insn = Input(UInt(params.xlen.W)) + val pc = Input(UInt(params.xlen.W)) + val interrupt = Input(Bool()) + val exception = Input(Bool()) + val trap_return = Input(Bool()) + } + val out = Output(new TraceCoreGroup(params)) + }) + + def gen_itype(insn: UInt, taken: Bool, is_branch: Bool, is_jal: Bool, is_jalr: Bool) = { + val itype = Wire(TraceItype()) + when (io.in.exception) { + itype := TraceItype.ITException + }.elsewhen (io.in.interrupt) { + itype := TraceItype.ITInterrupt + }.elsewhen (io.in.trap_return) { + itype := TraceItype.ITReturn + }.elsewhen (is_branch && taken) { + itype := TraceItype.ITBrTaken + }.elsewhen (is_branch && !taken) { + itype := TraceItype.ITBrNTaken + }.elsewhen (is_jal) { + itype := TraceItype.ITInJump + }.elsewhen (is_jalr) { + itype := TraceItype.ITUnJump + }.otherwise { + itype := TraceItype.ITNothing + } + itype +} + + io.out.iretire := io.in.valid + io.out.iaddr := io.in.pc + io.out.itype := gen_itype(io.in.insn, io.in.taken, io.in.is_branch, io.in.is_jal, io.in.is_jalr) + io.out.ilastsize := io.in.valid && !io.in.is_compressed // 2^1 if non-compressed, 2^0 if compressed +} \ No newline at end of file diff --git a/src/main/scala/util/TraceCoreInterface.scala b/src/main/scala/trace/TraceCoreInterface.scala similarity index 86% rename from src/main/scala/util/TraceCoreInterface.scala rename to src/main/scala/trace/TraceCoreInterface.scala index fad9263a47d..64eb16eb701 100644 --- a/src/main/scala/util/TraceCoreInterface.scala +++ b/src/main/scala/trace/TraceCoreInterface.scala @@ -1,7 +1,7 @@ // See LICENSE.Berkeley for license details. // See LICENSE.SiFive for license details. -package freechips.rocketchip.util +package freechips.rocketchip.trace import chisel3._ @@ -25,13 +25,14 @@ object TraceItype extends ChiselEnum { val ITInJump = Value(15.U) } -class TraceCoreParams ( - val nGroups: Int = 1, - val iretireWidth: Int = 1, - val xlen: Int = 32, - val iaddrWidth: Int = 32 +case class TraceCoreParams ( + nGroups: Int = 1, + iretireWidth: Int = 1, + xlen: Int = 32, + iaddrWidth: Int = 32 ) + class TraceCoreGroup (val params: TraceCoreParams) extends Bundle { val iretire = UInt(params.iretireWidth.W) val iaddr = UInt(params.iaddrWidth.W) @@ -44,5 +45,6 @@ class TraceCoreInterface (val params: TraceCoreParams) extends Bundle { val priv = UInt(4.W) val tval = UInt(params.xlen.W) val cause = UInt(params.xlen.W) + val time = UInt(params.xlen.W) } diff --git a/src/main/scala/trace/TraceEncoder.scala b/src/main/scala/trace/TraceEncoder.scala new file mode 100644 index 00000000000..361a94008d7 --- /dev/null +++ b/src/main/scala/trace/TraceEncoder.scala @@ -0,0 +1,33 @@ +// See LICENSE.Berkeley for license details. +// See LICENSE.SiFive for license details. + +package freechips.rocketchip.trace + +import chisel3._ +import chisel3.util._ +import scala.math.min + +import org.chipsalliance.cde.config.Parameters +import freechips.rocketchip.diplomacy._ + +case class TraceEncoderParams( + encoderBaseAddr: BigInt, + buildEncoder: Parameters => LazyTraceEncoder, + useArbiterMonitor: Boolean, + // a seq of functions that takes a parameter and returns a lazymodule and a target id + buildSinks: Seq[Parameters => (LazyTraceSink, Int)] = Seq.empty[Parameters => (LazyTraceSink, Int)] +) + +class LazyTraceEncoder(val coreParams: TraceCoreParams)(implicit p: Parameters) extends LazyModule { + override lazy val module = new LazyTraceEncoderModule(this) + override def shouldBeInlined = false +} + +class LazyTraceEncoderModule(outer: LazyTraceEncoder) extends LazyModuleImp(outer) { + val io = IO(new Bundle { + val control = Input(new TraceEncoderControlInterface()) + val in = Input(new TraceCoreInterface(outer.coreParams)) + val stall = Output(Bool()) + val out = Decoupled(UInt(8.W)) + }) +} \ No newline at end of file diff --git a/src/main/scala/trace/TraceEncoderController.scala b/src/main/scala/trace/TraceEncoderController.scala new file mode 100644 index 00000000000..2d94bf696a5 --- /dev/null +++ b/src/main/scala/trace/TraceEncoderController.scala @@ -0,0 +1,86 @@ +// See LICENSE.Berkeley for license details. +// See LICENSE.SiFive for license details. + +package freechips.rocketchip.trace + +import chisel3._ +import chisel3.util._ +import org.chipsalliance.cde.config.Parameters +import org.chipsalliance.diplomacy.lazymodule._ +import freechips.rocketchip.diplomacy.{AddressSet} +import freechips.rocketchip.resources.{SimpleDevice} +import freechips.rocketchip.tilelink.TLRegisterNode +import freechips.rocketchip.regmapper.{RegField, RegFieldDesc} + +object TraceSinkTarget { + def width = 8 +} + +class TraceEncoderControlInterface() extends Bundle { + val enable = Bool() + val target = UInt(TraceSinkTarget.width.W) + val hpmcounter_enable = UInt(32.W) + val hpmcounter_report_interval = UInt(32.W) +} +class TraceEncoderController(addr: BigInt, beatBytes: Int)(implicit p: Parameters) extends LazyModule { + + val device = new SimpleDevice("trace-encoder-controller", Seq("ucbbar,trace0")) + val node = TLRegisterNode( + address = Seq(AddressSet(addr, 0xFF)), + device = device, + beatBytes = beatBytes + ) + + override lazy val module = new Impl + class Impl extends LazyModuleImp(this) { + val io = IO(new Bundle { + val control = Output(new TraceEncoderControlInterface()) + }) + + val control_reg_write_valid = Wire(Bool()) + val control_reg_bits = RegInit(1.U(2.W)) + val enable = control_reg_bits(1) + val active = control_reg_bits(0) + io.control.enable := enable + + val trace_encoder_impl = RegInit(0.U(32.W)) + + val trace_sink_target = RegInit(0.U(TraceSinkTarget.width.W)) + io.control.target := trace_sink_target.asUInt + + val trace_hpmcounter_enable = RegInit(0.U(32.W)) + io.control.hpmcounter_enable := trace_hpmcounter_enable + + val trace_hpmcounter_report_interval = RegInit(0.U(32.W)) + io.control.hpmcounter_report_interval := trace_hpmcounter_report_interval + + def traceEncoderControlRegWrite(valid: Bool, bits: UInt): Bool = { + control_reg_write_valid := valid + when (control_reg_write_valid) { + control_reg_bits := bits + } + true.B + } + + def traceEncoderControlRegRead(ready: Bool): (Bool, UInt) = { + (true.B, control_reg_bits) + } + + val regmap = node.regmap( + Seq( + 0x00 -> Seq( + RegField(2, traceEncoderControlRegRead(_), traceEncoderControlRegWrite(_, _), + RegFieldDesc("control", "Control trace encoder")) + ), + 0x04 -> Seq( + RegField.r(32, trace_encoder_impl, + RegFieldDesc("impl", "Trace encoder implementation")) + ), + 0x20 -> Seq( + RegField(1, trace_sink_target, + RegFieldDesc("target", "Trace sink target")) + ) + ):_* + ) + } +} \ No newline at end of file diff --git a/src/main/scala/trace/TraceSink.scala b/src/main/scala/trace/TraceSink.scala new file mode 100644 index 00000000000..ff52e4af4be --- /dev/null +++ b/src/main/scala/trace/TraceSink.scala @@ -0,0 +1,20 @@ +package freechips.rocketchip.trace + +import chisel3._ +import chisel3.util._ +import freechips.rocketchip.tilelink._ +import freechips.rocketchip.diplomacy._ +import org.chipsalliance.cde.config.Parameters +import freechips.rocketchip.prci._ +import freechips.rocketchip.subsystem._ + +abstract class LazyTraceSink()(implicit p: Parameters) extends LazyModule { + val module: LazyTraceSinkModuleImp +} + +class LazyTraceSinkModuleImp(outer: LazyTraceSink) extends LazyModuleImp(outer) { + val io = IO(new Bundle { + val trace_in = Flipped(Decoupled(UInt(8.W))) + }) + io := DontCare +} \ No newline at end of file diff --git a/src/main/scala/trace/TraceSinkArbiter.scala b/src/main/scala/trace/TraceSinkArbiter.scala new file mode 100644 index 00000000000..ac50eae6451 --- /dev/null +++ b/src/main/scala/trace/TraceSinkArbiter.scala @@ -0,0 +1,35 @@ +// See LICENSE.Berkeley for license details. +// See LICENSE.SiFive for license details. + +package freechips.rocketchip.trace + +import chisel3._ +import chisel3.util._ +import org.chipsalliance.cde.config.Parameters +import org.chipsalliance.diplomacy.lazymodule._ +import freechips.rocketchip.diplomacy.{AddressSet} +import freechips.rocketchip.resources.{SimpleDevice} +import freechips.rocketchip.tile._ +import freechips.rocketchip.regmapper.{RegField, RegFieldDesc} + +class TraceSinkArbiter(nSeq : Seq[Int], use_monitor: Boolean = false, monitor_name: String = "unknown") extends Module { + val io = IO(new Bundle { + val target = Input(UInt(TraceSinkTarget.width.W)) + val in = Flipped(Decoupled(UInt(8.W))) + val out = Vec(nSeq.size, Decoupled(UInt(8.W))) + }) + val nVec = VecInit(nSeq.map(_.U)) + io.in.ready := Mux(nVec.contains(io.target), io.out(nVec.indexWhere(_ === io.target)).ready, true.B) + io.out.zipWithIndex.foreach { case (o, i) => + o.valid := io.in.valid && (io.target === nVec(i)) + o.bits := io.in.bits + } + + if (use_monitor) { + val monitor = Module(new TraceSinkMonitor(s"trace_monitor_$monitor_name.out")) + monitor.io.in_fire := io.in.valid && io.in.ready + monitor.io.in_byte := io.in.bits + monitor.io.clk := clock + monitor.io.reset := reset + } +} diff --git a/src/main/scala/trace/TraceSinkMonitor.scala b/src/main/scala/trace/TraceSinkMonitor.scala new file mode 100644 index 00000000000..529f3c11271 --- /dev/null +++ b/src/main/scala/trace/TraceSinkMonitor.scala @@ -0,0 +1,19 @@ +package freechips.rocketchip.trace + +import chisel3._ +import chisel3.util._ +import chisel3.experimental.StringParam + +class TraceSinkMonitor(name: String) extends BlackBox( + Map( + "FILE_NAME" -> StringParam(s"${name}_trace.out") + ) +) with HasBlackBoxResource { + val io = IO(new Bundle { + val clk = Input(Clock()) + val reset = Input(Reset()) + val in_fire = Input(Bool()) + val in_byte = Input(UInt(8.W)) + }) + addResource("/vsrc/TraceSinkMonitor.v") +} \ No newline at end of file diff --git a/src/main/scala/util/Blockable.scala b/src/main/scala/util/Blockable.scala index 3b96995dcf7..38ae6147a2c 100644 --- a/src/main/scala/util/Blockable.scala +++ b/src/main/scala/util/Blockable.scala @@ -6,6 +6,7 @@ import chisel3._ import chisel3.util.DecoupledIO import freechips.rocketchip.tile.{TraceBundle} import freechips.rocketchip.rocket.{TracedInstruction} +import freechips.rocketchip.trace.{TraceCoreInterface, TraceItype} /** A trait supplying a function allowing the contents of data * to be supressed for a time period, i.e. be blocked.