From 445b5da319ac4a83bb199c6c577fb276dc1b4e95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Lanzend=C3=B6rfer?= Date: Mon, 19 Aug 2024 04:43:39 +0100 Subject: [PATCH 01/22] Adding support for Litex There is a naming conflict of the ALU module which prevents a successful synthesis with Yosys. This patch fixes this conflict. In addition, this patch introduces the configurations expected by Litex when generating an SoC This patch also adds a generator for System Verilog which works with Yosys --- build.sc | 64 ++++++- src/main/scala/rocket/ALU.scala | 2 + src/main/scala/rocket/BitManipCrypto.scala | 0 src/main/scala/rocket/CryptoNIST.scala | 0 src/main/scala/subsystem/Litex.scala | 53 ++++++ src/main/scala/system/Litex.scala | 209 +++++++++++++++++++++ 6 files changed, 327 insertions(+), 1 deletion(-) delete mode 100644 src/main/scala/rocket/BitManipCrypto.scala delete mode 100644 src/main/scala/rocket/CryptoNIST.scala create mode 100644 src/main/scala/subsystem/Litex.scala create mode 100644 src/main/scala/system/Litex.scala 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/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/CryptoNIST.scala b/src/main/scala/rocket/CryptoNIST.scala deleted file mode 100644 index e69de29bb2d..00000000000 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 +) From d0c6b50fdefcdbe121e9788433ea51f7efaf1d32 Mon Sep 17 00:00:00 2001 From: John Ingalls <43973001+ingallsj@users.noreply.github.com> Date: Sun, 1 Sep 2024 12:09:41 -0700 Subject: [PATCH 02/22] VM disabled: support larger physical addresses (#3682) --- src/main/scala/rocket/CSR.scala | 2 +- src/main/scala/rocket/PTW.scala | 2 +- src/main/scala/rocket/TLB.scala | 2 +- src/main/scala/tile/BaseTile.scala | 6 +++++- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/main/scala/rocket/CSR.scala b/src/main/scala/rocket/CSR.scala index 407b1e988be..1003838ffa4 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) 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/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/tile/BaseTile.scala b/src/main/scala/tile/BaseTile.scala index 263b73c69a8..21d04607e9c 100644 --- a/src/main/scala/tile/BaseTile.scala +++ b/src/main/scala/tile/BaseTile.scala @@ -83,7 +83,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 From e66d6174bab7e1aae0bda2c678c44979f8c9eb10 Mon Sep 17 00:00:00 2001 From: Benjamin Sternthal Date: Mon, 9 Sep 2024 14:12:49 -0700 Subject: [PATCH 03/22] Add RocketChip Technical Charter Add approved RocketChip technical charter to the project repository. --- RocketChip_Technical_Charter_8-23-2024.pdf | Bin 0 -> 393284 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 RocketChip_Technical_Charter_8-23-2024.pdf diff --git a/RocketChip_Technical_Charter_8-23-2024.pdf b/RocketChip_Technical_Charter_8-23-2024.pdf new file mode 100644 index 0000000000000000000000000000000000000000..2e5ed34ee5f82fec4afbd160590b4f006d20c03b GIT binary patch literal 393284 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 z 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 k2^x~-{)o|eCYZ)IafF?iAe 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 Fe*l{=s-XY? literal 0 HcmV?d00001 From 2c260e2ba804c721068efd3414f20ea08906d83a Mon Sep 17 00:00:00 2001 From: Kian Moniri Date: Mon, 11 Nov 2024 13:43:06 -0500 Subject: [PATCH 04/22] Fix clock gating bug inside RocketCore when the RoCC is busy --- src/main/scala/rocket/RocketCore.scala | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/scala/rocket/RocketCore.scala b/src/main/scala/rocket/RocketCore.scala index 1491a4143e1..dffffb4fa1a 100644 --- a/src/main/scala/rocket/RocketCore.scala +++ b/src/main/scala/rocket/RocketCore.scala @@ -1174,6 +1174,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) From c1e2bd4694e6204682b50c95590362a0173bc373 Mon Sep 17 00:00:00 2001 From: linzhida Date: Wed, 11 Dec 2024 12:11:35 +0800 Subject: [PATCH 05/22] fix BitPat for Vector Mask-Register Logical Instructions Vector mask logical instructions are always unmasked, so there are no inactive elements, and the encodings with vm=0 are reserved. --- src/main/scala/rocket/Instructions.scala | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) 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") From 6b90dc289489c146b80f31a0841bd1dfaef2178c Mon Sep 17 00:00:00 2001 From: chengguanghui Date: Mon, 6 Jan 2025 18:18:54 +0800 Subject: [PATCH 06/22] fix `hartReset` in DM --- src/main/scala/devices/debug/Debug.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/scala/devices/debug/Debug.scala b/src/main/scala/devices/debug/Debug.scala index efaf345fb5f..95982b84690 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) := DMCONTROLNext.hartreset & hartSelected(component) io.hartResetReq.get(component) := hartResetReg(component) } } From 7ae0c21c195d1d02381ef305999a4240f24c69e8 Mon Sep 17 00:00:00 2001 From: Lux Date: Wed, 15 Jan 2025 09:47:11 -0800 Subject: [PATCH 07/22] ADD: core insn trace ingress generation --- src/main/scala/rocket/CSR.scala | 3 +- src/main/scala/rocket/RocketCore.scala | 24 +++++++++ src/main/scala/util/TraceCoreIngressGen.scala | 52 +++++++++++++++++++ src/main/scala/util/TraceCoreInterface.scala | 5 +- 4 files changed, 81 insertions(+), 3 deletions(-) create mode 100644 src/main/scala/util/TraceCoreIngressGen.scala diff --git a/src/main/scala/rocket/CSR.scala b/src/main/scala/rocket/CSR.scala index 407b1e988be..9ed99281e49 100644 --- a/src/main/scala/rocket/CSR.scala +++ b/src/main/scala/rocket/CSR.scala @@ -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/RocketCore.scala b/src/main/scala/rocket/RocketCore.scala index 1491a4143e1..8d8807569c5 100644 --- a/src/main/scala/rocket/RocketCore.scala +++ b/src/main/scala/rocket/RocketCore.scala @@ -131,6 +131,8 @@ class CoreInterrupts(val hasBeu: Boolean)(implicit p: Parameters) extends TileIn trait HasRocketCoreIO extends HasRocketCoreParameters { implicit val p: Parameters def nTotalRoCCCSRs: Int + def ingress_params = new 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 +148,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 = Output(new TraceCoreInterface(ingress_params)) }) } @@ -301,6 +304,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())) @@ -721,6 +725,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 } @@ -823,6 +828,25 @@ class Rocket(tile: RocketTile)(implicit p: Parameters) extends CoreModule()(p) wb_reg_wdata)))) when (rf_wen) { rf.write(rf_waddr, rf_wdata) } + val ingress_gen = Module(new TraceCoreIngressGen(ingress_params)) + ingress_gen.io.in.valid := wb_valid || wb_xcpt + ingress_gen.io.in.taken := wb_reg_br_taken + ingress_gen.io.in.is_branch := wb_ctrl.branch + ingress_gen.io.in.is_jal := wb_ctrl.jal + ingress_gen.io.in.is_jalr := wb_ctrl.jalr + ingress_gen.io.in.insn := wb_reg_inst + ingress_gen.io.in.pc := wb_reg_pc + ingress_gen.io.in.is_compressed := !wb_reg_raw_inst(1, 0).andR // 2'b11 is uncompressed, everything else is compressed + ingress_gen.io.in.interrupt := csr.io.trace(0).interrupt && csr.io.trace(0).exception + ingress_gen.io.in.exception := !csr.io.trace(0).interrupt && csr.io.trace(0).exception + ingress_gen.io.in.trap_return := csr.io.trap_return + + io.trace_core_ingress.group(0) <> ingress_gen.io.out + io.trace_core_ingress.priv := csr.io.trace(0).priv + io.trace_core_ingress.tval := csr.io.tval + io.trace_core_ingress.cause := csr.io.cause + io.trace_core_ingress.time := csr.io.time + // hook up control/status regfile csr.io.ungated_clock := clock csr.io.decode(0).inst := id_inst(0) diff --git a/src/main/scala/util/TraceCoreIngressGen.scala b/src/main/scala/util/TraceCoreIngressGen.scala new file mode 100644 index 00000000000..7a5b2689aa6 --- /dev/null +++ b/src/main/scala/util/TraceCoreIngressGen.scala @@ -0,0 +1,52 @@ +// See LICENSE.Berkeley for license details. +// See LICENSE.SiFive for license details. + +package freechips.rocketchip.util + +import chisel3._ + +class TraceCoreIngressGen(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/util/TraceCoreInterface.scala index fad9263a47d..61a4d4c3b01 100644 --- a/src/main/scala/util/TraceCoreInterface.scala +++ b/src/main/scala/util/TraceCoreInterface.scala @@ -28,8 +28,8 @@ object TraceItype extends ChiselEnum { class TraceCoreParams ( val nGroups: Int = 1, val iretireWidth: Int = 1, - val xlen: Int = 32, - val iaddrWidth: Int = 32 + val xlen: Int = 64, + val iaddrWidth: Int = 64 ) class TraceCoreGroup (val params: TraceCoreParams) extends Bundle { @@ -44,5 +44,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) } From 4147a0f6593624b251df5f5c09e0e633c7e7bfb9 Mon Sep 17 00:00:00 2001 From: Lux Date: Wed, 15 Jan 2025 10:59:03 -0800 Subject: [PATCH 08/22] ADD: tacit trace encoder, controller, and sink --- src/main/scala/util/TraceEncoder.scala | 422 ++++++++++++++++++ .../scala/util/TraceEncoderController.scala | 99 ++++ src/main/scala/util/TraceSink.scala | 166 +++++++ 3 files changed, 687 insertions(+) create mode 100644 src/main/scala/util/TraceEncoder.scala create mode 100644 src/main/scala/util/TraceEncoderController.scala create mode 100644 src/main/scala/util/TraceSink.scala diff --git a/src/main/scala/util/TraceEncoder.scala b/src/main/scala/util/TraceEncoder.scala new file mode 100644 index 00000000000..61f9ffb7f47 --- /dev/null +++ b/src/main/scala/util/TraceEncoder.scala @@ -0,0 +1,422 @@ +// See LICENSE.Berkeley for license details. +// See LICENSE.SiFive for license details. + +package freechips.rocketchip.util + +import chisel3._ +import chisel3.util._ +import scala.math.min + + +class TraceEncoderParams( + val coreParams: TraceCoreParams, + val bufferDepth: Int, + val encoderBaseAddr: BigInt, + val sinkDMABaseAddr: BigInt, + val useSinkPrint: Boolean, + val useSinkDMA: Boolean +) + +object FullHeaderType extends ChiselEnum { + val FTakenBranch = Value(0x0.U) // 000 + val FNotTakenBranch = Value(0x1.U) // 001 + val FUninfJump = Value(0x2.U) // 010 + val FInfJump = Value(0x3.U) // 011 + val FTrap = Value(0x4.U) // 100 + val FSync = Value(0x5.U) // 101 + val FValue = Value(0x6.U) // 110 + val FReserved = Value(0x7.U) // 111 +} + +object CompressedHeaderType extends ChiselEnum { + val CTB = Value(0x0.U) // 00, taken branch + val CNT = Value(0x1.U) // 01, not taken branch + val CNA = Value(0x2.U) // 10, not a compressed packet + val CIJ = Value(0x3.U) // 11, is a jump +} + +object TraceSinkTarget extends ChiselEnum { + val STPrint = Value(0x0.U) // 00, RTL print + val STDMA = Value(0x1.U) // 01, DMA +} + +object TrapType extends ChiselEnum { + val TNone = Value(0x0.U) + val TException = Value(0x1.U) + val TInterrupt = Value(0x2.U) + val TReturn = Value(0x4.U) +} + +object HeaderByte { + def apply(header_type: FullHeaderType.Type, trap_type: TrapType.Type): UInt = { + Cat( + trap_type.asUInt, + header_type.asUInt, + CompressedHeaderType.CNA.asUInt + ) + } +} + +// Variable-length encoding helper module +class VarLenEncoder(val maxWidth: Int) extends Module { + val maxNumBytes = maxWidth/(8-1) + 1 + + val io = IO(new Bundle { + val input_value = Input(UInt(maxWidth.W)) + val input_valid = Input(Bool()) + val output_num_bytes = Output(UInt(log2Ceil(maxNumBytes).W)) + val output_bytes = Output(Vec(maxNumBytes, UInt(8.W))) + }) + + // 0-indexed MSB index + val msb_index = (maxWidth - 1).U - PriorityEncoder(Reverse(io.input_value)) + io.output_num_bytes := Mux(io.input_valid, (msb_index / 7.U) + 1.U, 0.U) + + for (i <- 0 until maxNumBytes) { + val is_last_byte = (i.U === (io.output_num_bytes - 1.U)) + io.output_bytes(i) := Mux(i.U < io.output_num_bytes, + io.input_value(min(i*7+6, maxWidth-1), i*7) | Mux(is_last_byte, 0x80.U, 0.U), + 0.U + ) + } +} + +// slice packets into bytes TODO: is this efficient? +class TracePacketizer(val params: TraceEncoderParams) extends Module { + def getMaxNumBytes(width: Int): Int = { width/(8-1) + 1 } + val addrMaxNumBytes = getMaxNumBytes(params.coreParams.iaddrWidth) + val timeMaxNumBytes = getMaxNumBytes(params.coreParams.xlen) + // println(s"addrMaxNumBytes: $addrMaxNumBytes, timeMaxNumBytes: $timeMaxNumBytes") + val metaDataWidth = 2 * log2Ceil(addrMaxNumBytes) + log2Ceil(timeMaxNumBytes) + 1 + val io = IO(new Bundle { + val target_addr = Flipped(Decoupled(Vec(addrMaxNumBytes, UInt(8.W)))) + val trap_addr = Flipped(Decoupled(Vec(addrMaxNumBytes, UInt(8.W)))) + val time = Flipped(Decoupled(Vec(timeMaxNumBytes, UInt(8.W)))) + val byte = Flipped(Decoupled(UInt(8.W))) + val metadata = Flipped(Decoupled(UInt(metaDataWidth.W))) + val out = Decoupled(UInt(8.W)) + }) + + val pIdle :: pComp :: pFull :: Nil = Enum(3) + val state = RegInit(pIdle) + + val trap_addr_num_bytes = Reg(UInt(log2Ceil(addrMaxNumBytes).W)) + val trap_addr_index = Reg(UInt(log2Ceil(addrMaxNumBytes).W)) + val target_addr_num_bytes = Reg(UInt(log2Ceil(addrMaxNumBytes).W)) + val target_addr_index = Reg(UInt(log2Ceil(addrMaxNumBytes).W)) + val time_num_bytes = Reg(UInt(log2Ceil(timeMaxNumBytes).W)) + val time_index = Reg(UInt(log2Ceil(timeMaxNumBytes).W)) + val header_num_bytes = Reg(UInt(1.W)) + val header_index = Reg(UInt(1.W)) + + val is_compressed = io.metadata.bits(0) + val trap_addr_metadata = io.metadata.bits(metaDataWidth-1, log2Ceil(timeMaxNumBytes)+log2Ceil(addrMaxNumBytes)+1) + val target_addr_metadata = io.metadata.bits(log2Ceil(timeMaxNumBytes)+log2Ceil(addrMaxNumBytes), log2Ceil(timeMaxNumBytes)+1) + val time_metadata = io.metadata.bits(log2Ceil(timeMaxNumBytes), 1) + + // default values + io.out.valid := false.B + io.metadata.ready := false.B + io.target_addr.ready := false.B + io.trap_addr.ready := false.B + io.time.ready := false.B + io.byte.ready := false.B + io.out.bits := 0.U + + def prep_next_state(): Unit = { + trap_addr_index := 0.U + trap_addr_num_bytes := Mux(io.metadata.fire, trap_addr_metadata, 0.U) + target_addr_index := 0.U + target_addr_num_bytes := Mux(io.metadata.fire, target_addr_metadata, 0.U) + time_index := 0.U + time_num_bytes := Mux(io.metadata.fire, time_metadata, 0.U) + header_index := 0.U + header_num_bytes := Mux(io.metadata.fire, ~is_compressed, 0.U) + state := Mux(io.metadata.fire, + Mux(is_compressed, pComp, pFull), + pIdle + ) + } + + switch (state) { + is (pIdle) { + io.metadata.ready := true.B + when (io.metadata.fire) { + trap_addr_num_bytes := trap_addr_metadata + trap_addr_index := 0.U + target_addr_num_bytes := target_addr_metadata + target_addr_index := 0.U + time_num_bytes := time_metadata + time_index := 0.U + header_num_bytes := ~is_compressed + header_index := 0.U + state := Mux(is_compressed, pComp, pFull) + } + } + is (pComp) { + // transmit a byte from byte buffer + io.byte.ready := io.out.ready + io.out.valid := io.byte.valid + io.out.bits := io.byte.bits + when (io.byte.fire) { + // metadata runs ahead by 1 cycle for performance optimization + io.metadata.ready := true.B + prep_next_state() + } + } + is (pFull) { + // header, addr, time + io.out.valid := true.B + when (header_num_bytes > 0.U && header_index < header_num_bytes) { + io.out.bits := io.byte.bits + io.out.valid := io.byte.valid + header_index := header_index + io.out.fire + } .elsewhen (trap_addr_num_bytes > 0.U && trap_addr_index < trap_addr_num_bytes) { + io.out.bits := io.trap_addr.bits(trap_addr_index) + io.out.valid := io.trap_addr.valid + trap_addr_index := trap_addr_index + io.out.fire + } .elsewhen (target_addr_num_bytes > 0.U && target_addr_index < target_addr_num_bytes) { + io.out.bits := io.target_addr.bits(target_addr_index) + io.out.valid := io.target_addr.valid + target_addr_index := target_addr_index + io.out.fire + } .elsewhen (time_num_bytes > 0.U && time_index < time_num_bytes) { + io.out.bits := io.time.bits(time_index) + io.out.valid := io.time.valid + time_index := time_index + io.out.fire + } .otherwise { + // FIXME: delay for 1 cycle + io.out.valid := false.B + // release buffers + io.byte.ready := true.B + // if we ever have a packet, we need to be ready to accept it + io.target_addr.ready := target_addr_num_bytes =/= 0.U + io.trap_addr.ready := trap_addr_num_bytes =/= 0.U + io.time.ready := time_num_bytes =/= 0.U + io.metadata.ready := true.B + prep_next_state() + } + } + } +} + +class TraceEncoder(val params: TraceEncoderParams) extends Module { + val io = IO(new Bundle { + val control = Input(new TraceEncoderControlInterface()) + val in = Input(new TraceCoreInterface(params.coreParams)) + val stall = Output(Bool()) + val out = Decoupled(UInt(8.W)) + }) + + val MAX_DELTA_TIME_COMP = 0xCF // 63, 6 bits + + when (io.stall) { + printf("TraceEncoder stall detected\n") + } + + // states + val sIdle :: sSync :: sData :: Nil = Enum(3) + val state = RegInit(sIdle) + val enabled = RegInit(false.B) + val stall = Wire(Bool()) + val prev_time = Reg(UInt(params.coreParams.xlen.W)) + // pipeline of ingress data + val ingress_0 = RegInit(0.U.asTypeOf(new TraceCoreInterface(params.coreParams))) + val ingress_1 = RegInit(0.U.asTypeOf(new TraceCoreInterface(params.coreParams))) + + // shift every cycle, if not stalled + val pipeline_advance = Wire(Bool()) + pipeline_advance := !stall && io.in.group(0).iretire === 1.U + when (pipeline_advance) { + ingress_0 := io.in + ingress_1 := ingress_0 + } + + // encoders + val trap_addr_encoder = Module(new VarLenEncoder(params.coreParams.iaddrWidth)) + val target_addr_encoder = Module(new VarLenEncoder(params.coreParams.iaddrWidth)) + val time_encoder = Module(new VarLenEncoder(params.coreParams.xlen)) + val metadataWidth = log2Ceil(trap_addr_encoder.maxNumBytes) + log2Ceil(target_addr_encoder.maxNumBytes) + log2Ceil(time_encoder.maxNumBytes) + 1 + + // queue buffers + val trap_addr_buffer = Module(new Queue(Vec(trap_addr_encoder.maxNumBytes, UInt(8.W)), params.bufferDepth)) + val target_addr_buffer = Module(new Queue(Vec(target_addr_encoder.maxNumBytes, UInt(8.W)), params.bufferDepth)) + val time_buffer = Module(new Queue(Vec(time_encoder.maxNumBytes, UInt(8.W)), params.bufferDepth)) + val byte_buffer = Module(new Queue(UInt(8.W), params.bufferDepth)) // buffer compressed packet or full header + val metadata_buffer = Module(new Queue(UInt(metadataWidth.W), params.bufferDepth)) + // intermediate varlen encoder signals + val full_trap_addr = Wire(Vec(trap_addr_encoder.maxNumBytes, UInt(8.W))) + val trap_addr_num_bytes = Wire(UInt(log2Ceil(trap_addr_encoder.maxNumBytes).W)) + val full_target_addr = Wire(Vec(target_addr_encoder.maxNumBytes, UInt(8.W))) + val target_addr_num_bytes = Wire(UInt(log2Ceil(target_addr_encoder.maxNumBytes).W)) + val full_time = Wire(Vec(time_encoder.maxNumBytes, UInt(8.W))) + val time_num_bytes = Wire(UInt(log2Ceil(time_encoder.maxNumBytes).W)) + full_trap_addr := trap_addr_encoder.io.output_bytes + trap_addr_num_bytes := trap_addr_encoder.io.output_num_bytes + full_target_addr := target_addr_encoder.io.output_bytes + target_addr_num_bytes := target_addr_encoder.io.output_num_bytes + full_time := time_encoder.io.output_bytes + time_num_bytes := time_encoder.io.output_num_bytes + + // intermediate packet signals + val is_compressed = Wire(Bool()) + val delta_time = ingress_1.time - prev_time + val packet_valid = Wire(Bool()) + val header_byte = Wire(UInt(8.W)) // full header + val comp_packet = Wire(UInt(8.W)) // compressed packet + val comp_header = Wire(UInt(CompressedHeaderType.getWidth.W)) // compressed header + comp_packet := Cat(delta_time(5, 0), comp_header) + + // packetization of buffered message + val trace_packetizer = Module(new TracePacketizer(params)) + trace_packetizer.io.target_addr <> target_addr_buffer.io.deq + trace_packetizer.io.trap_addr <> trap_addr_buffer.io.deq + trace_packetizer.io.time <> time_buffer.io.deq + trace_packetizer.io.byte <> byte_buffer.io.deq + trace_packetizer.io.metadata <> metadata_buffer.io.deq + trace_packetizer.io.out <> io.out + + // intermediate encoder control signals + val encode_trap_addr_valid = Wire(Bool()) + val encode_target_addr_valid = Wire(Bool()) + + // metadata buffering + val metadata = Cat(trap_addr_num_bytes, target_addr_num_bytes, time_num_bytes, is_compressed) + metadata_buffer.io.enq.bits := metadata + metadata_buffer.io.enq.valid := packet_valid + // buffering compressed packet or full header depending on is_compressed + byte_buffer.io.enq.bits := Mux(is_compressed, comp_packet, header_byte) + byte_buffer.io.enq.valid := packet_valid + // trap address buffering + trap_addr_buffer.io.enq.bits := full_trap_addr + trap_addr_buffer.io.enq.valid := !is_compressed && packet_valid && encode_trap_addr_valid + // target address buffering + target_addr_buffer.io.enq.bits := full_target_addr + target_addr_buffer.io.enq.valid := !is_compressed && packet_valid && encode_target_addr_valid + // time buffering + time_buffer.io.enq.bits := full_time + time_buffer.io.enq.valid := !is_compressed && packet_valid + + // stall if any buffer is full + stall := !target_addr_buffer.io.enq.ready || !time_buffer.io.enq.ready || !byte_buffer.io.enq.ready + io.stall := stall + + val sent = RegInit(false.B) + // reset takes priority over enqueue + when (pipeline_advance) { + sent := false.B + } .elsewhen (byte_buffer.io.enq.fire) { + sent := true.B + } + + trap_addr_encoder.io.input_valid := encode_trap_addr_valid && !is_compressed && packet_valid + target_addr_encoder.io.input_valid := encode_target_addr_valid && !is_compressed && packet_valid + time_encoder.io.input_valid := !is_compressed && packet_valid + + // default values + trap_addr_encoder.io.input_value := 0.U + target_addr_encoder.io.input_value := 0.U + time_encoder.io.input_value := 0.U + is_compressed := false.B + packet_valid := false.B + encode_target_addr_valid := false.B + encode_trap_addr_valid := false.B + comp_header := CompressedHeaderType.CNA.asUInt + header_byte := HeaderByte(FullHeaderType.FReserved, TrapType.TNone) + // state machine + switch (state) { + is (sIdle) { + when (io.control.enable) { state := sSync } + } + is (sSync) { + header_byte := HeaderByte(FullHeaderType.FSync, TrapType.TNone) + time_encoder.io.input_value := ingress_0.time + prev_time := ingress_0.time + target_addr_encoder.io.input_value := ingress_0.group(0).iaddr >> 1.U // last bit is always 0 + encode_target_addr_valid := true.B + is_compressed := false.B + packet_valid := !sent + // state transition: wait for message to go in + state := Mux(pipeline_advance && (sent || byte_buffer.io.enq.fire), Mux(io.control.enable, sData, sIdle), sSync) + } + is (sData) { + when (!io.control.enable) { + state := sSync + } .otherwise { + switch (ingress_1.group(0).itype) { + is (TraceItype.ITNothing) { + packet_valid := false.B + } + is (TraceItype.ITBrTaken) { + header_byte := HeaderByte(FullHeaderType.FTakenBranch, TrapType.TNone) + comp_header := CompressedHeaderType.CTB.asUInt + time_encoder.io.input_value := delta_time + prev_time := ingress_1.time + is_compressed := delta_time <= MAX_DELTA_TIME_COMP.U + packet_valid := !sent + } + is (TraceItype.ITBrNTaken) { + header_byte := HeaderByte(FullHeaderType.FNotTakenBranch, TrapType.TNone) + comp_header := CompressedHeaderType.CNT.asUInt + time_encoder.io.input_value := delta_time + prev_time := ingress_1.time + is_compressed := delta_time <= MAX_DELTA_TIME_COMP.U + packet_valid := !sent + } + is (TraceItype.ITInJump) { + header_byte := HeaderByte(FullHeaderType.FInfJump, TrapType.TNone) + comp_header := CompressedHeaderType.CIJ.asUInt + time_encoder.io.input_value := delta_time + prev_time := ingress_1.time + is_compressed := delta_time <= MAX_DELTA_TIME_COMP.U + packet_valid := !sent + } + is (TraceItype.ITUnJump) { + header_byte := HeaderByte(FullHeaderType.FUninfJump, TrapType.TNone) + time_encoder.io.input_value := delta_time + prev_time := ingress_1.time + target_addr_encoder.io.input_value := (ingress_1.group(0).iaddr ^ ingress_0.group(0).iaddr) >> 1.U + encode_target_addr_valid := true.B + is_compressed := false.B + packet_valid := !sent + } + is (TraceItype.ITException) { + header_byte := HeaderByte(FullHeaderType.FTrap, TrapType.TException) + comp_header := CompressedHeaderType.CNA.asUInt + time_encoder.io.input_value := delta_time + prev_time := ingress_1.time + target_addr_encoder.io.input_value := (ingress_1.group(0).iaddr ^ ingress_0.group(0).iaddr) >> 1.U + encode_target_addr_valid := true.B + trap_addr_encoder.io.input_value := ingress_1.group(0).iaddr + encode_trap_addr_valid := true.B + is_compressed := false.B + packet_valid := !sent + } + is (TraceItype.ITInterrupt) { + header_byte := HeaderByte(FullHeaderType.FTrap, TrapType.TInterrupt) + comp_header := CompressedHeaderType.CNA.asUInt + time_encoder.io.input_value := delta_time + prev_time := ingress_1.time + target_addr_encoder.io.input_value := (ingress_1.group(0).iaddr ^ ingress_0.group(0).iaddr) >> 1.U + encode_target_addr_valid := true.B + trap_addr_encoder.io.input_value := ingress_1.group(0).iaddr + encode_trap_addr_valid := true.B + is_compressed := false.B + packet_valid := !sent + } + is (TraceItype.ITReturn) { + header_byte := HeaderByte(FullHeaderType.FTrap, TrapType.TReturn) + comp_header := CompressedHeaderType.CNA.asUInt + time_encoder.io.input_value := delta_time + prev_time := ingress_1.time + target_addr_encoder.io.input_value := (ingress_1.group(0).iaddr ^ ingress_0.group(0).iaddr) >> 1.U + encode_target_addr_valid := true.B + trap_addr_encoder.io.input_value := ingress_1.group(0).iaddr + encode_trap_addr_valid := true.B + is_compressed := false.B + packet_valid := !sent + } + } + } + } + } +} diff --git a/src/main/scala/util/TraceEncoderController.scala b/src/main/scala/util/TraceEncoderController.scala new file mode 100644 index 00000000000..cf93e2356c5 --- /dev/null +++ b/src/main/scala/util/TraceEncoderController.scala @@ -0,0 +1,99 @@ +// See LICENSE.Berkeley for license details. +// See LICENSE.SiFive for license details. + +package freechips.rocketchip.util + +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} + +class TraceEncoderControlInterface() extends Bundle { + val enable = Bool() + val target = UInt(TraceSinkTarget.getWidth.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_sink_target = RegInit(TraceSinkTarget.STPrint.asUInt) + 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 + printf("Writing to trace encoder control reg from %x to %x\n", + 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(1, trace_sink_target, + RegFieldDesc("target", "Trace sink target")) + ), + 0x08 -> Seq( + RegField(32, trace_hpmcounter_enable, + RegFieldDesc("hpmcounter_enable", "Trace hpmcounter enable")) + ), + 0x0C -> Seq( + RegField(32, trace_hpmcounter_report_interval, + RegFieldDesc("hpmcounter_report_interval", "Trace hpmcounter report interval")) + ) + ):_* + ) + } +} + +class TraceSinkArbiter(n: Int) extends Module { + val io = IO(new Bundle { + val target = Input(UInt(TraceSinkTarget.getWidth.W)) + val in = Flipped(Decoupled(UInt(8.W))) + val out = Vec(n, Decoupled(UInt(8.W))) + }) + io.in.ready := io.out(io.target).ready + io.out.zipWithIndex.foreach { case (o, i) => + o.valid := io.in.valid && (io.target === i.U) + o.bits := io.in.bits + } +} \ No newline at end of file diff --git a/src/main/scala/util/TraceSink.scala b/src/main/scala/util/TraceSink.scala new file mode 100644 index 00000000000..a07cd94c584 --- /dev/null +++ b/src/main/scala/util/TraceSink.scala @@ -0,0 +1,166 @@ +package freechips.rocketchip.util + +import chisel3._ +import chisel3.util._ +import chisel3.experimental.StringParam +import freechips.rocketchip.tilelink._ +import freechips.rocketchip.diplomacy._ +import org.chipsalliance.cde.config.{Parameters, Field, Config} +import freechips.rocketchip.subsystem._ +import freechips.rocketchip.prci._ +import freechips.rocketchip.regmapper.{RegField, RegFieldDesc} + +trait HasTraceSinkIO { + val io = IO(new Bundle { + val in = Flipped(Decoupled(UInt(8.W))) + }) +} + +class TraceSinkPrint(bb_name: String)(implicit p: Parameters) extends LazyModule { + override lazy val module = new TraceSinkPrintImpl(this) + val blackbox_name = bb_name + class TraceSinkPrintImpl(outer: TraceSinkPrint) extends LazyModuleImp(outer) with HasTraceSinkIO { + withClockAndReset(clock, reset) { + io.in.ready := true.B + val byte_printer = Module(new BytePrinter(outer.blackbox_name)) + byte_printer.io.clk := clock + byte_printer.io.reset := reset + byte_printer.io.in_valid := io.in.valid + byte_printer.io.in_byte := io.in.bits + } + } +} + +class BytePrinter(name: String) extends BlackBox( + Map( + "FILE_NAME" -> StringParam(s"tacit_${name}_trace.out") + ) +) with HasBlackBoxResource { + val io = IO(new Bundle { + val clk = Input(Clock()) + val reset = Input(Reset()) + val in_valid = Input(Bool()) + val in_byte = Input(UInt(8.W)) + }) + addResource("/vsrc/BytePrinter.v") +} + +class TraceSinkDMA(addr: BigInt, beatBytes: Int)(implicit p: Parameters) extends LazyModule { + val node = TLClientNode(Seq(TLMasterPortParameters.v1(Seq(TLClientParameters( + name = "trace-sink-dma", sourceId = IdRange(0, 1)))))) + + val device = new SimpleDevice("trace-sink-dma", Seq("ucbbar,trace0")) + val regnode = TLRegisterNode( + address = Seq(AddressSet(addr, 0xFF)), + device = device, + beatBytes = beatBytes + ) + + lazy val module = new TraceSinkDMAImpl(this) + class TraceSinkDMAImpl(outer: TraceSinkDMA) extends LazyModuleImp(outer) with HasTraceSinkIO { + val fifo = Module(new Queue(UInt(8.W), 32)) + fifo.io.enq <> io.in + val (mem, edge) = outer.node.out(0) + val addrBits = edge.bundle.addressBits + val busWidth = edge.bundle.dataBits + val blockBytes = p(CacheBlockBytes) + + val mIdle :: mCollect :: mWrite :: mResp :: Nil = Enum(4) + val mstate = RegInit(mIdle) + + // tracks how much trace data have we written in total + val addr_counter = RegInit(0.U(64.W)) + // tracks how much trace data have we collected in current transaction + val collect_counter = RegInit(0.U(4.W)) + val msg_buffer = RegInit(VecInit(Seq.fill(busWidth / 8)(0.U(8.W)))) + + val dma_start_addr = RegInit(0.U(64.W)) + val dma_addr_write_valid = Wire(Bool()) + + val flush_reg = RegInit(false.B) + val done_reg = RegInit(false.B) + val collect_full = collect_counter === (busWidth / 8).U + val collect_advance = Mux(flush_reg, collect_full || fifo.io.deq.valid === false.B, collect_full) + val flush_done = (flush_reg) && (fifo.io.deq.valid === false.B) + done_reg := done_reg || flush_done + + mem.a.valid := mstate === mWrite + mem.d.ready := mstate === mResp + fifo.io.deq.ready := false.B // default case + dontTouch(mem.d.valid) + + // mask according to collect_counter + val mask = (1.U << collect_counter) - 1.U + // putting the buffer data on the TL mem lane + + val put_req = edge.Put( + fromSource = 0.U, + toAddress = addr_counter + dma_start_addr, + lgSize = log2Ceil(busWidth / 8).U, + data = Cat(msg_buffer.reverse), + mask = mask)._2 + + mem.a.bits := put_req + + switch(mstate) { + is (mIdle) { + fifo.io.deq.ready := false.B + mstate := Mux(fifo.io.deq.valid, mCollect, mIdle) + collect_counter := 0.U + } + is (mCollect) { + // either we have collected enough data or that's all the messages for now + mstate := Mux(collect_advance, mWrite, mCollect) + collect_counter := Mux(fifo.io.deq.fire, collect_counter + 1.U, collect_counter) + msg_buffer(collect_counter) := Mux(fifo.io.deq.fire, fifo.io.deq.bits, msg_buffer(collect_counter)) + fifo.io.deq.ready := collect_counter < (busWidth / 8).U + } + // potentially, optimize this by pipelining collect and write + is (mWrite) { + // we need to write the collected data to the memory + fifo.io.deq.ready := false.B + mstate := Mux(mem.a.fire, mResp, mWrite) + } + is (mResp) { + fifo.io.deq.ready := false.B + mstate := Mux(mem.d.fire, mIdle, mResp) + addr_counter := Mux(mem.d.fire, addr_counter + collect_counter, addr_counter) + } + } + + // regmap handler functions + def traceSinkDMARegWrite(valid: Bool, bits: UInt): Bool = { + dma_addr_write_valid := valid && mstate === mIdle + when (dma_addr_write_valid) { + dma_start_addr := bits + printf("Writing to trace sink DMA reg from %x to %x\n", + dma_start_addr, bits) + } + true.B + } + + def traceSinkDMARegRead(ready: Bool): (Bool, UInt) = { + (true.B, dma_start_addr) + } + + val regmap = regnode.regmap( + Seq( + 0x00 -> Seq( + RegField(1, flush_reg, + RegFieldDesc("flush_reg", "Flush register")) + ), + 0x04 -> Seq( + RegField.r(1, done_reg, + RegFieldDesc("done_reg", "Done register")) + ), + 0x08 -> Seq( + RegField(64, traceSinkDMARegRead(_), traceSinkDMARegWrite(_, _), + RegFieldDesc("dma_start_addr", "DMA start address")) + ), + 0x10 -> Seq(RegField(64, addr_counter, + RegFieldDesc("addr_counter", "Address counter")) + ) + ):_* + ) + } +} \ No newline at end of file From 754bf4c1a5a7b3199e342d0680018434e46d8ccd Mon Sep 17 00:00:00 2001 From: Lux Date: Wed, 15 Jan 2025 11:20:17 -0800 Subject: [PATCH 09/22] ADD: trace tile instantiation and connection --- src/main/scala/subsystem/HasTiles.scala | 10 +++++ src/main/scala/tile/BaseTile.scala | 4 ++ src/main/scala/tile/RocketTile.scala | 50 ++++++++++++++++++++++++- 3 files changed, 62 insertions(+), 2 deletions(-) diff --git a/src/main/scala/subsystem/HasTiles.scala b/src/main/scala/subsystem/HasTiles.scala index ea1f34f7e7b..35abfea854d 100644 --- a/src/main/scala/subsystem/HasTiles.scala +++ b/src/main/scala/subsystem/HasTiles.scala @@ -175,6 +175,7 @@ trait CanAttachTile { connectOutputNotifications(domain, context) connectInputConstants(domain, context) connectTrace(domain, context) + connectTraceSinkDMA(domain, context) } /** Connect the port where the tile is the master to a TileLink interconnect. */ @@ -301,6 +302,15 @@ trait CanAttachTile { resetCrossingType = crossingParams.resetCrossingType) context.traceCoreNodes(domain.element.tileId) :*= traceCoreCrossingNode := domain.element.traceCoreNode } + + /** Function to handle connection from trace sink dma to mbus */ + def connectTraceSinkDMA(domain: TilePRCIDomain[TileType], context: TileContextType): Unit = { + implicit val p = context.p + val mbus = context.locateTLBusWrapper(MBUS) + mbus.coupleFrom(tileParams.baseName) { bus => + bus :=* crossingParams.master.injectNode(context) :=* domain.element.traceSinkIdentityNode + } + } } case class CloneTileAttachParams( diff --git a/src/main/scala/tile/BaseTile.scala b/src/main/scala/tile/BaseTile.scala index 263b73c69a8..a7dfb48e6a2 100644 --- a/src/main/scala/tile/BaseTile.scala +++ b/src/main/scala/tile/BaseTile.scala @@ -24,6 +24,8 @@ import freechips.rocketchip.util.{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] @@ -299,6 +301,8 @@ abstract class BaseTile private (crossing: ClockCrossingType, q: Parameters) val traceCoreSourceNode = BundleBridgeSource(() => new TraceCoreInterface(traceCoreParams)) /** Node for external consumers to source a V1.0 instruction trace from the core. */ val traceCoreNode = traceCoreSourceNode + /** Node for tile to drive encoded instruction trace to external consumers. */ + val traceSinkIdentityNode = TLIdentityNode() /** Node to broadcast collected trace sideband signals into the tile. */ val traceAuxNexusNode = BundleBridgeNexus[TraceAux](default = Some(() => { diff --git a/src/main/scala/tile/RocketTile.scala b/src/main/scala/tile/RocketTile.scala index 619e7d836ca..6bb8f7a9686 100644 --- a/src/main/scala/tile/RocketTile.scala +++ b/src/main/scala/tile/RocketTile.scala @@ -25,6 +25,12 @@ 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.util.{ + Annotated, InOrderArbiter, TraceEncoder, + TraceEncoderParams, TraceSinkPrint, TraceSinkDMA, + TraceEncoderController, TraceSinkArbiter +} +import freechips.rocketchip.subsystem._ import freechips.rocketchip.util.BooleanToAugmentedBoolean @@ -40,7 +46,8 @@ case class RocketTileParams( beuAddr: Option[BigInt] = None, blockerCtrlAddr: Option[BigInt] = None, clockSinkParams: ClockSinkParameters = ClockSinkParameters(), - boundaryBuffers: Option[RocketTileBoundaryBufferParams] = None + boundaryBuffers: Option[RocketTileBoundaryBufferParams] = None, + ltrace: Option[TraceEncoderParams] = None ) extends InstantiableTileParams[RocketTile] { require(icache.isDefined) require(dcache.isDefined) @@ -83,6 +90,23 @@ class RocketTile private( beu } + val trace_encoder_controller = rocketParams.ltrace.map { t => + val trace_encoder_controller = LazyModule(new TraceEncoderController(t.encoderBaseAddr, xBytes)) + connectTLSlave(trace_encoder_controller.node, xBytes) + trace_encoder_controller + } + + val trace_sink_print = rocketParams.ltrace.map { t => + LazyModule(new TraceSinkPrint(rocketParams.uniqueName)) + } + + val trace_sink_dma = rocketParams.ltrace.map { t => + val trace_sink_dma = LazyModule(new TraceSinkDMA(t.sinkDMABaseAddr, xBytes)) + connectTLSlave(trace_sink_dma.regnode, xBytes) + traceSinkIdentityNode := trace_sink_dma.node + trace_sink_dma + } + val tile_master_blocker = tileParams.blockerCtrlAddr .map(BasicBusBlockerParams(_, xBytes, masterPortBeatBytes, deadlock = true)) @@ -153,6 +177,28 @@ 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.ltrace.isDefined) { + val trace_encoder = Module(new TraceEncoder(outer.rocketParams.ltrace.get)) + + core.io.trace_core_ingress <> trace_encoder.io.in + outer.trace_encoder_controller.foreach { lm => + trace_encoder.io.control <> lm.module.io.control + } + + val trace_sink_arbiter = Module(new TraceSinkArbiter(2)) + trace_sink_arbiter.io.target := trace_encoder.io.control.target + trace_sink_arbiter.io.in <> trace_encoder.io.out + outer.trace_sink_print.foreach { lm => + lm.module.io.in <> trace_sink_arbiter.io.out(0) + } + outer.trace_sink_dma.foreach { lm => + lm.module.io.in <> trace_sink_arbiter.io.out(1) + } + core.io.traceStall := outer.traceAuxSinkNode.bundle.stall || trace_encoder.io.stall + } 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 +223,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 + // 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, From c25af3e9711d7f43b3a95984d30846d30d42c464 Mon Sep 17 00:00:00 2001 From: Lux Date: Thu, 16 Jan 2025 15:49:57 -0800 Subject: [PATCH 10/22] ADD: address all PR comments --- src/main/scala/rocket/RocketCore.scala | 46 ++++++++-------- src/main/scala/subsystem/Cluster.scala | 2 +- .../subsystem/HasHierarchicalElements.scala | 2 +- src/main/scala/subsystem/HasTiles.scala | 6 ++- .../HierarchicalElementPRCIDomain.scala | 2 +- src/main/scala/tile/BaseTile.scala | 2 +- src/main/scala/tile/RocketTile.scala | 16 +++--- src/main/scala/tile/TilePRCIDomain.scala | 2 +- src/main/scala/trace/TraceCoreIngress.scala | 52 +++++++++++++++++++ .../{util => trace}/TraceCoreInterface.scala | 13 ++--- .../scala/{util => trace}/TraceEncoder.scala | 16 +++--- .../TraceEncoderController.scala | 2 +- src/main/scala/trace/TraceSink.scala | 16 ++++++ .../TraceSinkDMA.scala} | 40 +------------- src/main/scala/trace/TraceSinkPrint.scala | 38 ++++++++++++++ src/main/scala/util/Blockable.scala | 1 + src/main/scala/util/TraceCoreIngressGen.scala | 52 ------------------- 17 files changed, 170 insertions(+), 138 deletions(-) create mode 100644 src/main/scala/trace/TraceCoreIngress.scala rename src/main/scala/{util => trace}/TraceCoreInterface.scala (88%) rename src/main/scala/{util => trace}/TraceEncoder.scala (98%) rename src/main/scala/{util => trace}/TraceEncoderController.scala (98%) create mode 100644 src/main/scala/trace/TraceSink.scala rename src/main/scala/{util/TraceSink.scala => trace/TraceSinkDMA.scala} (80%) create mode 100644 src/main/scala/trace/TraceSinkPrint.scala delete mode 100644 src/main/scala/util/TraceCoreIngressGen.scala diff --git a/src/main/scala/rocket/RocketCore.scala b/src/main/scala/rocket/RocketCore.scala index 8d8807569c5..5f898f14080 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,7 +133,7 @@ class CoreInterrupts(val hasBeu: Boolean)(implicit p: Parameters) extends TileIn trait HasRocketCoreIO extends HasRocketCoreParameters { implicit val p: Parameters def nTotalRoCCCSRs: Int - def ingress_params = new TraceCoreParams(nGroups = 1, iretireWidth = coreParams.retireWidth, + 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)) @@ -148,7 +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 = Output(new TraceCoreInterface(ingress_params)) + val trace_core_ingress = if (rocketParams.enableTraceCoreIngress) Some(Output(new TraceCoreInterface(traceIngressParams))) else None }) } @@ -828,24 +830,26 @@ class Rocket(tile: RocketTile)(implicit p: Parameters) extends CoreModule()(p) wb_reg_wdata)))) when (rf_wen) { rf.write(rf_waddr, rf_wdata) } - val ingress_gen = Module(new TraceCoreIngressGen(ingress_params)) - ingress_gen.io.in.valid := wb_valid || wb_xcpt - ingress_gen.io.in.taken := wb_reg_br_taken - ingress_gen.io.in.is_branch := wb_ctrl.branch - ingress_gen.io.in.is_jal := wb_ctrl.jal - ingress_gen.io.in.is_jalr := wb_ctrl.jalr - ingress_gen.io.in.insn := wb_reg_inst - ingress_gen.io.in.pc := wb_reg_pc - ingress_gen.io.in.is_compressed := !wb_reg_raw_inst(1, 0).andR // 2'b11 is uncompressed, everything else is compressed - ingress_gen.io.in.interrupt := csr.io.trace(0).interrupt && csr.io.trace(0).exception - ingress_gen.io.in.exception := !csr.io.trace(0).interrupt && csr.io.trace(0).exception - ingress_gen.io.in.trap_return := csr.io.trap_return - - io.trace_core_ingress.group(0) <> ingress_gen.io.out - io.trace_core_ingress.priv := csr.io.trace(0).priv - io.trace_core_ingress.tval := csr.io.tval - io.trace_core_ingress.cause := csr.io.cause - io.trace_core_ingress.time := csr.io.time + 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 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 35abfea854d..7d74e8a4de1 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 @@ -175,6 +175,10 @@ trait CanAttachTile { connectOutputNotifications(domain, context) connectInputConstants(domain, context) connectTrace(domain, context) + /** This is different from connectTrace + * connectTrace is for modules outside of the tile to get trace data + * connectTraceSinkDMA is for trace sink dma to ship trace data outside of the tile + */ connectTraceSinkDMA(domain, context) } 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/tile/BaseTile.scala b/src/main/scala/tile/BaseTile.scala index a7dfb48e6a2..8ad25710c70 100644 --- a/src/main/scala/tile/BaseTile.scala +++ b/src/main/scala/tile/BaseTile.scala @@ -19,7 +19,7 @@ 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 diff --git a/src/main/scala/tile/RocketTile.scala b/src/main/scala/tile/RocketTile.scala index 6bb8f7a9686..04fb4d2f12d 100644 --- a/src/main/scala/tile/RocketTile.scala +++ b/src/main/scala/tile/RocketTile.scala @@ -25,9 +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.util.{ - Annotated, InOrderArbiter, TraceEncoder, - TraceEncoderParams, TraceSinkPrint, TraceSinkDMA, +import freechips.rocketchip.trace.{ + TraceEncoder, TraceEncoderParams, TraceSinkPrint, TraceSinkDMA, TraceEncoderController, TraceSinkArbiter } import freechips.rocketchip.subsystem._ @@ -90,6 +89,11 @@ class RocketTile private( beu } + /** + * A Centralized Trace encoder controller, + * controlling enable/disable of trace encoder + * and selecting trace sink + */ val trace_encoder_controller = rocketParams.ltrace.map { t => val trace_encoder_controller = LazyModule(new TraceEncoderController(t.encoderBaseAddr, xBytes)) connectTLSlave(trace_encoder_controller.node, xBytes) @@ -180,7 +184,7 @@ class RocketTileModuleImp(outer: RocketTile) extends BaseTileModuleImp(outer) if (outer.rocketParams.ltrace.isDefined) { val trace_encoder = Module(new TraceEncoder(outer.rocketParams.ltrace.get)) - core.io.trace_core_ingress <> trace_encoder.io.in + core.io.trace_core_ingress.get <> trace_encoder.io.in outer.trace_encoder_controller.foreach { lm => trace_encoder.io.control <> lm.module.io.control } @@ -189,10 +193,10 @@ class RocketTileModuleImp(outer: RocketTile) extends BaseTileModuleImp(outer) trace_sink_arbiter.io.target := trace_encoder.io.control.target trace_sink_arbiter.io.in <> trace_encoder.io.out outer.trace_sink_print.foreach { lm => - lm.module.io.in <> trace_sink_arbiter.io.out(0) + lm.module.io.trace_in <> trace_sink_arbiter.io.out(0) } outer.trace_sink_dma.foreach { lm => - lm.module.io.in <> trace_sink_arbiter.io.out(1) + lm.module.io.trace_in <> trace_sink_arbiter.io.out(1) } core.io.traceStall := outer.traceAuxSinkNode.bundle.stall || trace_encoder.io.stall } else { 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 88% rename from src/main/scala/util/TraceCoreInterface.scala rename to src/main/scala/trace/TraceCoreInterface.scala index 61a4d4c3b01..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 = 64, - val iaddrWidth: Int = 64 +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) diff --git a/src/main/scala/util/TraceEncoder.scala b/src/main/scala/trace/TraceEncoder.scala similarity index 98% rename from src/main/scala/util/TraceEncoder.scala rename to src/main/scala/trace/TraceEncoder.scala index 61f9ffb7f47..3e61ffcad79 100644 --- a/src/main/scala/util/TraceEncoder.scala +++ b/src/main/scala/trace/TraceEncoder.scala @@ -1,20 +1,20 @@ // See LICENSE.Berkeley for license details. // See LICENSE.SiFive for license details. -package freechips.rocketchip.util +package freechips.rocketchip.trace import chisel3._ import chisel3.util._ import scala.math.min -class TraceEncoderParams( - val coreParams: TraceCoreParams, - val bufferDepth: Int, - val encoderBaseAddr: BigInt, - val sinkDMABaseAddr: BigInt, - val useSinkPrint: Boolean, - val useSinkDMA: Boolean +case class TraceEncoderParams( + coreParams: TraceCoreParams, + bufferDepth: Int, + encoderBaseAddr: BigInt, + sinkDMABaseAddr: BigInt, + useSinkPrint: Boolean, + useSinkDMA: Boolean ) object FullHeaderType extends ChiselEnum { diff --git a/src/main/scala/util/TraceEncoderController.scala b/src/main/scala/trace/TraceEncoderController.scala similarity index 98% rename from src/main/scala/util/TraceEncoderController.scala rename to src/main/scala/trace/TraceEncoderController.scala index cf93e2356c5..d4ed10a1ee1 100644 --- a/src/main/scala/util/TraceEncoderController.scala +++ b/src/main/scala/trace/TraceEncoderController.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._ import chisel3.util._ diff --git a/src/main/scala/trace/TraceSink.scala b/src/main/scala/trace/TraceSink.scala new file mode 100644 index 00000000000..e72cb46453a --- /dev/null +++ b/src/main/scala/trace/TraceSink.scala @@ -0,0 +1,16 @@ +package freechips.rocketchip.trace + +import chisel3._ +import chisel3.util._ +import freechips.rocketchip.tilelink._ +import freechips.rocketchip.diplomacy._ +import org.chipsalliance.cde.config.{Parameters, Field, Config} +import freechips.rocketchip.subsystem._ +import freechips.rocketchip.prci._ +import freechips.rocketchip.regmapper.{RegField, RegFieldDesc} + +trait HasTraceSinkIO { + val io = IO(new Bundle { + val trace_in = Flipped(Decoupled(UInt(8.W))) + }) +} diff --git a/src/main/scala/util/TraceSink.scala b/src/main/scala/trace/TraceSinkDMA.scala similarity index 80% rename from src/main/scala/util/TraceSink.scala rename to src/main/scala/trace/TraceSinkDMA.scala index a07cd94c584..f2de1177233 100644 --- a/src/main/scala/util/TraceSink.scala +++ b/src/main/scala/trace/TraceSinkDMA.scala @@ -1,8 +1,7 @@ -package freechips.rocketchip.util +package freechips.rocketchip.trace import chisel3._ import chisel3.util._ -import chisel3.experimental.StringParam import freechips.rocketchip.tilelink._ import freechips.rocketchip.diplomacy._ import org.chipsalliance.cde.config.{Parameters, Field, Config} @@ -10,41 +9,6 @@ import freechips.rocketchip.subsystem._ import freechips.rocketchip.prci._ import freechips.rocketchip.regmapper.{RegField, RegFieldDesc} -trait HasTraceSinkIO { - val io = IO(new Bundle { - val in = Flipped(Decoupled(UInt(8.W))) - }) -} - -class TraceSinkPrint(bb_name: String)(implicit p: Parameters) extends LazyModule { - override lazy val module = new TraceSinkPrintImpl(this) - val blackbox_name = bb_name - class TraceSinkPrintImpl(outer: TraceSinkPrint) extends LazyModuleImp(outer) with HasTraceSinkIO { - withClockAndReset(clock, reset) { - io.in.ready := true.B - val byte_printer = Module(new BytePrinter(outer.blackbox_name)) - byte_printer.io.clk := clock - byte_printer.io.reset := reset - byte_printer.io.in_valid := io.in.valid - byte_printer.io.in_byte := io.in.bits - } - } -} - -class BytePrinter(name: String) extends BlackBox( - Map( - "FILE_NAME" -> StringParam(s"tacit_${name}_trace.out") - ) -) with HasBlackBoxResource { - val io = IO(new Bundle { - val clk = Input(Clock()) - val reset = Input(Reset()) - val in_valid = Input(Bool()) - val in_byte = Input(UInt(8.W)) - }) - addResource("/vsrc/BytePrinter.v") -} - class TraceSinkDMA(addr: BigInt, beatBytes: Int)(implicit p: Parameters) extends LazyModule { val node = TLClientNode(Seq(TLMasterPortParameters.v1(Seq(TLClientParameters( name = "trace-sink-dma", sourceId = IdRange(0, 1)))))) @@ -59,7 +23,7 @@ class TraceSinkDMA(addr: BigInt, beatBytes: Int)(implicit p: Parameters) extends lazy val module = new TraceSinkDMAImpl(this) class TraceSinkDMAImpl(outer: TraceSinkDMA) extends LazyModuleImp(outer) with HasTraceSinkIO { val fifo = Module(new Queue(UInt(8.W), 32)) - fifo.io.enq <> io.in + fifo.io.enq <> io.trace_in val (mem, edge) = outer.node.out(0) val addrBits = edge.bundle.addressBits val busWidth = edge.bundle.dataBits diff --git a/src/main/scala/trace/TraceSinkPrint.scala b/src/main/scala/trace/TraceSinkPrint.scala new file mode 100644 index 00000000000..275d75b005d --- /dev/null +++ b/src/main/scala/trace/TraceSinkPrint.scala @@ -0,0 +1,38 @@ +package freechips.rocketchip.trace + + +import chisel3._ +import chisel3.util._ +import chisel3.experimental.StringParam +import freechips.rocketchip.diplomacy._ +import freechips.rocketchip.prci._ +import org.chipsalliance.cde.config.{Parameters} + +class TraceSinkPrint(blackbox_file_name: String)(implicit p: Parameters) extends LazyModule { + override lazy val module = new TraceSinkPrintImpl(this) + val blackbox_name = blackbox_file_name + class TraceSinkPrintImpl(outer: TraceSinkPrint) extends LazyModuleImp(outer) with HasTraceSinkIO { + withClockAndReset(clock, reset) { + io.trace_in.ready := true.B + val byte_printer = Module(new BytePrinter(outer.blackbox_name)) + byte_printer.io.clk := clock + byte_printer.io.reset := reset + byte_printer.io.in_valid := io.trace_in.valid + byte_printer.io.in_byte := io.trace_in.bits + } + } +} + +class BytePrinter(name: String) extends BlackBox( + Map( + "FILE_NAME" -> StringParam(s"tacit_${name}_trace.out") + ) +) with HasBlackBoxResource { + val io = IO(new Bundle { + val clk = Input(Clock()) + val reset = Input(Reset()) + val in_valid = Input(Bool()) + val in_byte = Input(UInt(8.W)) + }) + addResource("/vsrc/BytePrinter.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. diff --git a/src/main/scala/util/TraceCoreIngressGen.scala b/src/main/scala/util/TraceCoreIngressGen.scala deleted file mode 100644 index 7a5b2689aa6..00000000000 --- a/src/main/scala/util/TraceCoreIngressGen.scala +++ /dev/null @@ -1,52 +0,0 @@ -// See LICENSE.Berkeley for license details. -// See LICENSE.SiFive for license details. - -package freechips.rocketchip.util - -import chisel3._ - -class TraceCoreIngressGen(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 From 7667eaee119dccef1a32f7bccc315d320905dde1 Mon Sep 17 00:00:00 2001 From: Lux Date: Thu, 16 Jan 2025 15:51:52 -0800 Subject: [PATCH 11/22] ADD: Print BlackBox --- src/main/resources/vsrc/BytePrinter.v | 36 +++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 src/main/resources/vsrc/BytePrinter.v diff --git a/src/main/resources/vsrc/BytePrinter.v b/src/main/resources/vsrc/BytePrinter.v new file mode 100644 index 00000000000..300c487cf52 --- /dev/null +++ b/src/main/resources/vsrc/BytePrinter.v @@ -0,0 +1,36 @@ +module BytePrinter +#( + parameter FILE_NAME = "byte_printer.txt" +) +( + input clk, + input reset, + input in_valid, + input[7:0] in_byte +); + +`ifdef VCS + +integer file; + +initial begin + file = $fopen(FILE_NAME, "w"); + if (file == 0) begin + $display("Failed to open byte_printer.txt"); + $finish; + end +end + +always @(posedge clk) begin + if (in_valid & ~reset) begin + $fwrite(file, "%c", in_byte); + end +end + +final begin + $fclose(file); +end + +`endif + +endmodule \ No newline at end of file From b814ad1d2e9f5f794e96925283971001c0dd231c Mon Sep 17 00:00:00 2001 From: Lux Date: Mon, 20 Jan 2025 13:14:23 -0800 Subject: [PATCH 12/22] REFACTOR: use canhave + traits for sinks for scalability --- .../{BytePrinter.v => TraceSinkMonitor.v} | 10 ++-- src/main/scala/tile/RocketTile.scala | 30 ++++------- src/main/scala/trace/TraceEncoder.scala | 5 +- .../scala/trace/TraceEncoderController.scala | 13 ----- src/main/scala/trace/TraceSink.scala | 24 +++++++-- src/main/scala/trace/TraceSinkAlways.scala | 54 +++++++++++++++++++ src/main/scala/trace/TraceSinkArbiter.scala | 40 ++++++++++++++ src/main/scala/trace/TraceSinkDMA.scala | 49 +++++++++++++++-- src/main/scala/trace/TraceSinkMonitor.scala | 19 +++++++ src/main/scala/trace/TraceSinkPrint.scala | 38 ------------- 10 files changed, 195 insertions(+), 87 deletions(-) rename src/main/resources/vsrc/{BytePrinter.v => TraceSinkMonitor.v} (65%) create mode 100644 src/main/scala/trace/TraceSinkAlways.scala create mode 100644 src/main/scala/trace/TraceSinkArbiter.scala create mode 100644 src/main/scala/trace/TraceSinkMonitor.scala delete mode 100644 src/main/scala/trace/TraceSinkPrint.scala diff --git a/src/main/resources/vsrc/BytePrinter.v b/src/main/resources/vsrc/TraceSinkMonitor.v similarity index 65% rename from src/main/resources/vsrc/BytePrinter.v rename to src/main/resources/vsrc/TraceSinkMonitor.v index 300c487cf52..f2f72ce7f21 100644 --- a/src/main/resources/vsrc/BytePrinter.v +++ b/src/main/resources/vsrc/TraceSinkMonitor.v @@ -1,11 +1,11 @@ -module BytePrinter +module TraceSinkMonitor #( - parameter FILE_NAME = "byte_printer.txt" + parameter FILE_NAME = "trace_sink_monitor.txt" ) ( input clk, input reset, - input in_valid, + input in_fire, input[7:0] in_byte ); @@ -16,13 +16,13 @@ integer file; initial begin file = $fopen(FILE_NAME, "w"); if (file == 0) begin - $display("Failed to open byte_printer.txt"); + $display("Failed to open %s", FILE_NAME); $finish; end end always @(posedge clk) begin - if (in_valid & ~reset) begin + if (in_fire & ~reset) begin $fwrite(file, "%c", in_byte); end end diff --git a/src/main/scala/tile/RocketTile.scala b/src/main/scala/tile/RocketTile.scala index 04fb4d2f12d..22b74a40ac5 100644 --- a/src/main/scala/tile/RocketTile.scala +++ b/src/main/scala/tile/RocketTile.scala @@ -26,12 +26,12 @@ import freechips.rocketchip.subsystem.HierarchicalElementCrossingParamsLike import freechips.rocketchip.prci.{ClockSinkParameters, RationalCrossing, ClockCrossingType} import freechips.rocketchip.util.{Annotated, InOrderArbiter} import freechips.rocketchip.trace.{ - TraceEncoder, TraceEncoderParams, TraceSinkPrint, TraceSinkDMA, - TraceEncoderController, TraceSinkArbiter -} + TraceEncoder, TraceEncoderParams, TraceSinkAlways, TraceSinkDMA, + TraceEncoderController, TraceSinkArbiter} import freechips.rocketchip.subsystem._ import freechips.rocketchip.util.BooleanToAugmentedBoolean +import freechips.rocketchip.trace.CanHaveTraceSinkAlways case class RocketTileBoundaryBufferParams(force: Boolean = false) @@ -100,15 +100,9 @@ class RocketTile private( trace_encoder_controller } - val trace_sink_print = rocketParams.ltrace.map { t => - LazyModule(new TraceSinkPrint(rocketParams.uniqueName)) - } - - val trace_sink_dma = rocketParams.ltrace.map { t => - val trace_sink_dma = LazyModule(new TraceSinkDMA(t.sinkDMABaseAddr, xBytes)) - connectTLSlave(trace_sink_dma.regnode, xBytes) - traceSinkIdentityNode := trace_sink_dma.node - trace_sink_dma + val trace_sink_arbiter = rocketParams.ltrace.map { t => + val trace_sink_arbiter = LazyModule(new TraceSinkArbiter(t.sinks, use_monitor = t.useArbiterMonitor, monitor_name = rocketParams.uniqueName)) + trace_sink_arbiter } val tile_master_blocker = @@ -189,15 +183,11 @@ class RocketTileModuleImp(outer: RocketTile) extends BaseTileModuleImp(outer) trace_encoder.io.control <> lm.module.io.control } - val trace_sink_arbiter = Module(new TraceSinkArbiter(2)) - trace_sink_arbiter.io.target := trace_encoder.io.control.target - trace_sink_arbiter.io.in <> trace_encoder.io.out - outer.trace_sink_print.foreach { lm => - lm.module.io.trace_in <> trace_sink_arbiter.io.out(0) - } - outer.trace_sink_dma.foreach { lm => - lm.module.io.trace_in <> trace_sink_arbiter.io.out(1) + outer.trace_sink_arbiter.foreach { lm => + lm.module.io.target := trace_encoder.io.control.target + lm.module.io.in <> trace_encoder.io.out } + core.io.traceStall := outer.traceAuxSinkNode.bundle.stall || trace_encoder.io.stall } else { core.io.traceStall := outer.traceAuxSinkNode.bundle.stall diff --git a/src/main/scala/trace/TraceEncoder.scala b/src/main/scala/trace/TraceEncoder.scala index 3e61ffcad79..602610f5504 100644 --- a/src/main/scala/trace/TraceEncoder.scala +++ b/src/main/scala/trace/TraceEncoder.scala @@ -12,9 +12,8 @@ case class TraceEncoderParams( coreParams: TraceCoreParams, bufferDepth: Int, encoderBaseAddr: BigInt, - sinkDMABaseAddr: BigInt, - useSinkPrint: Boolean, - useSinkDMA: Boolean + useArbiterMonitor: Boolean, + sinks: Seq[Int] = Seq.empty[Int] ) object FullHeaderType extends ChiselEnum { diff --git a/src/main/scala/trace/TraceEncoderController.scala b/src/main/scala/trace/TraceEncoderController.scala index d4ed10a1ee1..1bdd46c0087 100644 --- a/src/main/scala/trace/TraceEncoderController.scala +++ b/src/main/scala/trace/TraceEncoderController.scala @@ -83,17 +83,4 @@ class TraceEncoderController(addr: BigInt, beatBytes: Int)(implicit p: Parameter ):_* ) } -} - -class TraceSinkArbiter(n: Int) extends Module { - val io = IO(new Bundle { - val target = Input(UInt(TraceSinkTarget.getWidth.W)) - val in = Flipped(Decoupled(UInt(8.W))) - val out = Vec(n, Decoupled(UInt(8.W))) - }) - io.in.ready := io.out(io.target).ready - io.out.zipWithIndex.foreach { case (o, i) => - o.valid := io.in.valid && (io.target === i.U) - o.bits := io.in.bits - } } \ No newline at end of file diff --git a/src/main/scala/trace/TraceSink.scala b/src/main/scala/trace/TraceSink.scala index e72cb46453a..07437c1fbb4 100644 --- a/src/main/scala/trace/TraceSink.scala +++ b/src/main/scala/trace/TraceSink.scala @@ -5,12 +5,28 @@ import chisel3.util._ import freechips.rocketchip.tilelink._ import freechips.rocketchip.diplomacy._ import org.chipsalliance.cde.config.{Parameters, Field, Config} -import freechips.rocketchip.subsystem._ import freechips.rocketchip.prci._ -import freechips.rocketchip.regmapper.{RegField, RegFieldDesc} +import freechips.rocketchip.subsystem._ + +class WithTraceSink(targetId: Int = 0) extends Config((site, here, up) => { + case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map { + case tp: RocketTileAttachParams => { + assert(tp.tileParams.ltrace.isDefined, "TraceSink must be used with a tile that has a trace encoder") + assert(!tp.tileParams.ltrace.get.sinks.contains(targetId), "This targetId is already in use") + tp.copy(tileParams = tp.tileParams.copy( + ltrace = Some(tp.tileParams.ltrace.get.copy(sinks = tp.tileParams.ltrace.get.sinks :+ targetId)))) + } + case other => other + } +}) -trait HasTraceSinkIO { +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/TraceSinkAlways.scala b/src/main/scala/trace/TraceSinkAlways.scala new file mode 100644 index 00000000000..5b53eb0ebff --- /dev/null +++ b/src/main/scala/trace/TraceSinkAlways.scala @@ -0,0 +1,54 @@ +package freechips.rocketchip.trace + +import chisel3._ +import chisel3.util._ +import freechips.rocketchip.diplomacy._ +import freechips.rocketchip.prci._ +import org.chipsalliance.cde.config.{Parameters, Config, Field} +import freechips.rocketchip.tile._ +import freechips.rocketchip.subsystem._ +case object TraceSinkAlwaysKey extends Field[Option[Int]](None) + +class TraceSinkAlways()(implicit p: Parameters) extends LazyModule { + println(s"TraceSinkAlways Lazy Init}") + override lazy val module = new TraceSinkAlwaysImpl(this) + class TraceSinkAlwaysImpl(outer: TraceSinkAlways) extends LazyModuleImp(outer) { + println(s"TraceSinkAlways Impl Init") + val io = IO(new Bundle { + val trace_in = Flipped(Decoupled(UInt(8.W))) + }) + withClockAndReset(clock, reset) { + io.trace_in.ready := true.B + } + } +} + +class WithTraceSinkAlways(targetId: Int = 0) extends Config( + (new WithTraceSink(targetId)).alter((site, here, up) => { + case TraceSinkAlwaysKey => Some(targetId) + }) +) + +trait CanHaveTraceSinkAlways {this: BaseSubsystem with InstantiatesHierarchicalElements => + val traceSinkAlways = p(TraceSinkAlwaysKey) match { + case Some(targetId) => { + val arbs = totalTiles.values.map { t => t match { + case r: RocketTile => List((t, r.trace_sink_arbiter.get)) + case _ => Nil + }}.flatten + + arbs.map { case (t, arb) => + t { // in the implicit clock domain of tile + val traceSinkAlways = LazyModule(new TraceSinkAlways()(p)) + val index = t.asInstanceOf[RocketTile].rocketParams.ltrace.get.sinks.indexOf(targetId) + println(s"What? $index") + InModuleBody { + println(s"TraceSinkAlways In Module Body") + traceSinkAlways.module.io.trace_in <> arb.module.io.out(index) + } + } + } + } + case _ => None + } +} \ 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..733dd351ae1 --- /dev/null +++ b/src/main/scala/trace/TraceSinkArbiter.scala @@ -0,0 +1,40 @@ +// 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")(implicit p: Parameters) extends LazyModule { + println(s"TraceSinkArbiter nSeq: $nSeq") + override lazy val module = new TraceSinkArbiterModuleImp(this) + class TraceSinkArbiterModuleImp(outer: TraceSinkArbiter) extends LazyModuleImp(outer) { + val io = IO(new Bundle { + val target = Input(UInt(TraceSinkTarget.getWidth.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")) + println(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/TraceSinkDMA.scala b/src/main/scala/trace/TraceSinkDMA.scala index f2de1177233..d82edbd6eb7 100644 --- a/src/main/scala/trace/TraceSinkDMA.scala +++ b/src/main/scala/trace/TraceSinkDMA.scala @@ -8,20 +8,28 @@ import org.chipsalliance.cde.config.{Parameters, Field, Config} import freechips.rocketchip.subsystem._ import freechips.rocketchip.prci._ import freechips.rocketchip.regmapper.{RegField, RegFieldDesc} +import freechips.rocketchip.tile._ -class TraceSinkDMA(addr: BigInt, beatBytes: Int)(implicit p: Parameters) extends LazyModule { +case object TraceSinkDMAKey extends Field[Option[Int]](None) + +case class TraceSinkDMAParams( + regNodeBaseAddr: BigInt, + beatBytes: Int +) + +class TraceSinkDMA(params: TraceSinkDMAParams)(implicit p: Parameters) extends LazyTraceSink { val node = TLClientNode(Seq(TLMasterPortParameters.v1(Seq(TLClientParameters( name = "trace-sink-dma", sourceId = IdRange(0, 1)))))) val device = new SimpleDevice("trace-sink-dma", Seq("ucbbar,trace0")) val regnode = TLRegisterNode( - address = Seq(AddressSet(addr, 0xFF)), + address = Seq(AddressSet(params.regNodeBaseAddr, 0xFF)), device = device, - beatBytes = beatBytes + beatBytes = params.beatBytes ) lazy val module = new TraceSinkDMAImpl(this) - class TraceSinkDMAImpl(outer: TraceSinkDMA) extends LazyModuleImp(outer) with HasTraceSinkIO { + class TraceSinkDMAImpl(outer: TraceSinkDMA) extends LazyTraceSinkModuleImp(outer) { val fifo = Module(new Queue(UInt(8.W), 32)) fifo.io.enq <> io.trace_in val (mem, edge) = outer.node.out(0) @@ -127,4 +135,37 @@ class TraceSinkDMA(addr: BigInt, beatBytes: Int)(implicit p: Parameters) extends ):_* ) } +} + +class WithTraceSinkDMA(targetId: Int = 1) extends Config( + (new WithTraceSink(targetId)).alter((site, here, up) => { + case TraceSinkDMAKey => Some(targetId) + }) +) + +trait CanHaveTraceSinkDMA {this: BaseSubsystem with InstantiatesHierarchicalElements => + val traceSinkDMA = p(TraceSinkDMAKey) match { + case Some(targetId) => { + val arbs = totalTiles.values.map { t => t match { + case r: RocketTile => List((t, r.trace_sink_arbiter.get)) + case _ => Nil + }}.flatten + arbs.map { case (t, arb) => + t { // in the implicit clock domain of tile + val traceSinkDMA = LazyModule(new TraceSinkDMA(TraceSinkDMAParams( + regNodeBaseAddr = 0x3010000 + t.tileParams.tileId * 0x1000, + beatBytes = t.xBytes + ))(p)) + val index = t.asInstanceOf[RocketTile].rocketParams.ltrace.get.sinks.indexOf(targetId) + t.connectTLSlave(traceSinkDMA.regnode, t.xBytes) + t.traceSinkIdentityNode := traceSinkDMA.node + + InModuleBody { + traceSinkDMA.module.io.trace_in <> arb.module.io.out(index) + } + } + } + } + case _ => None + } } \ No newline at end of file diff --git a/src/main/scala/trace/TraceSinkMonitor.scala b/src/main/scala/trace/TraceSinkMonitor.scala new file mode 100644 index 00000000000..111a21fdb69 --- /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"tacit_${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/trace/TraceSinkPrint.scala b/src/main/scala/trace/TraceSinkPrint.scala deleted file mode 100644 index 275d75b005d..00000000000 --- a/src/main/scala/trace/TraceSinkPrint.scala +++ /dev/null @@ -1,38 +0,0 @@ -package freechips.rocketchip.trace - - -import chisel3._ -import chisel3.util._ -import chisel3.experimental.StringParam -import freechips.rocketchip.diplomacy._ -import freechips.rocketchip.prci._ -import org.chipsalliance.cde.config.{Parameters} - -class TraceSinkPrint(blackbox_file_name: String)(implicit p: Parameters) extends LazyModule { - override lazy val module = new TraceSinkPrintImpl(this) - val blackbox_name = blackbox_file_name - class TraceSinkPrintImpl(outer: TraceSinkPrint) extends LazyModuleImp(outer) with HasTraceSinkIO { - withClockAndReset(clock, reset) { - io.trace_in.ready := true.B - val byte_printer = Module(new BytePrinter(outer.blackbox_name)) - byte_printer.io.clk := clock - byte_printer.io.reset := reset - byte_printer.io.in_valid := io.trace_in.valid - byte_printer.io.in_byte := io.trace_in.bits - } - } -} - -class BytePrinter(name: String) extends BlackBox( - Map( - "FILE_NAME" -> StringParam(s"tacit_${name}_trace.out") - ) -) with HasBlackBoxResource { - val io = IO(new Bundle { - val clk = Input(Clock()) - val reset = Input(Reset()) - val in_valid = Input(Bool()) - val in_byte = Input(UInt(8.W)) - }) - addResource("/vsrc/BytePrinter.v") -} \ No newline at end of file From 8d29be4fc604ad441979808d8f0b5355c89209ed Mon Sep 17 00:00:00 2001 From: Lux Date: Mon, 20 Jan 2025 15:46:54 -0800 Subject: [PATCH 13/22] ADD: bump TraceSinkDMA to inject node from trait instead of in tiles --- src/main/scala/subsystem/HasTiles.scala | 14 -------------- src/main/scala/tile/BaseTile.scala | 2 -- src/main/scala/trace/TraceSinkDMA.scala | 6 ++++-- 3 files changed, 4 insertions(+), 18 deletions(-) diff --git a/src/main/scala/subsystem/HasTiles.scala b/src/main/scala/subsystem/HasTiles.scala index 7d74e8a4de1..5a0f0b856c6 100644 --- a/src/main/scala/subsystem/HasTiles.scala +++ b/src/main/scala/subsystem/HasTiles.scala @@ -175,11 +175,6 @@ trait CanAttachTile { connectOutputNotifications(domain, context) connectInputConstants(domain, context) connectTrace(domain, context) - /** This is different from connectTrace - * connectTrace is for modules outside of the tile to get trace data - * connectTraceSinkDMA is for trace sink dma to ship trace data outside of the tile - */ - connectTraceSinkDMA(domain, context) } /** Connect the port where the tile is the master to a TileLink interconnect. */ @@ -306,15 +301,6 @@ trait CanAttachTile { resetCrossingType = crossingParams.resetCrossingType) context.traceCoreNodes(domain.element.tileId) :*= traceCoreCrossingNode := domain.element.traceCoreNode } - - /** Function to handle connection from trace sink dma to mbus */ - def connectTraceSinkDMA(domain: TilePRCIDomain[TileType], context: TileContextType): Unit = { - implicit val p = context.p - val mbus = context.locateTLBusWrapper(MBUS) - mbus.coupleFrom(tileParams.baseName) { bus => - bus :=* crossingParams.master.injectNode(context) :=* domain.element.traceSinkIdentityNode - } - } } case class CloneTileAttachParams( diff --git a/src/main/scala/tile/BaseTile.scala b/src/main/scala/tile/BaseTile.scala index 8ad25710c70..898827abeeb 100644 --- a/src/main/scala/tile/BaseTile.scala +++ b/src/main/scala/tile/BaseTile.scala @@ -301,8 +301,6 @@ abstract class BaseTile private (crossing: ClockCrossingType, q: Parameters) val traceCoreSourceNode = BundleBridgeSource(() => new TraceCoreInterface(traceCoreParams)) /** Node for external consumers to source a V1.0 instruction trace from the core. */ val traceCoreNode = traceCoreSourceNode - /** Node for tile to drive encoded instruction trace to external consumers. */ - val traceSinkIdentityNode = TLIdentityNode() /** Node to broadcast collected trace sideband signals into the tile. */ val traceAuxNexusNode = BundleBridgeNexus[TraceAux](default = Some(() => { diff --git a/src/main/scala/trace/TraceSinkDMA.scala b/src/main/scala/trace/TraceSinkDMA.scala index d82edbd6eb7..4353faed1d3 100644 --- a/src/main/scala/trace/TraceSinkDMA.scala +++ b/src/main/scala/trace/TraceSinkDMA.scala @@ -158,8 +158,10 @@ trait CanHaveTraceSinkDMA {this: BaseSubsystem with InstantiatesHierarchicalElem ))(p)) val index = t.asInstanceOf[RocketTile].rocketParams.ltrace.get.sinks.indexOf(targetId) t.connectTLSlave(traceSinkDMA.regnode, t.xBytes) - t.traceSinkIdentityNode := traceSinkDMA.node - + val mbus = locateTLBusWrapper(MBUS) + mbus.coupleFrom(t.tileParams.baseName) { bus => + bus := mbus.crossOut(traceSinkDMA.node)(ValName("trace_sink_dma"))(AsynchronousCrossing()) + } InModuleBody { traceSinkDMA.module.io.trace_in <> arb.module.io.out(index) } From 84cbd51409ad4d89424f1b887db72b85e19a625d Mon Sep 17 00:00:00 2001 From: Lux Date: Mon, 20 Jan 2025 16:08:45 -0800 Subject: [PATCH 14/22] ADD: tail case bug fix --- src/main/scala/trace/TraceSinkDMA.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/scala/trace/TraceSinkDMA.scala b/src/main/scala/trace/TraceSinkDMA.scala index 4353faed1d3..ef46aef86bb 100644 --- a/src/main/scala/trace/TraceSinkDMA.scala +++ b/src/main/scala/trace/TraceSinkDMA.scala @@ -53,7 +53,7 @@ class TraceSinkDMA(params: TraceSinkDMAParams)(implicit p: Parameters) extends L val done_reg = RegInit(false.B) val collect_full = collect_counter === (busWidth / 8).U val collect_advance = Mux(flush_reg, collect_full || fifo.io.deq.valid === false.B, collect_full) - val flush_done = (flush_reg) && (fifo.io.deq.valid === false.B) + val flush_done = (flush_reg) && (fifo.io.deq.valid === false.B) && mstate === mIdle done_reg := done_reg || flush_done mem.a.valid := mstate === mWrite From ab79600171e9bcda50610a5c81a9d17d46f59a09 Mon Sep 17 00:00:00 2001 From: Lux Date: Thu, 23 Jan 2025 13:38:17 -0800 Subject: [PATCH 15/22] REFACTOR: reorganize code structure --- src/main/scala/tile/RocketTile.scala | 17 +++++-- src/main/scala/trace/TraceEncoder.scala | 4 +- src/main/scala/trace/TraceSink.scala | 12 ----- src/main/scala/trace/TraceSinkAlways.scala | 48 +++++------------- src/main/scala/trace/TraceSinkDMA.scala | 57 +++++++++++----------- 5 files changed, 56 insertions(+), 82 deletions(-) diff --git a/src/main/scala/tile/RocketTile.scala b/src/main/scala/tile/RocketTile.scala index 22b74a40ac5..050176ae6d5 100644 --- a/src/main/scala/tile/RocketTile.scala +++ b/src/main/scala/tile/RocketTile.scala @@ -31,7 +31,6 @@ import freechips.rocketchip.trace.{ import freechips.rocketchip.subsystem._ import freechips.rocketchip.util.BooleanToAugmentedBoolean -import freechips.rocketchip.trace.CanHaveTraceSinkAlways case class RocketTileBoundaryBufferParams(force: Boolean = false) @@ -100,9 +99,16 @@ class RocketTile private( trace_encoder_controller } + val (trace_sinks, trace_sink_ids) = rocketParams.ltrace match { + case Some(t) => + val sequence = t.buildSinks.map {_(p)} + (sequence.map(_._1), sequence.map(_._2)) + case None => (Seq.empty, Seq.empty) + } + val trace_sink_arbiter = rocketParams.ltrace.map { t => - val trace_sink_arbiter = LazyModule(new TraceSinkArbiter(t.sinks, use_monitor = t.useArbiterMonitor, monitor_name = rocketParams.uniqueName)) - trace_sink_arbiter + val arb = LazyModule(new TraceSinkArbiter(trace_sink_ids, use_monitor = t.useArbiterMonitor, monitor_name = rocketParams.uniqueName)) + arb } val tile_master_blocker = @@ -193,6 +199,11 @@ class RocketTileModuleImp(outer: RocketTile) extends BaseTileModuleImp(outer) core.io.traceStall := outer.traceAuxSinkNode.bundle.stall } + outer.trace_sinks.zip(outer.trace_sink_ids).foreach { case (sink, id) => + val index = outer.trace_sink_ids.indexOf(id) + sink.module.io.trace_in <> outer.trace_sink_arbiter.get.module.io.out(index) + } + // Report unrecoverable error conditions; for now the only cause is cache ECC errors outer.reportHalt(List(outer.dcache.module.io.errors)) diff --git a/src/main/scala/trace/TraceEncoder.scala b/src/main/scala/trace/TraceEncoder.scala index 602610f5504..ee55162f4d5 100644 --- a/src/main/scala/trace/TraceEncoder.scala +++ b/src/main/scala/trace/TraceEncoder.scala @@ -7,13 +7,15 @@ import chisel3._ import chisel3.util._ import scala.math.min +import org.chipsalliance.cde.config.Parameters case class TraceEncoderParams( coreParams: TraceCoreParams, bufferDepth: Int, encoderBaseAddr: BigInt, useArbiterMonitor: Boolean, - sinks: Seq[Int] = Seq.empty[Int] + // 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)] ) object FullHeaderType extends ChiselEnum { diff --git a/src/main/scala/trace/TraceSink.scala b/src/main/scala/trace/TraceSink.scala index 07437c1fbb4..9d6b5fcf525 100644 --- a/src/main/scala/trace/TraceSink.scala +++ b/src/main/scala/trace/TraceSink.scala @@ -8,18 +8,6 @@ import org.chipsalliance.cde.config.{Parameters, Field, Config} import freechips.rocketchip.prci._ import freechips.rocketchip.subsystem._ -class WithTraceSink(targetId: Int = 0) extends Config((site, here, up) => { - case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map { - case tp: RocketTileAttachParams => { - assert(tp.tileParams.ltrace.isDefined, "TraceSink must be used with a tile that has a trace encoder") - assert(!tp.tileParams.ltrace.get.sinks.contains(targetId), "This targetId is already in use") - tp.copy(tileParams = tp.tileParams.copy( - ltrace = Some(tp.tileParams.ltrace.get.copy(sinks = tp.tileParams.ltrace.get.sinks :+ targetId)))) - } - case other => other - } -}) - abstract class LazyTraceSink()(implicit p: Parameters) extends LazyModule { val module: LazyTraceSinkModuleImp } diff --git a/src/main/scala/trace/TraceSinkAlways.scala b/src/main/scala/trace/TraceSinkAlways.scala index 5b53eb0ebff..c22e762a6a5 100644 --- a/src/main/scala/trace/TraceSinkAlways.scala +++ b/src/main/scala/trace/TraceSinkAlways.scala @@ -9,46 +9,20 @@ import freechips.rocketchip.tile._ import freechips.rocketchip.subsystem._ case object TraceSinkAlwaysKey extends Field[Option[Int]](None) -class TraceSinkAlways()(implicit p: Parameters) extends LazyModule { - println(s"TraceSinkAlways Lazy Init}") +class TraceSinkAlways()(implicit p: Parameters) extends LazyTraceSink { override lazy val module = new TraceSinkAlwaysImpl(this) - class TraceSinkAlwaysImpl(outer: TraceSinkAlways) extends LazyModuleImp(outer) { - println(s"TraceSinkAlways Impl Init") - val io = IO(new Bundle { - val trace_in = Flipped(Decoupled(UInt(8.W))) - }) - withClockAndReset(clock, reset) { - io.trace_in.ready := true.B - } + class TraceSinkAlwaysImpl(outer: TraceSinkAlways) extends LazyTraceSinkModuleImp(outer) { + io.trace_in.ready := true.B } } -class WithTraceSinkAlways(targetId: Int = 0) extends Config( - (new WithTraceSink(targetId)).alter((site, here, up) => { - case TraceSinkAlwaysKey => Some(targetId) - }) -) - -trait CanHaveTraceSinkAlways {this: BaseSubsystem with InstantiatesHierarchicalElements => - val traceSinkAlways = p(TraceSinkAlwaysKey) match { - case Some(targetId) => { - val arbs = totalTiles.values.map { t => t match { - case r: RocketTile => List((t, r.trace_sink_arbiter.get)) - case _ => Nil - }}.flatten - - arbs.map { case (t, arb) => - t { // in the implicit clock domain of tile - val traceSinkAlways = LazyModule(new TraceSinkAlways()(p)) - val index = t.asInstanceOf[RocketTile].rocketParams.ltrace.get.sinks.indexOf(targetId) - println(s"What? $index") - InModuleBody { - println(s"TraceSinkAlways In Module Body") - traceSinkAlways.module.io.trace_in <> arb.module.io.out(index) - } - } - } +class WithTraceSinkAlways(targetId: Int = 0) extends Config((site, here, up) => { + case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map { + case tp: RocketTileAttachParams => { + tp.copy(tileParams = tp.tileParams.copy( + ltrace = Some(tp.tileParams.ltrace.get.copy(buildSinks = tp.tileParams.ltrace.get.buildSinks :+ (p => (LazyModule(new TraceSinkAlways()(p)), targetId))))) + ) } - case _ => None + case other => other } -} \ No newline at end of file +}) \ No newline at end of file diff --git a/src/main/scala/trace/TraceSinkDMA.scala b/src/main/scala/trace/TraceSinkDMA.scala index ef46aef86bb..6a34c01ece2 100644 --- a/src/main/scala/trace/TraceSinkDMA.scala +++ b/src/main/scala/trace/TraceSinkDMA.scala @@ -137,37 +137,36 @@ class TraceSinkDMA(params: TraceSinkDMAParams)(implicit p: Parameters) extends L } } -class WithTraceSinkDMA(targetId: Int = 1) extends Config( - (new WithTraceSink(targetId)).alter((site, here, up) => { - case TraceSinkDMAKey => Some(targetId) - }) -) +class WithTraceSinkDMA(targetId: Int = 1) extends Config((site, here, up) => { + case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map { + case tp: RocketTileAttachParams => { + // redefine tile level constants + val xBytes = tp.tileParams.core.xLen / 8 + tp.copy(tileParams = tp.tileParams.copy( + ltrace = Some(tp.tileParams.ltrace.get.copy(buildSinks = + tp.tileParams.ltrace.get.buildSinks :+ (p => + (LazyModule(new TraceSinkDMA(TraceSinkDMAParams( + regNodeBaseAddr = 0x3010000 + tp.tileParams.tileId * 0x1000, + beatBytes = xBytes + ))(p)), targetId))))) + ) + } + case other => other + } +}) trait CanHaveTraceSinkDMA {this: BaseSubsystem with InstantiatesHierarchicalElements => - val traceSinkDMA = p(TraceSinkDMAKey) match { - case Some(targetId) => { - val arbs = totalTiles.values.map { t => t match { - case r: RocketTile => List((t, r.trace_sink_arbiter.get)) - case _ => Nil - }}.flatten - arbs.map { case (t, arb) => - t { // in the implicit clock domain of tile - val traceSinkDMA = LazyModule(new TraceSinkDMA(TraceSinkDMAParams( - regNodeBaseAddr = 0x3010000 + t.tileParams.tileId * 0x1000, - beatBytes = t.xBytes - ))(p)) - val index = t.asInstanceOf[RocketTile].rocketParams.ltrace.get.sinks.indexOf(targetId) - t.connectTLSlave(traceSinkDMA.regnode, t.xBytes) - val mbus = locateTLBusWrapper(MBUS) - mbus.coupleFrom(t.tileParams.baseName) { bus => - bus := mbus.crossOut(traceSinkDMA.node)(ValName("trace_sink_dma"))(AsynchronousCrossing()) - } - InModuleBody { - traceSinkDMA.module.io.trace_in <> arb.module.io.out(index) - } - } + val traceSinkDMAs = totalTiles.values.map { t => t match { + case r: RocketTile => r.trace_sinks.collect { case r: TraceSinkDMA => (t, r) } + case _ => Nil + }}.flatten + val mbus = locateTLBusWrapper(MBUS) + traceSinkDMAs.foreach { case (t, s) => + t { // in the implicit clock domain of tile + mbus.coupleFrom(t.tileParams.baseName) { bus => + bus := mbus.crossOut(s.node)(ValName("trace_sink_dma"))(AsynchronousCrossing()) } + t.connectTLSlave(s.regnode, t.xBytes) } - case _ => None } -} \ No newline at end of file +} From 7acebde35dc89b9f81fa1699c608eda56545f9a8 Mon Sep 17 00:00:00 2001 From: Lux Date: Thu, 23 Jan 2025 14:05:21 -0800 Subject: [PATCH 16/22] ADD: remove prints, cleanup code --- src/main/scala/tile/RocketTile.scala | 14 ++++++-------- src/main/scala/trace/TraceSinkArbiter.scala | 2 -- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/src/main/scala/tile/RocketTile.scala b/src/main/scala/tile/RocketTile.scala index 050176ae6d5..1662a24e4b4 100644 --- a/src/main/scala/tile/RocketTile.scala +++ b/src/main/scala/tile/RocketTile.scala @@ -99,15 +99,13 @@ class RocketTile private( trace_encoder_controller } - val (trace_sinks, trace_sink_ids) = rocketParams.ltrace match { - case Some(t) => - val sequence = t.buildSinks.map {_(p)} - (sequence.map(_._1), sequence.map(_._2)) - case None => (Seq.empty, Seq.empty) + val (trace_sinks, traceSinkIds) = rocketParams.ltrace match { + case Some(t) => t.buildSinks.map {_(p)}.unzip + case None => (Nil, Nil) } val trace_sink_arbiter = rocketParams.ltrace.map { t => - val arb = LazyModule(new TraceSinkArbiter(trace_sink_ids, use_monitor = t.useArbiterMonitor, monitor_name = rocketParams.uniqueName)) + val arb = LazyModule(new TraceSinkArbiter(traceSinkIds, use_monitor = t.useArbiterMonitor, monitor_name = rocketParams.uniqueName)) arb } @@ -199,8 +197,8 @@ class RocketTileModuleImp(outer: RocketTile) extends BaseTileModuleImp(outer) core.io.traceStall := outer.traceAuxSinkNode.bundle.stall } - outer.trace_sinks.zip(outer.trace_sink_ids).foreach { case (sink, id) => - val index = outer.trace_sink_ids.indexOf(id) + outer.trace_sinks.zip(outer.traceSinkIds).foreach { case (sink, id) => + val index = outer.traceSinkIds.indexOf(id) sink.module.io.trace_in <> outer.trace_sink_arbiter.get.module.io.out(index) } diff --git a/src/main/scala/trace/TraceSinkArbiter.scala b/src/main/scala/trace/TraceSinkArbiter.scala index 733dd351ae1..abbe41ec30e 100644 --- a/src/main/scala/trace/TraceSinkArbiter.scala +++ b/src/main/scala/trace/TraceSinkArbiter.scala @@ -13,7 +13,6 @@ import freechips.rocketchip.tile._ import freechips.rocketchip.regmapper.{RegField, RegFieldDesc} class TraceSinkArbiter(nSeq : Seq[Int], use_monitor: Boolean = false, monitor_name: String = "unknown")(implicit p: Parameters) extends LazyModule { - println(s"TraceSinkArbiter nSeq: $nSeq") override lazy val module = new TraceSinkArbiterModuleImp(this) class TraceSinkArbiterModuleImp(outer: TraceSinkArbiter) extends LazyModuleImp(outer) { val io = IO(new Bundle { @@ -30,7 +29,6 @@ class TraceSinkArbiter(nSeq : Seq[Int], use_monitor: Boolean = false, monitor_na if (use_monitor) { val monitor = Module(new TraceSinkMonitor(s"trace_monitor_$monitor_name.out")) - println(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 From 24cf6fa51f5d83ede84278610abb3e403e76d7fc Mon Sep 17 00:00:00 2001 From: Lux Date: Thu, 23 Jan 2025 18:49:41 -0800 Subject: [PATCH 17/22] ADD: refactor --- src/main/scala/tile/RocketTile.scala | 29 +- src/main/scala/trace/TacitEncoder.scala | 408 ++++++++++++++++++ src/main/scala/trace/TraceEncoder.scala | 406 +---------------- .../scala/trace/TraceEncoderController.scala | 24 +- src/main/scala/trace/TraceSink.scala | 2 +- src/main/scala/trace/TraceSinkAlways.scala | 3 +- src/main/scala/trace/TraceSinkArbiter.scala | 3 +- src/main/scala/trace/TraceSinkDMA.scala | 6 +- 8 files changed, 451 insertions(+), 430 deletions(-) create mode 100644 src/main/scala/trace/TacitEncoder.scala diff --git a/src/main/scala/tile/RocketTile.scala b/src/main/scala/tile/RocketTile.scala index 1662a24e4b4..074b17593c1 100644 --- a/src/main/scala/tile/RocketTile.scala +++ b/src/main/scala/tile/RocketTile.scala @@ -26,7 +26,7 @@ import freechips.rocketchip.subsystem.HierarchicalElementCrossingParamsLike import freechips.rocketchip.prci.{ClockSinkParameters, RationalCrossing, ClockCrossingType} import freechips.rocketchip.util.{Annotated, InOrderArbiter} import freechips.rocketchip.trace.{ - TraceEncoder, TraceEncoderParams, TraceSinkAlways, TraceSinkDMA, + TraceEncoderParams, TraceSinkAlways, TraceSinkDMA, TraceEncoderController, TraceSinkArbiter} import freechips.rocketchip.subsystem._ @@ -45,7 +45,7 @@ case class RocketTileParams( blockerCtrlAddr: Option[BigInt] = None, clockSinkParams: ClockSinkParameters = ClockSinkParameters(), boundaryBuffers: Option[RocketTileBoundaryBufferParams] = None, - ltrace: Option[TraceEncoderParams] = None + traceParams: Option[TraceEncoderParams] = None ) extends InstantiableTileParams[RocketTile] { require(icache.isDefined) require(dcache.isDefined) @@ -93,18 +93,23 @@ class RocketTile private( * controlling enable/disable of trace encoder * and selecting trace sink */ - val trace_encoder_controller = rocketParams.ltrace.map { t => + 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_sinks, traceSinkIds) = rocketParams.ltrace match { + 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 trace_sink_arbiter = rocketParams.ltrace.map { t => + val trace_sink_arbiter = rocketParams.traceParams.map { t => val arb = LazyModule(new TraceSinkArbiter(traceSinkIds, use_monitor = t.useArbiterMonitor, monitor_name = rocketParams.uniqueName)) arb } @@ -179,20 +184,18 @@ 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.ltrace.isDefined) { - val trace_encoder = Module(new TraceEncoder(outer.rocketParams.ltrace.get)) - - core.io.trace_core_ingress.get <> trace_encoder.io.in + if (outer.rocketParams.traceParams.isDefined) { + core.io.trace_core_ingress.get <> outer.trace_encoder.get.module.io.in outer.trace_encoder_controller.foreach { lm => - trace_encoder.io.control <> lm.module.io.control + outer.trace_encoder.get.module.io.control <> lm.module.io.control } outer.trace_sink_arbiter.foreach { lm => - lm.module.io.target := trace_encoder.io.control.target - lm.module.io.in <> trace_encoder.io.out + lm.module.io.target := outer.trace_encoder.get.module.io.control.target + lm.module.io.in <> outer.trace_encoder.get.module.io.out } - core.io.traceStall := outer.traceAuxSinkNode.bundle.stall || trace_encoder.io.stall + core.io.traceStall := outer.traceAuxSinkNode.bundle.stall || outer.trace_encoder.get.module.io.stall } else { core.io.traceStall := outer.traceAuxSinkNode.bundle.stall } diff --git a/src/main/scala/trace/TacitEncoder.scala b/src/main/scala/trace/TacitEncoder.scala new file mode 100644 index 00000000000..6d28ec0df44 --- /dev/null +++ b/src/main/scala/trace/TacitEncoder.scala @@ -0,0 +1,408 @@ +// 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 + +object FullHeaderType extends ChiselEnum { + val FTakenBranch = Value(0x0.U) // 000 + val FNotTakenBranch = Value(0x1.U) // 001 + val FUninfJump = Value(0x2.U) // 010 + val FInfJump = Value(0x3.U) // 011 + val FTrap = Value(0x4.U) // 100 + val FSync = Value(0x5.U) // 101 + val FValue = Value(0x6.U) // 110 + val FReserved = Value(0x7.U) // 111 +} + +object CompressedHeaderType extends ChiselEnum { + val CTB = Value(0x0.U) // 00, taken branch + val CNT = Value(0x1.U) // 01, not taken branch + val CNA = Value(0x2.U) // 10, not a compressed packet + val CIJ = Value(0x3.U) // 11, is a jump +} + +object TrapType extends ChiselEnum { + val TNone = Value(0x0.U) + val TException = Value(0x1.U) + val TInterrupt = Value(0x2.U) + val TReturn = Value(0x4.U) +} + +object HeaderByte { + def apply(header_type: FullHeaderType.Type, trap_type: TrapType.Type): UInt = { + Cat( + trap_type.asUInt, + header_type.asUInt, + CompressedHeaderType.CNA.asUInt + ) + } +} + +// Variable-length encoding helper module +class VarLenEncoder(val maxWidth: Int) extends Module { + val maxNumBytes = maxWidth/(8-1) + 1 + + val io = IO(new Bundle { + val input_value = Input(UInt(maxWidth.W)) + val input_valid = Input(Bool()) + val output_num_bytes = Output(UInt(log2Ceil(maxNumBytes).W)) + val output_bytes = Output(Vec(maxNumBytes, UInt(8.W))) + }) + + // 0-indexed MSB index + val msb_index = (maxWidth - 1).U - PriorityEncoder(Reverse(io.input_value)) + io.output_num_bytes := Mux(io.input_valid, (msb_index / 7.U) + 1.U, 0.U) + + for (i <- 0 until maxNumBytes) { + val is_last_byte = (i.U === (io.output_num_bytes - 1.U)) + io.output_bytes(i) := Mux(i.U < io.output_num_bytes, + io.input_value(min(i*7+6, maxWidth-1), i*7) | Mux(is_last_byte, 0x80.U, 0.U), + 0.U + ) + } +} + +// slice packets into bytes TODO: is this efficient? +class TracePacketizer(val coreParams: TraceCoreParams) extends Module { + def getMaxNumBytes(width: Int): Int = { width/(8-1) + 1 } + val addrMaxNumBytes = getMaxNumBytes(coreParams.iaddrWidth) + val timeMaxNumBytes = getMaxNumBytes(coreParams.xlen) + // println(s"addrMaxNumBytes: $addrMaxNumBytes, timeMaxNumBytes: $timeMaxNumBytes") + val metaDataWidth = 2 * log2Ceil(addrMaxNumBytes) + log2Ceil(timeMaxNumBytes) + 1 + val io = IO(new Bundle { + val target_addr = Flipped(Decoupled(Vec(addrMaxNumBytes, UInt(8.W)))) + val trap_addr = Flipped(Decoupled(Vec(addrMaxNumBytes, UInt(8.W)))) + val time = Flipped(Decoupled(Vec(timeMaxNumBytes, UInt(8.W)))) + val byte = Flipped(Decoupled(UInt(8.W))) + val metadata = Flipped(Decoupled(UInt(metaDataWidth.W))) + val out = Decoupled(UInt(8.W)) + }) + + val pIdle :: pComp :: pFull :: Nil = Enum(3) + val state = RegInit(pIdle) + + val trap_addr_num_bytes = Reg(UInt(log2Ceil(addrMaxNumBytes).W)) + val trap_addr_index = Reg(UInt(log2Ceil(addrMaxNumBytes).W)) + val target_addr_num_bytes = Reg(UInt(log2Ceil(addrMaxNumBytes).W)) + val target_addr_index = Reg(UInt(log2Ceil(addrMaxNumBytes).W)) + val time_num_bytes = Reg(UInt(log2Ceil(timeMaxNumBytes).W)) + val time_index = Reg(UInt(log2Ceil(timeMaxNumBytes).W)) + val header_num_bytes = Reg(UInt(1.W)) + val header_index = Reg(UInt(1.W)) + + val is_compressed = io.metadata.bits(0) + val trap_addr_metadata = io.metadata.bits(metaDataWidth-1, log2Ceil(timeMaxNumBytes)+log2Ceil(addrMaxNumBytes)+1) + val target_addr_metadata = io.metadata.bits(log2Ceil(timeMaxNumBytes)+log2Ceil(addrMaxNumBytes), log2Ceil(timeMaxNumBytes)+1) + val time_metadata = io.metadata.bits(log2Ceil(timeMaxNumBytes), 1) + + // default values + io.out.valid := false.B + io.metadata.ready := false.B + io.target_addr.ready := false.B + io.trap_addr.ready := false.B + io.time.ready := false.B + io.byte.ready := false.B + io.out.bits := 0.U + + def prep_next_state(): Unit = { + trap_addr_index := 0.U + trap_addr_num_bytes := Mux(io.metadata.fire, trap_addr_metadata, 0.U) + target_addr_index := 0.U + target_addr_num_bytes := Mux(io.metadata.fire, target_addr_metadata, 0.U) + time_index := 0.U + time_num_bytes := Mux(io.metadata.fire, time_metadata, 0.U) + header_index := 0.U + header_num_bytes := Mux(io.metadata.fire, ~is_compressed, 0.U) + state := Mux(io.metadata.fire, + Mux(is_compressed, pComp, pFull), + pIdle + ) + } + + switch (state) { + is (pIdle) { + io.metadata.ready := true.B + when (io.metadata.fire) { + trap_addr_num_bytes := trap_addr_metadata + trap_addr_index := 0.U + target_addr_num_bytes := target_addr_metadata + target_addr_index := 0.U + time_num_bytes := time_metadata + time_index := 0.U + header_num_bytes := ~is_compressed + header_index := 0.U + state := Mux(is_compressed, pComp, pFull) + } + } + is (pComp) { + // transmit a byte from byte buffer + io.byte.ready := io.out.ready + io.out.valid := io.byte.valid + io.out.bits := io.byte.bits + when (io.byte.fire) { + // metadata runs ahead by 1 cycle for performance optimization + io.metadata.ready := true.B + prep_next_state() + } + } + is (pFull) { + // header, addr, time + io.out.valid := true.B + when (header_num_bytes > 0.U && header_index < header_num_bytes) { + io.out.bits := io.byte.bits + io.out.valid := io.byte.valid + header_index := header_index + io.out.fire + } .elsewhen (trap_addr_num_bytes > 0.U && trap_addr_index < trap_addr_num_bytes) { + io.out.bits := io.trap_addr.bits(trap_addr_index) + io.out.valid := io.trap_addr.valid + trap_addr_index := trap_addr_index + io.out.fire + } .elsewhen (target_addr_num_bytes > 0.U && target_addr_index < target_addr_num_bytes) { + io.out.bits := io.target_addr.bits(target_addr_index) + io.out.valid := io.target_addr.valid + target_addr_index := target_addr_index + io.out.fire + } .elsewhen (time_num_bytes > 0.U && time_index < time_num_bytes) { + io.out.bits := io.time.bits(time_index) + io.out.valid := io.time.valid + time_index := time_index + io.out.fire + } .otherwise { + // FIXME: delay for 1 cycle + io.out.valid := false.B + // release buffers + io.byte.ready := true.B + // if we ever have a packet, we need to be ready to accept it + io.target_addr.ready := target_addr_num_bytes =/= 0.U + io.trap_addr.ready := trap_addr_num_bytes =/= 0.U + io.time.ready := time_num_bytes =/= 0.U + io.metadata.ready := true.B + prep_next_state() + } + } + } +} + +class TacitEncoder(override val coreParams: TraceCoreParams, val bufferDepth: Int)(implicit p: Parameters) + extends LazyTraceEncoder(coreParams)(p) { + override lazy val module = new TacitEncoderModule(this) +} + +class TacitEncoderModule(outer: TacitEncoder) extends LazyTraceEncoderModule(outer) { + + val MAX_DELTA_TIME_COMP = 0xCF // 63, 6 bits + + // when (io.stall) { + // printf("TraceEncoder stall detected\n") + // } + + // states + val sIdle :: sSync :: sData :: Nil = Enum(3) + val state = RegInit(sIdle) + val enabled = RegInit(false.B) + val stall = Wire(Bool()) + val prev_time = Reg(UInt(outer.coreParams.xlen.W)) + // pipeline of ingress data + val ingress_0 = RegInit(0.U.asTypeOf(new TraceCoreInterface(outer.coreParams))) + val ingress_1 = RegInit(0.U.asTypeOf(new TraceCoreInterface(outer.coreParams))) + + // shift every cycle, if not stalled + val pipeline_advance = Wire(Bool()) + pipeline_advance := !stall && io.in.group(0).iretire === 1.U + when (pipeline_advance) { + ingress_0 := io.in + ingress_1 := ingress_0 + } + + // encoders + val trap_addr_encoder = Module(new VarLenEncoder(outer.coreParams.iaddrWidth)) + val target_addr_encoder = Module(new VarLenEncoder(outer.coreParams.iaddrWidth)) + val time_encoder = Module(new VarLenEncoder(outer.coreParams.xlen)) + val metadataWidth = log2Ceil(trap_addr_encoder.maxNumBytes) + log2Ceil(target_addr_encoder.maxNumBytes) + log2Ceil(time_encoder.maxNumBytes) + 1 + + // queue buffers + val trap_addr_buffer = Module(new Queue(Vec(trap_addr_encoder.maxNumBytes, UInt(8.W)), outer.bufferDepth)) + val target_addr_buffer = Module(new Queue(Vec(target_addr_encoder.maxNumBytes, UInt(8.W)), outer.bufferDepth)) + val time_buffer = Module(new Queue(Vec(time_encoder.maxNumBytes, UInt(8.W)), outer.bufferDepth)) + val byte_buffer = Module(new Queue(UInt(8.W), outer.bufferDepth)) // buffer compressed packet or full header + val metadata_buffer = Module(new Queue(UInt(metadataWidth.W), outer.bufferDepth)) + // intermediate varlen encoder signals + val full_trap_addr = Wire(Vec(trap_addr_encoder.maxNumBytes, UInt(8.W))) + val trap_addr_num_bytes = Wire(UInt(log2Ceil(trap_addr_encoder.maxNumBytes).W)) + val full_target_addr = Wire(Vec(target_addr_encoder.maxNumBytes, UInt(8.W))) + val target_addr_num_bytes = Wire(UInt(log2Ceil(target_addr_encoder.maxNumBytes).W)) + val full_time = Wire(Vec(time_encoder.maxNumBytes, UInt(8.W))) + val time_num_bytes = Wire(UInt(log2Ceil(time_encoder.maxNumBytes).W)) + full_trap_addr := trap_addr_encoder.io.output_bytes + trap_addr_num_bytes := trap_addr_encoder.io.output_num_bytes + full_target_addr := target_addr_encoder.io.output_bytes + target_addr_num_bytes := target_addr_encoder.io.output_num_bytes + full_time := time_encoder.io.output_bytes + time_num_bytes := time_encoder.io.output_num_bytes + + // intermediate packet signals + val is_compressed = Wire(Bool()) + val delta_time = ingress_1.time - prev_time + val packet_valid = Wire(Bool()) + val header_byte = Wire(UInt(8.W)) // full header + val comp_packet = Wire(UInt(8.W)) // compressed packet + val comp_header = Wire(UInt(CompressedHeaderType.getWidth.W)) // compressed header + comp_packet := Cat(delta_time(5, 0), comp_header) + + // packetization of buffered message + val trace_packetizer = Module(new TracePacketizer(outer.coreParams)) + trace_packetizer.io.target_addr <> target_addr_buffer.io.deq + trace_packetizer.io.trap_addr <> trap_addr_buffer.io.deq + trace_packetizer.io.time <> time_buffer.io.deq + trace_packetizer.io.byte <> byte_buffer.io.deq + trace_packetizer.io.metadata <> metadata_buffer.io.deq + trace_packetizer.io.out <> io.out + + // intermediate encoder control signals + val encode_trap_addr_valid = Wire(Bool()) + val encode_target_addr_valid = Wire(Bool()) + + // metadata buffering + val metadata = Cat(trap_addr_num_bytes, target_addr_num_bytes, time_num_bytes, is_compressed) + metadata_buffer.io.enq.bits := metadata + metadata_buffer.io.enq.valid := packet_valid + // buffering compressed packet or full header depending on is_compressed + byte_buffer.io.enq.bits := Mux(is_compressed, comp_packet, header_byte) + byte_buffer.io.enq.valid := packet_valid + // trap address buffering + trap_addr_buffer.io.enq.bits := full_trap_addr + trap_addr_buffer.io.enq.valid := !is_compressed && packet_valid && encode_trap_addr_valid + // target address buffering + target_addr_buffer.io.enq.bits := full_target_addr + target_addr_buffer.io.enq.valid := !is_compressed && packet_valid && encode_target_addr_valid + // time buffering + time_buffer.io.enq.bits := full_time + time_buffer.io.enq.valid := !is_compressed && packet_valid + + // stall if any buffer is full + stall := !target_addr_buffer.io.enq.ready || !time_buffer.io.enq.ready || !byte_buffer.io.enq.ready + io.stall := stall + + val sent = RegInit(false.B) + // reset takes priority over enqueue + when (pipeline_advance) { + sent := false.B + } .elsewhen (byte_buffer.io.enq.fire) { + sent := true.B + } + + trap_addr_encoder.io.input_valid := encode_trap_addr_valid && !is_compressed && packet_valid + target_addr_encoder.io.input_valid := encode_target_addr_valid && !is_compressed && packet_valid + time_encoder.io.input_valid := !is_compressed && packet_valid + + // default values + trap_addr_encoder.io.input_value := 0.U + target_addr_encoder.io.input_value := 0.U + time_encoder.io.input_value := 0.U + is_compressed := false.B + packet_valid := false.B + encode_target_addr_valid := false.B + encode_trap_addr_valid := false.B + comp_header := CompressedHeaderType.CNA.asUInt + header_byte := HeaderByte(FullHeaderType.FReserved, TrapType.TNone) + // state machine + switch (state) { + is (sIdle) { + when (io.control.enable) { state := sSync } + } + is (sSync) { + header_byte := HeaderByte(FullHeaderType.FSync, TrapType.TNone) + time_encoder.io.input_value := ingress_0.time + prev_time := ingress_0.time + target_addr_encoder.io.input_value := ingress_0.group(0).iaddr >> 1.U // last bit is always 0 + encode_target_addr_valid := true.B + is_compressed := false.B + packet_valid := !sent + // state transition: wait for message to go in + state := Mux(pipeline_advance && (sent || byte_buffer.io.enq.fire), Mux(io.control.enable, sData, sIdle), sSync) + } + is (sData) { + when (!io.control.enable) { + state := sSync + } .otherwise { + switch (ingress_1.group(0).itype) { + is (TraceItype.ITNothing) { + packet_valid := false.B + } + is (TraceItype.ITBrTaken) { + header_byte := HeaderByte(FullHeaderType.FTakenBranch, TrapType.TNone) + comp_header := CompressedHeaderType.CTB.asUInt + time_encoder.io.input_value := delta_time + prev_time := ingress_1.time + is_compressed := delta_time <= MAX_DELTA_TIME_COMP.U + packet_valid := !sent + } + is (TraceItype.ITBrNTaken) { + header_byte := HeaderByte(FullHeaderType.FNotTakenBranch, TrapType.TNone) + comp_header := CompressedHeaderType.CNT.asUInt + time_encoder.io.input_value := delta_time + prev_time := ingress_1.time + is_compressed := delta_time <= MAX_DELTA_TIME_COMP.U + packet_valid := !sent + } + is (TraceItype.ITInJump) { + header_byte := HeaderByte(FullHeaderType.FInfJump, TrapType.TNone) + comp_header := CompressedHeaderType.CIJ.asUInt + time_encoder.io.input_value := delta_time + prev_time := ingress_1.time + is_compressed := delta_time <= MAX_DELTA_TIME_COMP.U + packet_valid := !sent + } + is (TraceItype.ITUnJump) { + header_byte := HeaderByte(FullHeaderType.FUninfJump, TrapType.TNone) + time_encoder.io.input_value := delta_time + prev_time := ingress_1.time + target_addr_encoder.io.input_value := (ingress_1.group(0).iaddr ^ ingress_0.group(0).iaddr) >> 1.U + encode_target_addr_valid := true.B + is_compressed := false.B + packet_valid := !sent + } + is (TraceItype.ITException) { + header_byte := HeaderByte(FullHeaderType.FTrap, TrapType.TException) + comp_header := CompressedHeaderType.CNA.asUInt + time_encoder.io.input_value := delta_time + prev_time := ingress_1.time + target_addr_encoder.io.input_value := (ingress_1.group(0).iaddr ^ ingress_0.group(0).iaddr) >> 1.U + encode_target_addr_valid := true.B + trap_addr_encoder.io.input_value := ingress_1.group(0).iaddr + encode_trap_addr_valid := true.B + is_compressed := false.B + packet_valid := !sent + } + is (TraceItype.ITInterrupt) { + header_byte := HeaderByte(FullHeaderType.FTrap, TrapType.TInterrupt) + comp_header := CompressedHeaderType.CNA.asUInt + time_encoder.io.input_value := delta_time + prev_time := ingress_1.time + target_addr_encoder.io.input_value := (ingress_1.group(0).iaddr ^ ingress_0.group(0).iaddr) >> 1.U + encode_target_addr_valid := true.B + trap_addr_encoder.io.input_value := ingress_1.group(0).iaddr + encode_trap_addr_valid := true.B + is_compressed := false.B + packet_valid := !sent + } + is (TraceItype.ITReturn) { + header_byte := HeaderByte(FullHeaderType.FTrap, TrapType.TReturn) + comp_header := CompressedHeaderType.CNA.asUInt + time_encoder.io.input_value := delta_time + prev_time := ingress_1.time + target_addr_encoder.io.input_value := (ingress_1.group(0).iaddr ^ ingress_0.group(0).iaddr) >> 1.U + encode_target_addr_valid := true.B + trap_addr_encoder.io.input_value := ingress_1.group(0).iaddr + encode_trap_addr_valid := true.B + is_compressed := false.B + packet_valid := !sent + } + } + } + } + } +} diff --git a/src/main/scala/trace/TraceEncoder.scala b/src/main/scala/trace/TraceEncoder.scala index ee55162f4d5..361a94008d7 100644 --- a/src/main/scala/trace/TraceEncoder.scala +++ b/src/main/scala/trace/TraceEncoder.scala @@ -8,416 +8,26 @@ import chisel3.util._ import scala.math.min import org.chipsalliance.cde.config.Parameters +import freechips.rocketchip.diplomacy._ case class TraceEncoderParams( - coreParams: TraceCoreParams, - bufferDepth: Int, 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)] ) -object FullHeaderType extends ChiselEnum { - val FTakenBranch = Value(0x0.U) // 000 - val FNotTakenBranch = Value(0x1.U) // 001 - val FUninfJump = Value(0x2.U) // 010 - val FInfJump = Value(0x3.U) // 011 - val FTrap = Value(0x4.U) // 100 - val FSync = Value(0x5.U) // 101 - val FValue = Value(0x6.U) // 110 - val FReserved = Value(0x7.U) // 111 +class LazyTraceEncoder(val coreParams: TraceCoreParams)(implicit p: Parameters) extends LazyModule { + override lazy val module = new LazyTraceEncoderModule(this) + override def shouldBeInlined = false } -object CompressedHeaderType extends ChiselEnum { - val CTB = Value(0x0.U) // 00, taken branch - val CNT = Value(0x1.U) // 01, not taken branch - val CNA = Value(0x2.U) // 10, not a compressed packet - val CIJ = Value(0x3.U) // 11, is a jump -} - -object TraceSinkTarget extends ChiselEnum { - val STPrint = Value(0x0.U) // 00, RTL print - val STDMA = Value(0x1.U) // 01, DMA -} - -object TrapType extends ChiselEnum { - val TNone = Value(0x0.U) - val TException = Value(0x1.U) - val TInterrupt = Value(0x2.U) - val TReturn = Value(0x4.U) -} - -object HeaderByte { - def apply(header_type: FullHeaderType.Type, trap_type: TrapType.Type): UInt = { - Cat( - trap_type.asUInt, - header_type.asUInt, - CompressedHeaderType.CNA.asUInt - ) - } -} - -// Variable-length encoding helper module -class VarLenEncoder(val maxWidth: Int) extends Module { - val maxNumBytes = maxWidth/(8-1) + 1 - - val io = IO(new Bundle { - val input_value = Input(UInt(maxWidth.W)) - val input_valid = Input(Bool()) - val output_num_bytes = Output(UInt(log2Ceil(maxNumBytes).W)) - val output_bytes = Output(Vec(maxNumBytes, UInt(8.W))) - }) - - // 0-indexed MSB index - val msb_index = (maxWidth - 1).U - PriorityEncoder(Reverse(io.input_value)) - io.output_num_bytes := Mux(io.input_valid, (msb_index / 7.U) + 1.U, 0.U) - - for (i <- 0 until maxNumBytes) { - val is_last_byte = (i.U === (io.output_num_bytes - 1.U)) - io.output_bytes(i) := Mux(i.U < io.output_num_bytes, - io.input_value(min(i*7+6, maxWidth-1), i*7) | Mux(is_last_byte, 0x80.U, 0.U), - 0.U - ) - } -} - -// slice packets into bytes TODO: is this efficient? -class TracePacketizer(val params: TraceEncoderParams) extends Module { - def getMaxNumBytes(width: Int): Int = { width/(8-1) + 1 } - val addrMaxNumBytes = getMaxNumBytes(params.coreParams.iaddrWidth) - val timeMaxNumBytes = getMaxNumBytes(params.coreParams.xlen) - // println(s"addrMaxNumBytes: $addrMaxNumBytes, timeMaxNumBytes: $timeMaxNumBytes") - val metaDataWidth = 2 * log2Ceil(addrMaxNumBytes) + log2Ceil(timeMaxNumBytes) + 1 - val io = IO(new Bundle { - val target_addr = Flipped(Decoupled(Vec(addrMaxNumBytes, UInt(8.W)))) - val trap_addr = Flipped(Decoupled(Vec(addrMaxNumBytes, UInt(8.W)))) - val time = Flipped(Decoupled(Vec(timeMaxNumBytes, UInt(8.W)))) - val byte = Flipped(Decoupled(UInt(8.W))) - val metadata = Flipped(Decoupled(UInt(metaDataWidth.W))) - val out = Decoupled(UInt(8.W)) - }) - - val pIdle :: pComp :: pFull :: Nil = Enum(3) - val state = RegInit(pIdle) - - val trap_addr_num_bytes = Reg(UInt(log2Ceil(addrMaxNumBytes).W)) - val trap_addr_index = Reg(UInt(log2Ceil(addrMaxNumBytes).W)) - val target_addr_num_bytes = Reg(UInt(log2Ceil(addrMaxNumBytes).W)) - val target_addr_index = Reg(UInt(log2Ceil(addrMaxNumBytes).W)) - val time_num_bytes = Reg(UInt(log2Ceil(timeMaxNumBytes).W)) - val time_index = Reg(UInt(log2Ceil(timeMaxNumBytes).W)) - val header_num_bytes = Reg(UInt(1.W)) - val header_index = Reg(UInt(1.W)) - - val is_compressed = io.metadata.bits(0) - val trap_addr_metadata = io.metadata.bits(metaDataWidth-1, log2Ceil(timeMaxNumBytes)+log2Ceil(addrMaxNumBytes)+1) - val target_addr_metadata = io.metadata.bits(log2Ceil(timeMaxNumBytes)+log2Ceil(addrMaxNumBytes), log2Ceil(timeMaxNumBytes)+1) - val time_metadata = io.metadata.bits(log2Ceil(timeMaxNumBytes), 1) - - // default values - io.out.valid := false.B - io.metadata.ready := false.B - io.target_addr.ready := false.B - io.trap_addr.ready := false.B - io.time.ready := false.B - io.byte.ready := false.B - io.out.bits := 0.U - - def prep_next_state(): Unit = { - trap_addr_index := 0.U - trap_addr_num_bytes := Mux(io.metadata.fire, trap_addr_metadata, 0.U) - target_addr_index := 0.U - target_addr_num_bytes := Mux(io.metadata.fire, target_addr_metadata, 0.U) - time_index := 0.U - time_num_bytes := Mux(io.metadata.fire, time_metadata, 0.U) - header_index := 0.U - header_num_bytes := Mux(io.metadata.fire, ~is_compressed, 0.U) - state := Mux(io.metadata.fire, - Mux(is_compressed, pComp, pFull), - pIdle - ) - } - - switch (state) { - is (pIdle) { - io.metadata.ready := true.B - when (io.metadata.fire) { - trap_addr_num_bytes := trap_addr_metadata - trap_addr_index := 0.U - target_addr_num_bytes := target_addr_metadata - target_addr_index := 0.U - time_num_bytes := time_metadata - time_index := 0.U - header_num_bytes := ~is_compressed - header_index := 0.U - state := Mux(is_compressed, pComp, pFull) - } - } - is (pComp) { - // transmit a byte from byte buffer - io.byte.ready := io.out.ready - io.out.valid := io.byte.valid - io.out.bits := io.byte.bits - when (io.byte.fire) { - // metadata runs ahead by 1 cycle for performance optimization - io.metadata.ready := true.B - prep_next_state() - } - } - is (pFull) { - // header, addr, time - io.out.valid := true.B - when (header_num_bytes > 0.U && header_index < header_num_bytes) { - io.out.bits := io.byte.bits - io.out.valid := io.byte.valid - header_index := header_index + io.out.fire - } .elsewhen (trap_addr_num_bytes > 0.U && trap_addr_index < trap_addr_num_bytes) { - io.out.bits := io.trap_addr.bits(trap_addr_index) - io.out.valid := io.trap_addr.valid - trap_addr_index := trap_addr_index + io.out.fire - } .elsewhen (target_addr_num_bytes > 0.U && target_addr_index < target_addr_num_bytes) { - io.out.bits := io.target_addr.bits(target_addr_index) - io.out.valid := io.target_addr.valid - target_addr_index := target_addr_index + io.out.fire - } .elsewhen (time_num_bytes > 0.U && time_index < time_num_bytes) { - io.out.bits := io.time.bits(time_index) - io.out.valid := io.time.valid - time_index := time_index + io.out.fire - } .otherwise { - // FIXME: delay for 1 cycle - io.out.valid := false.B - // release buffers - io.byte.ready := true.B - // if we ever have a packet, we need to be ready to accept it - io.target_addr.ready := target_addr_num_bytes =/= 0.U - io.trap_addr.ready := trap_addr_num_bytes =/= 0.U - io.time.ready := time_num_bytes =/= 0.U - io.metadata.ready := true.B - prep_next_state() - } - } - } -} - -class TraceEncoder(val params: TraceEncoderParams) extends Module { +class LazyTraceEncoderModule(outer: LazyTraceEncoder) extends LazyModuleImp(outer) { val io = IO(new Bundle { val control = Input(new TraceEncoderControlInterface()) - val in = Input(new TraceCoreInterface(params.coreParams)) + val in = Input(new TraceCoreInterface(outer.coreParams)) val stall = Output(Bool()) val out = Decoupled(UInt(8.W)) }) - - val MAX_DELTA_TIME_COMP = 0xCF // 63, 6 bits - - when (io.stall) { - printf("TraceEncoder stall detected\n") - } - - // states - val sIdle :: sSync :: sData :: Nil = Enum(3) - val state = RegInit(sIdle) - val enabled = RegInit(false.B) - val stall = Wire(Bool()) - val prev_time = Reg(UInt(params.coreParams.xlen.W)) - // pipeline of ingress data - val ingress_0 = RegInit(0.U.asTypeOf(new TraceCoreInterface(params.coreParams))) - val ingress_1 = RegInit(0.U.asTypeOf(new TraceCoreInterface(params.coreParams))) - - // shift every cycle, if not stalled - val pipeline_advance = Wire(Bool()) - pipeline_advance := !stall && io.in.group(0).iretire === 1.U - when (pipeline_advance) { - ingress_0 := io.in - ingress_1 := ingress_0 - } - - // encoders - val trap_addr_encoder = Module(new VarLenEncoder(params.coreParams.iaddrWidth)) - val target_addr_encoder = Module(new VarLenEncoder(params.coreParams.iaddrWidth)) - val time_encoder = Module(new VarLenEncoder(params.coreParams.xlen)) - val metadataWidth = log2Ceil(trap_addr_encoder.maxNumBytes) + log2Ceil(target_addr_encoder.maxNumBytes) + log2Ceil(time_encoder.maxNumBytes) + 1 - - // queue buffers - val trap_addr_buffer = Module(new Queue(Vec(trap_addr_encoder.maxNumBytes, UInt(8.W)), params.bufferDepth)) - val target_addr_buffer = Module(new Queue(Vec(target_addr_encoder.maxNumBytes, UInt(8.W)), params.bufferDepth)) - val time_buffer = Module(new Queue(Vec(time_encoder.maxNumBytes, UInt(8.W)), params.bufferDepth)) - val byte_buffer = Module(new Queue(UInt(8.W), params.bufferDepth)) // buffer compressed packet or full header - val metadata_buffer = Module(new Queue(UInt(metadataWidth.W), params.bufferDepth)) - // intermediate varlen encoder signals - val full_trap_addr = Wire(Vec(trap_addr_encoder.maxNumBytes, UInt(8.W))) - val trap_addr_num_bytes = Wire(UInt(log2Ceil(trap_addr_encoder.maxNumBytes).W)) - val full_target_addr = Wire(Vec(target_addr_encoder.maxNumBytes, UInt(8.W))) - val target_addr_num_bytes = Wire(UInt(log2Ceil(target_addr_encoder.maxNumBytes).W)) - val full_time = Wire(Vec(time_encoder.maxNumBytes, UInt(8.W))) - val time_num_bytes = Wire(UInt(log2Ceil(time_encoder.maxNumBytes).W)) - full_trap_addr := trap_addr_encoder.io.output_bytes - trap_addr_num_bytes := trap_addr_encoder.io.output_num_bytes - full_target_addr := target_addr_encoder.io.output_bytes - target_addr_num_bytes := target_addr_encoder.io.output_num_bytes - full_time := time_encoder.io.output_bytes - time_num_bytes := time_encoder.io.output_num_bytes - - // intermediate packet signals - val is_compressed = Wire(Bool()) - val delta_time = ingress_1.time - prev_time - val packet_valid = Wire(Bool()) - val header_byte = Wire(UInt(8.W)) // full header - val comp_packet = Wire(UInt(8.W)) // compressed packet - val comp_header = Wire(UInt(CompressedHeaderType.getWidth.W)) // compressed header - comp_packet := Cat(delta_time(5, 0), comp_header) - - // packetization of buffered message - val trace_packetizer = Module(new TracePacketizer(params)) - trace_packetizer.io.target_addr <> target_addr_buffer.io.deq - trace_packetizer.io.trap_addr <> trap_addr_buffer.io.deq - trace_packetizer.io.time <> time_buffer.io.deq - trace_packetizer.io.byte <> byte_buffer.io.deq - trace_packetizer.io.metadata <> metadata_buffer.io.deq - trace_packetizer.io.out <> io.out - - // intermediate encoder control signals - val encode_trap_addr_valid = Wire(Bool()) - val encode_target_addr_valid = Wire(Bool()) - - // metadata buffering - val metadata = Cat(trap_addr_num_bytes, target_addr_num_bytes, time_num_bytes, is_compressed) - metadata_buffer.io.enq.bits := metadata - metadata_buffer.io.enq.valid := packet_valid - // buffering compressed packet or full header depending on is_compressed - byte_buffer.io.enq.bits := Mux(is_compressed, comp_packet, header_byte) - byte_buffer.io.enq.valid := packet_valid - // trap address buffering - trap_addr_buffer.io.enq.bits := full_trap_addr - trap_addr_buffer.io.enq.valid := !is_compressed && packet_valid && encode_trap_addr_valid - // target address buffering - target_addr_buffer.io.enq.bits := full_target_addr - target_addr_buffer.io.enq.valid := !is_compressed && packet_valid && encode_target_addr_valid - // time buffering - time_buffer.io.enq.bits := full_time - time_buffer.io.enq.valid := !is_compressed && packet_valid - - // stall if any buffer is full - stall := !target_addr_buffer.io.enq.ready || !time_buffer.io.enq.ready || !byte_buffer.io.enq.ready - io.stall := stall - - val sent = RegInit(false.B) - // reset takes priority over enqueue - when (pipeline_advance) { - sent := false.B - } .elsewhen (byte_buffer.io.enq.fire) { - sent := true.B - } - - trap_addr_encoder.io.input_valid := encode_trap_addr_valid && !is_compressed && packet_valid - target_addr_encoder.io.input_valid := encode_target_addr_valid && !is_compressed && packet_valid - time_encoder.io.input_valid := !is_compressed && packet_valid - - // default values - trap_addr_encoder.io.input_value := 0.U - target_addr_encoder.io.input_value := 0.U - time_encoder.io.input_value := 0.U - is_compressed := false.B - packet_valid := false.B - encode_target_addr_valid := false.B - encode_trap_addr_valid := false.B - comp_header := CompressedHeaderType.CNA.asUInt - header_byte := HeaderByte(FullHeaderType.FReserved, TrapType.TNone) - // state machine - switch (state) { - is (sIdle) { - when (io.control.enable) { state := sSync } - } - is (sSync) { - header_byte := HeaderByte(FullHeaderType.FSync, TrapType.TNone) - time_encoder.io.input_value := ingress_0.time - prev_time := ingress_0.time - target_addr_encoder.io.input_value := ingress_0.group(0).iaddr >> 1.U // last bit is always 0 - encode_target_addr_valid := true.B - is_compressed := false.B - packet_valid := !sent - // state transition: wait for message to go in - state := Mux(pipeline_advance && (sent || byte_buffer.io.enq.fire), Mux(io.control.enable, sData, sIdle), sSync) - } - is (sData) { - when (!io.control.enable) { - state := sSync - } .otherwise { - switch (ingress_1.group(0).itype) { - is (TraceItype.ITNothing) { - packet_valid := false.B - } - is (TraceItype.ITBrTaken) { - header_byte := HeaderByte(FullHeaderType.FTakenBranch, TrapType.TNone) - comp_header := CompressedHeaderType.CTB.asUInt - time_encoder.io.input_value := delta_time - prev_time := ingress_1.time - is_compressed := delta_time <= MAX_DELTA_TIME_COMP.U - packet_valid := !sent - } - is (TraceItype.ITBrNTaken) { - header_byte := HeaderByte(FullHeaderType.FNotTakenBranch, TrapType.TNone) - comp_header := CompressedHeaderType.CNT.asUInt - time_encoder.io.input_value := delta_time - prev_time := ingress_1.time - is_compressed := delta_time <= MAX_DELTA_TIME_COMP.U - packet_valid := !sent - } - is (TraceItype.ITInJump) { - header_byte := HeaderByte(FullHeaderType.FInfJump, TrapType.TNone) - comp_header := CompressedHeaderType.CIJ.asUInt - time_encoder.io.input_value := delta_time - prev_time := ingress_1.time - is_compressed := delta_time <= MAX_DELTA_TIME_COMP.U - packet_valid := !sent - } - is (TraceItype.ITUnJump) { - header_byte := HeaderByte(FullHeaderType.FUninfJump, TrapType.TNone) - time_encoder.io.input_value := delta_time - prev_time := ingress_1.time - target_addr_encoder.io.input_value := (ingress_1.group(0).iaddr ^ ingress_0.group(0).iaddr) >> 1.U - encode_target_addr_valid := true.B - is_compressed := false.B - packet_valid := !sent - } - is (TraceItype.ITException) { - header_byte := HeaderByte(FullHeaderType.FTrap, TrapType.TException) - comp_header := CompressedHeaderType.CNA.asUInt - time_encoder.io.input_value := delta_time - prev_time := ingress_1.time - target_addr_encoder.io.input_value := (ingress_1.group(0).iaddr ^ ingress_0.group(0).iaddr) >> 1.U - encode_target_addr_valid := true.B - trap_addr_encoder.io.input_value := ingress_1.group(0).iaddr - encode_trap_addr_valid := true.B - is_compressed := false.B - packet_valid := !sent - } - is (TraceItype.ITInterrupt) { - header_byte := HeaderByte(FullHeaderType.FTrap, TrapType.TInterrupt) - comp_header := CompressedHeaderType.CNA.asUInt - time_encoder.io.input_value := delta_time - prev_time := ingress_1.time - target_addr_encoder.io.input_value := (ingress_1.group(0).iaddr ^ ingress_0.group(0).iaddr) >> 1.U - encode_target_addr_valid := true.B - trap_addr_encoder.io.input_value := ingress_1.group(0).iaddr - encode_trap_addr_valid := true.B - is_compressed := false.B - packet_valid := !sent - } - is (TraceItype.ITReturn) { - header_byte := HeaderByte(FullHeaderType.FTrap, TrapType.TReturn) - comp_header := CompressedHeaderType.CNA.asUInt - time_encoder.io.input_value := delta_time - prev_time := ingress_1.time - target_addr_encoder.io.input_value := (ingress_1.group(0).iaddr ^ ingress_0.group(0).iaddr) >> 1.U - encode_target_addr_valid := true.B - trap_addr_encoder.io.input_value := ingress_1.group(0).iaddr - encode_trap_addr_valid := true.B - is_compressed := false.B - packet_valid := !sent - } - } - } - } - } -} +} \ No newline at end of file diff --git a/src/main/scala/trace/TraceEncoderController.scala b/src/main/scala/trace/TraceEncoderController.scala index 1bdd46c0087..2d94bf696a5 100644 --- a/src/main/scala/trace/TraceEncoderController.scala +++ b/src/main/scala/trace/TraceEncoderController.scala @@ -12,9 +12,13 @@ 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.getWidth.W) + val target = UInt(TraceSinkTarget.width.W) val hpmcounter_enable = UInt(32.W) val hpmcounter_report_interval = UInt(32.W) } @@ -39,7 +43,9 @@ class TraceEncoderController(addr: BigInt, beatBytes: Int)(implicit p: Parameter val active = control_reg_bits(0) io.control.enable := enable - val trace_sink_target = RegInit(TraceSinkTarget.STPrint.asUInt) + 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)) @@ -52,8 +58,6 @@ class TraceEncoderController(addr: BigInt, beatBytes: Int)(implicit p: Parameter control_reg_write_valid := valid when (control_reg_write_valid) { control_reg_bits := bits - printf("Writing to trace encoder control reg from %x to %x\n", - control_reg_bits, bits) } true.B } @@ -69,16 +73,12 @@ class TraceEncoderController(addr: BigInt, beatBytes: Int)(implicit p: Parameter 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")) - ), - 0x08 -> Seq( - RegField(32, trace_hpmcounter_enable, - RegFieldDesc("hpmcounter_enable", "Trace hpmcounter enable")) - ), - 0x0C -> Seq( - RegField(32, trace_hpmcounter_report_interval, - RegFieldDesc("hpmcounter_report_interval", "Trace hpmcounter report interval")) ) ):_* ) diff --git a/src/main/scala/trace/TraceSink.scala b/src/main/scala/trace/TraceSink.scala index 9d6b5fcf525..ff52e4af4be 100644 --- a/src/main/scala/trace/TraceSink.scala +++ b/src/main/scala/trace/TraceSink.scala @@ -4,7 +4,7 @@ import chisel3._ import chisel3.util._ import freechips.rocketchip.tilelink._ import freechips.rocketchip.diplomacy._ -import org.chipsalliance.cde.config.{Parameters, Field, Config} +import org.chipsalliance.cde.config.Parameters import freechips.rocketchip.prci._ import freechips.rocketchip.subsystem._ diff --git a/src/main/scala/trace/TraceSinkAlways.scala b/src/main/scala/trace/TraceSinkAlways.scala index c22e762a6a5..af840460d7c 100644 --- a/src/main/scala/trace/TraceSinkAlways.scala +++ b/src/main/scala/trace/TraceSinkAlways.scala @@ -20,7 +20,8 @@ class WithTraceSinkAlways(targetId: Int = 0) extends Config((site, here, up) => case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map { case tp: RocketTileAttachParams => { tp.copy(tileParams = tp.tileParams.copy( - ltrace = Some(tp.tileParams.ltrace.get.copy(buildSinks = tp.tileParams.ltrace.get.buildSinks :+ (p => (LazyModule(new TraceSinkAlways()(p)), targetId))))) + traceParams = Some(tp.tileParams.traceParams.get.copy(buildSinks = + tp.tileParams.traceParams.get.buildSinks :+ (p => (LazyModule(new TraceSinkAlways()(p)), targetId))))) ) } case other => other diff --git a/src/main/scala/trace/TraceSinkArbiter.scala b/src/main/scala/trace/TraceSinkArbiter.scala index abbe41ec30e..aaa3d5f33bc 100644 --- a/src/main/scala/trace/TraceSinkArbiter.scala +++ b/src/main/scala/trace/TraceSinkArbiter.scala @@ -14,9 +14,10 @@ import freechips.rocketchip.regmapper.{RegField, RegFieldDesc} class TraceSinkArbiter(nSeq : Seq[Int], use_monitor: Boolean = false, monitor_name: String = "unknown")(implicit p: Parameters) extends LazyModule { override lazy val module = new TraceSinkArbiterModuleImp(this) + override def shouldBeInlined = false class TraceSinkArbiterModuleImp(outer: TraceSinkArbiter) extends LazyModuleImp(outer) { val io = IO(new Bundle { - val target = Input(UInt(TraceSinkTarget.getWidth.W)) + val target = Input(UInt(TraceSinkTarget.width.W)) val in = Flipped(Decoupled(UInt(8.W))) val out = Vec(nSeq.size, Decoupled(UInt(8.W))) }) diff --git a/src/main/scala/trace/TraceSinkDMA.scala b/src/main/scala/trace/TraceSinkDMA.scala index 6a34c01ece2..da44766a128 100644 --- a/src/main/scala/trace/TraceSinkDMA.scala +++ b/src/main/scala/trace/TraceSinkDMA.scala @@ -105,8 +105,6 @@ class TraceSinkDMA(params: TraceSinkDMAParams)(implicit p: Parameters) extends L dma_addr_write_valid := valid && mstate === mIdle when (dma_addr_write_valid) { dma_start_addr := bits - printf("Writing to trace sink DMA reg from %x to %x\n", - dma_start_addr, bits) } true.B } @@ -143,8 +141,8 @@ class WithTraceSinkDMA(targetId: Int = 1) extends Config((site, here, up) => { // redefine tile level constants val xBytes = tp.tileParams.core.xLen / 8 tp.copy(tileParams = tp.tileParams.copy( - ltrace = Some(tp.tileParams.ltrace.get.copy(buildSinks = - tp.tileParams.ltrace.get.buildSinks :+ (p => + traceParams = Some(tp.tileParams.traceParams.get.copy(buildSinks = + tp.tileParams.traceParams.get.buildSinks :+ (p => (LazyModule(new TraceSinkDMA(TraceSinkDMAParams( regNodeBaseAddr = 0x3010000 + tp.tileParams.tileId * 0x1000, beatBytes = xBytes From f294695c4ab4234cf201d772d5bfea9cb14e59d3 Mon Sep 17 00:00:00 2001 From: Lux Date: Fri, 24 Jan 2025 12:06:10 -0800 Subject: [PATCH 18/22] FIX: VCS->NOT SYN --- src/main/resources/vsrc/TraceSinkMonitor.v | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/vsrc/TraceSinkMonitor.v b/src/main/resources/vsrc/TraceSinkMonitor.v index f2f72ce7f21..a0de8903bd2 100644 --- a/src/main/resources/vsrc/TraceSinkMonitor.v +++ b/src/main/resources/vsrc/TraceSinkMonitor.v @@ -9,7 +9,7 @@ module TraceSinkMonitor input[7:0] in_byte ); -`ifdef VCS +`ifndef SYNTHESIS integer file; From 96f98509e27b326054729251543426fb9416053d Mon Sep 17 00:00:00 2001 From: Lux Date: Mon, 27 Jan 2025 16:45:32 -0800 Subject: [PATCH 19/22] RM: non-standard components --- src/main/scala/tile/RocketTile.scala | 6 +- src/main/scala/trace/TacitEncoder.scala | 408 -------------------- src/main/scala/trace/TraceSinkAlways.scala | 29 -- src/main/scala/trace/TraceSinkDMA.scala | 170 -------- src/main/scala/trace/TraceSinkMonitor.scala | 2 +- 5 files changed, 3 insertions(+), 612 deletions(-) delete mode 100644 src/main/scala/trace/TacitEncoder.scala delete mode 100644 src/main/scala/trace/TraceSinkAlways.scala delete mode 100644 src/main/scala/trace/TraceSinkDMA.scala diff --git a/src/main/scala/tile/RocketTile.scala b/src/main/scala/tile/RocketTile.scala index 074b17593c1..ae9dd0fa2a4 100644 --- a/src/main/scala/tile/RocketTile.scala +++ b/src/main/scala/tile/RocketTile.scala @@ -25,9 +25,7 @@ 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, TraceSinkAlways, TraceSinkDMA, - TraceEncoderController, TraceSinkArbiter} +import freechips.rocketchip.trace.{TraceEncoderParams,TraceEncoderController, TraceSinkArbiter} import freechips.rocketchip.subsystem._ import freechips.rocketchip.util.BooleanToAugmentedBoolean @@ -229,7 +227,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/trace/TacitEncoder.scala b/src/main/scala/trace/TacitEncoder.scala deleted file mode 100644 index 6d28ec0df44..00000000000 --- a/src/main/scala/trace/TacitEncoder.scala +++ /dev/null @@ -1,408 +0,0 @@ -// 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 - -object FullHeaderType extends ChiselEnum { - val FTakenBranch = Value(0x0.U) // 000 - val FNotTakenBranch = Value(0x1.U) // 001 - val FUninfJump = Value(0x2.U) // 010 - val FInfJump = Value(0x3.U) // 011 - val FTrap = Value(0x4.U) // 100 - val FSync = Value(0x5.U) // 101 - val FValue = Value(0x6.U) // 110 - val FReserved = Value(0x7.U) // 111 -} - -object CompressedHeaderType extends ChiselEnum { - val CTB = Value(0x0.U) // 00, taken branch - val CNT = Value(0x1.U) // 01, not taken branch - val CNA = Value(0x2.U) // 10, not a compressed packet - val CIJ = Value(0x3.U) // 11, is a jump -} - -object TrapType extends ChiselEnum { - val TNone = Value(0x0.U) - val TException = Value(0x1.U) - val TInterrupt = Value(0x2.U) - val TReturn = Value(0x4.U) -} - -object HeaderByte { - def apply(header_type: FullHeaderType.Type, trap_type: TrapType.Type): UInt = { - Cat( - trap_type.asUInt, - header_type.asUInt, - CompressedHeaderType.CNA.asUInt - ) - } -} - -// Variable-length encoding helper module -class VarLenEncoder(val maxWidth: Int) extends Module { - val maxNumBytes = maxWidth/(8-1) + 1 - - val io = IO(new Bundle { - val input_value = Input(UInt(maxWidth.W)) - val input_valid = Input(Bool()) - val output_num_bytes = Output(UInt(log2Ceil(maxNumBytes).W)) - val output_bytes = Output(Vec(maxNumBytes, UInt(8.W))) - }) - - // 0-indexed MSB index - val msb_index = (maxWidth - 1).U - PriorityEncoder(Reverse(io.input_value)) - io.output_num_bytes := Mux(io.input_valid, (msb_index / 7.U) + 1.U, 0.U) - - for (i <- 0 until maxNumBytes) { - val is_last_byte = (i.U === (io.output_num_bytes - 1.U)) - io.output_bytes(i) := Mux(i.U < io.output_num_bytes, - io.input_value(min(i*7+6, maxWidth-1), i*7) | Mux(is_last_byte, 0x80.U, 0.U), - 0.U - ) - } -} - -// slice packets into bytes TODO: is this efficient? -class TracePacketizer(val coreParams: TraceCoreParams) extends Module { - def getMaxNumBytes(width: Int): Int = { width/(8-1) + 1 } - val addrMaxNumBytes = getMaxNumBytes(coreParams.iaddrWidth) - val timeMaxNumBytes = getMaxNumBytes(coreParams.xlen) - // println(s"addrMaxNumBytes: $addrMaxNumBytes, timeMaxNumBytes: $timeMaxNumBytes") - val metaDataWidth = 2 * log2Ceil(addrMaxNumBytes) + log2Ceil(timeMaxNumBytes) + 1 - val io = IO(new Bundle { - val target_addr = Flipped(Decoupled(Vec(addrMaxNumBytes, UInt(8.W)))) - val trap_addr = Flipped(Decoupled(Vec(addrMaxNumBytes, UInt(8.W)))) - val time = Flipped(Decoupled(Vec(timeMaxNumBytes, UInt(8.W)))) - val byte = Flipped(Decoupled(UInt(8.W))) - val metadata = Flipped(Decoupled(UInt(metaDataWidth.W))) - val out = Decoupled(UInt(8.W)) - }) - - val pIdle :: pComp :: pFull :: Nil = Enum(3) - val state = RegInit(pIdle) - - val trap_addr_num_bytes = Reg(UInt(log2Ceil(addrMaxNumBytes).W)) - val trap_addr_index = Reg(UInt(log2Ceil(addrMaxNumBytes).W)) - val target_addr_num_bytes = Reg(UInt(log2Ceil(addrMaxNumBytes).W)) - val target_addr_index = Reg(UInt(log2Ceil(addrMaxNumBytes).W)) - val time_num_bytes = Reg(UInt(log2Ceil(timeMaxNumBytes).W)) - val time_index = Reg(UInt(log2Ceil(timeMaxNumBytes).W)) - val header_num_bytes = Reg(UInt(1.W)) - val header_index = Reg(UInt(1.W)) - - val is_compressed = io.metadata.bits(0) - val trap_addr_metadata = io.metadata.bits(metaDataWidth-1, log2Ceil(timeMaxNumBytes)+log2Ceil(addrMaxNumBytes)+1) - val target_addr_metadata = io.metadata.bits(log2Ceil(timeMaxNumBytes)+log2Ceil(addrMaxNumBytes), log2Ceil(timeMaxNumBytes)+1) - val time_metadata = io.metadata.bits(log2Ceil(timeMaxNumBytes), 1) - - // default values - io.out.valid := false.B - io.metadata.ready := false.B - io.target_addr.ready := false.B - io.trap_addr.ready := false.B - io.time.ready := false.B - io.byte.ready := false.B - io.out.bits := 0.U - - def prep_next_state(): Unit = { - trap_addr_index := 0.U - trap_addr_num_bytes := Mux(io.metadata.fire, trap_addr_metadata, 0.U) - target_addr_index := 0.U - target_addr_num_bytes := Mux(io.metadata.fire, target_addr_metadata, 0.U) - time_index := 0.U - time_num_bytes := Mux(io.metadata.fire, time_metadata, 0.U) - header_index := 0.U - header_num_bytes := Mux(io.metadata.fire, ~is_compressed, 0.U) - state := Mux(io.metadata.fire, - Mux(is_compressed, pComp, pFull), - pIdle - ) - } - - switch (state) { - is (pIdle) { - io.metadata.ready := true.B - when (io.metadata.fire) { - trap_addr_num_bytes := trap_addr_metadata - trap_addr_index := 0.U - target_addr_num_bytes := target_addr_metadata - target_addr_index := 0.U - time_num_bytes := time_metadata - time_index := 0.U - header_num_bytes := ~is_compressed - header_index := 0.U - state := Mux(is_compressed, pComp, pFull) - } - } - is (pComp) { - // transmit a byte from byte buffer - io.byte.ready := io.out.ready - io.out.valid := io.byte.valid - io.out.bits := io.byte.bits - when (io.byte.fire) { - // metadata runs ahead by 1 cycle for performance optimization - io.metadata.ready := true.B - prep_next_state() - } - } - is (pFull) { - // header, addr, time - io.out.valid := true.B - when (header_num_bytes > 0.U && header_index < header_num_bytes) { - io.out.bits := io.byte.bits - io.out.valid := io.byte.valid - header_index := header_index + io.out.fire - } .elsewhen (trap_addr_num_bytes > 0.U && trap_addr_index < trap_addr_num_bytes) { - io.out.bits := io.trap_addr.bits(trap_addr_index) - io.out.valid := io.trap_addr.valid - trap_addr_index := trap_addr_index + io.out.fire - } .elsewhen (target_addr_num_bytes > 0.U && target_addr_index < target_addr_num_bytes) { - io.out.bits := io.target_addr.bits(target_addr_index) - io.out.valid := io.target_addr.valid - target_addr_index := target_addr_index + io.out.fire - } .elsewhen (time_num_bytes > 0.U && time_index < time_num_bytes) { - io.out.bits := io.time.bits(time_index) - io.out.valid := io.time.valid - time_index := time_index + io.out.fire - } .otherwise { - // FIXME: delay for 1 cycle - io.out.valid := false.B - // release buffers - io.byte.ready := true.B - // if we ever have a packet, we need to be ready to accept it - io.target_addr.ready := target_addr_num_bytes =/= 0.U - io.trap_addr.ready := trap_addr_num_bytes =/= 0.U - io.time.ready := time_num_bytes =/= 0.U - io.metadata.ready := true.B - prep_next_state() - } - } - } -} - -class TacitEncoder(override val coreParams: TraceCoreParams, val bufferDepth: Int)(implicit p: Parameters) - extends LazyTraceEncoder(coreParams)(p) { - override lazy val module = new TacitEncoderModule(this) -} - -class TacitEncoderModule(outer: TacitEncoder) extends LazyTraceEncoderModule(outer) { - - val MAX_DELTA_TIME_COMP = 0xCF // 63, 6 bits - - // when (io.stall) { - // printf("TraceEncoder stall detected\n") - // } - - // states - val sIdle :: sSync :: sData :: Nil = Enum(3) - val state = RegInit(sIdle) - val enabled = RegInit(false.B) - val stall = Wire(Bool()) - val prev_time = Reg(UInt(outer.coreParams.xlen.W)) - // pipeline of ingress data - val ingress_0 = RegInit(0.U.asTypeOf(new TraceCoreInterface(outer.coreParams))) - val ingress_1 = RegInit(0.U.asTypeOf(new TraceCoreInterface(outer.coreParams))) - - // shift every cycle, if not stalled - val pipeline_advance = Wire(Bool()) - pipeline_advance := !stall && io.in.group(0).iretire === 1.U - when (pipeline_advance) { - ingress_0 := io.in - ingress_1 := ingress_0 - } - - // encoders - val trap_addr_encoder = Module(new VarLenEncoder(outer.coreParams.iaddrWidth)) - val target_addr_encoder = Module(new VarLenEncoder(outer.coreParams.iaddrWidth)) - val time_encoder = Module(new VarLenEncoder(outer.coreParams.xlen)) - val metadataWidth = log2Ceil(trap_addr_encoder.maxNumBytes) + log2Ceil(target_addr_encoder.maxNumBytes) + log2Ceil(time_encoder.maxNumBytes) + 1 - - // queue buffers - val trap_addr_buffer = Module(new Queue(Vec(trap_addr_encoder.maxNumBytes, UInt(8.W)), outer.bufferDepth)) - val target_addr_buffer = Module(new Queue(Vec(target_addr_encoder.maxNumBytes, UInt(8.W)), outer.bufferDepth)) - val time_buffer = Module(new Queue(Vec(time_encoder.maxNumBytes, UInt(8.W)), outer.bufferDepth)) - val byte_buffer = Module(new Queue(UInt(8.W), outer.bufferDepth)) // buffer compressed packet or full header - val metadata_buffer = Module(new Queue(UInt(metadataWidth.W), outer.bufferDepth)) - // intermediate varlen encoder signals - val full_trap_addr = Wire(Vec(trap_addr_encoder.maxNumBytes, UInt(8.W))) - val trap_addr_num_bytes = Wire(UInt(log2Ceil(trap_addr_encoder.maxNumBytes).W)) - val full_target_addr = Wire(Vec(target_addr_encoder.maxNumBytes, UInt(8.W))) - val target_addr_num_bytes = Wire(UInt(log2Ceil(target_addr_encoder.maxNumBytes).W)) - val full_time = Wire(Vec(time_encoder.maxNumBytes, UInt(8.W))) - val time_num_bytes = Wire(UInt(log2Ceil(time_encoder.maxNumBytes).W)) - full_trap_addr := trap_addr_encoder.io.output_bytes - trap_addr_num_bytes := trap_addr_encoder.io.output_num_bytes - full_target_addr := target_addr_encoder.io.output_bytes - target_addr_num_bytes := target_addr_encoder.io.output_num_bytes - full_time := time_encoder.io.output_bytes - time_num_bytes := time_encoder.io.output_num_bytes - - // intermediate packet signals - val is_compressed = Wire(Bool()) - val delta_time = ingress_1.time - prev_time - val packet_valid = Wire(Bool()) - val header_byte = Wire(UInt(8.W)) // full header - val comp_packet = Wire(UInt(8.W)) // compressed packet - val comp_header = Wire(UInt(CompressedHeaderType.getWidth.W)) // compressed header - comp_packet := Cat(delta_time(5, 0), comp_header) - - // packetization of buffered message - val trace_packetizer = Module(new TracePacketizer(outer.coreParams)) - trace_packetizer.io.target_addr <> target_addr_buffer.io.deq - trace_packetizer.io.trap_addr <> trap_addr_buffer.io.deq - trace_packetizer.io.time <> time_buffer.io.deq - trace_packetizer.io.byte <> byte_buffer.io.deq - trace_packetizer.io.metadata <> metadata_buffer.io.deq - trace_packetizer.io.out <> io.out - - // intermediate encoder control signals - val encode_trap_addr_valid = Wire(Bool()) - val encode_target_addr_valid = Wire(Bool()) - - // metadata buffering - val metadata = Cat(trap_addr_num_bytes, target_addr_num_bytes, time_num_bytes, is_compressed) - metadata_buffer.io.enq.bits := metadata - metadata_buffer.io.enq.valid := packet_valid - // buffering compressed packet or full header depending on is_compressed - byte_buffer.io.enq.bits := Mux(is_compressed, comp_packet, header_byte) - byte_buffer.io.enq.valid := packet_valid - // trap address buffering - trap_addr_buffer.io.enq.bits := full_trap_addr - trap_addr_buffer.io.enq.valid := !is_compressed && packet_valid && encode_trap_addr_valid - // target address buffering - target_addr_buffer.io.enq.bits := full_target_addr - target_addr_buffer.io.enq.valid := !is_compressed && packet_valid && encode_target_addr_valid - // time buffering - time_buffer.io.enq.bits := full_time - time_buffer.io.enq.valid := !is_compressed && packet_valid - - // stall if any buffer is full - stall := !target_addr_buffer.io.enq.ready || !time_buffer.io.enq.ready || !byte_buffer.io.enq.ready - io.stall := stall - - val sent = RegInit(false.B) - // reset takes priority over enqueue - when (pipeline_advance) { - sent := false.B - } .elsewhen (byte_buffer.io.enq.fire) { - sent := true.B - } - - trap_addr_encoder.io.input_valid := encode_trap_addr_valid && !is_compressed && packet_valid - target_addr_encoder.io.input_valid := encode_target_addr_valid && !is_compressed && packet_valid - time_encoder.io.input_valid := !is_compressed && packet_valid - - // default values - trap_addr_encoder.io.input_value := 0.U - target_addr_encoder.io.input_value := 0.U - time_encoder.io.input_value := 0.U - is_compressed := false.B - packet_valid := false.B - encode_target_addr_valid := false.B - encode_trap_addr_valid := false.B - comp_header := CompressedHeaderType.CNA.asUInt - header_byte := HeaderByte(FullHeaderType.FReserved, TrapType.TNone) - // state machine - switch (state) { - is (sIdle) { - when (io.control.enable) { state := sSync } - } - is (sSync) { - header_byte := HeaderByte(FullHeaderType.FSync, TrapType.TNone) - time_encoder.io.input_value := ingress_0.time - prev_time := ingress_0.time - target_addr_encoder.io.input_value := ingress_0.group(0).iaddr >> 1.U // last bit is always 0 - encode_target_addr_valid := true.B - is_compressed := false.B - packet_valid := !sent - // state transition: wait for message to go in - state := Mux(pipeline_advance && (sent || byte_buffer.io.enq.fire), Mux(io.control.enable, sData, sIdle), sSync) - } - is (sData) { - when (!io.control.enable) { - state := sSync - } .otherwise { - switch (ingress_1.group(0).itype) { - is (TraceItype.ITNothing) { - packet_valid := false.B - } - is (TraceItype.ITBrTaken) { - header_byte := HeaderByte(FullHeaderType.FTakenBranch, TrapType.TNone) - comp_header := CompressedHeaderType.CTB.asUInt - time_encoder.io.input_value := delta_time - prev_time := ingress_1.time - is_compressed := delta_time <= MAX_DELTA_TIME_COMP.U - packet_valid := !sent - } - is (TraceItype.ITBrNTaken) { - header_byte := HeaderByte(FullHeaderType.FNotTakenBranch, TrapType.TNone) - comp_header := CompressedHeaderType.CNT.asUInt - time_encoder.io.input_value := delta_time - prev_time := ingress_1.time - is_compressed := delta_time <= MAX_DELTA_TIME_COMP.U - packet_valid := !sent - } - is (TraceItype.ITInJump) { - header_byte := HeaderByte(FullHeaderType.FInfJump, TrapType.TNone) - comp_header := CompressedHeaderType.CIJ.asUInt - time_encoder.io.input_value := delta_time - prev_time := ingress_1.time - is_compressed := delta_time <= MAX_DELTA_TIME_COMP.U - packet_valid := !sent - } - is (TraceItype.ITUnJump) { - header_byte := HeaderByte(FullHeaderType.FUninfJump, TrapType.TNone) - time_encoder.io.input_value := delta_time - prev_time := ingress_1.time - target_addr_encoder.io.input_value := (ingress_1.group(0).iaddr ^ ingress_0.group(0).iaddr) >> 1.U - encode_target_addr_valid := true.B - is_compressed := false.B - packet_valid := !sent - } - is (TraceItype.ITException) { - header_byte := HeaderByte(FullHeaderType.FTrap, TrapType.TException) - comp_header := CompressedHeaderType.CNA.asUInt - time_encoder.io.input_value := delta_time - prev_time := ingress_1.time - target_addr_encoder.io.input_value := (ingress_1.group(0).iaddr ^ ingress_0.group(0).iaddr) >> 1.U - encode_target_addr_valid := true.B - trap_addr_encoder.io.input_value := ingress_1.group(0).iaddr - encode_trap_addr_valid := true.B - is_compressed := false.B - packet_valid := !sent - } - is (TraceItype.ITInterrupt) { - header_byte := HeaderByte(FullHeaderType.FTrap, TrapType.TInterrupt) - comp_header := CompressedHeaderType.CNA.asUInt - time_encoder.io.input_value := delta_time - prev_time := ingress_1.time - target_addr_encoder.io.input_value := (ingress_1.group(0).iaddr ^ ingress_0.group(0).iaddr) >> 1.U - encode_target_addr_valid := true.B - trap_addr_encoder.io.input_value := ingress_1.group(0).iaddr - encode_trap_addr_valid := true.B - is_compressed := false.B - packet_valid := !sent - } - is (TraceItype.ITReturn) { - header_byte := HeaderByte(FullHeaderType.FTrap, TrapType.TReturn) - comp_header := CompressedHeaderType.CNA.asUInt - time_encoder.io.input_value := delta_time - prev_time := ingress_1.time - target_addr_encoder.io.input_value := (ingress_1.group(0).iaddr ^ ingress_0.group(0).iaddr) >> 1.U - encode_target_addr_valid := true.B - trap_addr_encoder.io.input_value := ingress_1.group(0).iaddr - encode_trap_addr_valid := true.B - is_compressed := false.B - packet_valid := !sent - } - } - } - } - } -} diff --git a/src/main/scala/trace/TraceSinkAlways.scala b/src/main/scala/trace/TraceSinkAlways.scala deleted file mode 100644 index af840460d7c..00000000000 --- a/src/main/scala/trace/TraceSinkAlways.scala +++ /dev/null @@ -1,29 +0,0 @@ -package freechips.rocketchip.trace - -import chisel3._ -import chisel3.util._ -import freechips.rocketchip.diplomacy._ -import freechips.rocketchip.prci._ -import org.chipsalliance.cde.config.{Parameters, Config, Field} -import freechips.rocketchip.tile._ -import freechips.rocketchip.subsystem._ -case object TraceSinkAlwaysKey extends Field[Option[Int]](None) - -class TraceSinkAlways()(implicit p: Parameters) extends LazyTraceSink { - override lazy val module = new TraceSinkAlwaysImpl(this) - class TraceSinkAlwaysImpl(outer: TraceSinkAlways) extends LazyTraceSinkModuleImp(outer) { - io.trace_in.ready := true.B - } -} - -class WithTraceSinkAlways(targetId: Int = 0) extends Config((site, here, up) => { - case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map { - case tp: RocketTileAttachParams => { - tp.copy(tileParams = tp.tileParams.copy( - traceParams = Some(tp.tileParams.traceParams.get.copy(buildSinks = - tp.tileParams.traceParams.get.buildSinks :+ (p => (LazyModule(new TraceSinkAlways()(p)), targetId))))) - ) - } - case other => other - } -}) \ No newline at end of file diff --git a/src/main/scala/trace/TraceSinkDMA.scala b/src/main/scala/trace/TraceSinkDMA.scala deleted file mode 100644 index da44766a128..00000000000 --- a/src/main/scala/trace/TraceSinkDMA.scala +++ /dev/null @@ -1,170 +0,0 @@ -package freechips.rocketchip.trace - -import chisel3._ -import chisel3.util._ -import freechips.rocketchip.tilelink._ -import freechips.rocketchip.diplomacy._ -import org.chipsalliance.cde.config.{Parameters, Field, Config} -import freechips.rocketchip.subsystem._ -import freechips.rocketchip.prci._ -import freechips.rocketchip.regmapper.{RegField, RegFieldDesc} -import freechips.rocketchip.tile._ - -case object TraceSinkDMAKey extends Field[Option[Int]](None) - -case class TraceSinkDMAParams( - regNodeBaseAddr: BigInt, - beatBytes: Int -) - -class TraceSinkDMA(params: TraceSinkDMAParams)(implicit p: Parameters) extends LazyTraceSink { - val node = TLClientNode(Seq(TLMasterPortParameters.v1(Seq(TLClientParameters( - name = "trace-sink-dma", sourceId = IdRange(0, 1)))))) - - val device = new SimpleDevice("trace-sink-dma", Seq("ucbbar,trace0")) - val regnode = TLRegisterNode( - address = Seq(AddressSet(params.regNodeBaseAddr, 0xFF)), - device = device, - beatBytes = params.beatBytes - ) - - lazy val module = new TraceSinkDMAImpl(this) - class TraceSinkDMAImpl(outer: TraceSinkDMA) extends LazyTraceSinkModuleImp(outer) { - val fifo = Module(new Queue(UInt(8.W), 32)) - fifo.io.enq <> io.trace_in - val (mem, edge) = outer.node.out(0) - val addrBits = edge.bundle.addressBits - val busWidth = edge.bundle.dataBits - val blockBytes = p(CacheBlockBytes) - - val mIdle :: mCollect :: mWrite :: mResp :: Nil = Enum(4) - val mstate = RegInit(mIdle) - - // tracks how much trace data have we written in total - val addr_counter = RegInit(0.U(64.W)) - // tracks how much trace data have we collected in current transaction - val collect_counter = RegInit(0.U(4.W)) - val msg_buffer = RegInit(VecInit(Seq.fill(busWidth / 8)(0.U(8.W)))) - - val dma_start_addr = RegInit(0.U(64.W)) - val dma_addr_write_valid = Wire(Bool()) - - val flush_reg = RegInit(false.B) - val done_reg = RegInit(false.B) - val collect_full = collect_counter === (busWidth / 8).U - val collect_advance = Mux(flush_reg, collect_full || fifo.io.deq.valid === false.B, collect_full) - val flush_done = (flush_reg) && (fifo.io.deq.valid === false.B) && mstate === mIdle - done_reg := done_reg || flush_done - - mem.a.valid := mstate === mWrite - mem.d.ready := mstate === mResp - fifo.io.deq.ready := false.B // default case - dontTouch(mem.d.valid) - - // mask according to collect_counter - val mask = (1.U << collect_counter) - 1.U - // putting the buffer data on the TL mem lane - - val put_req = edge.Put( - fromSource = 0.U, - toAddress = addr_counter + dma_start_addr, - lgSize = log2Ceil(busWidth / 8).U, - data = Cat(msg_buffer.reverse), - mask = mask)._2 - - mem.a.bits := put_req - - switch(mstate) { - is (mIdle) { - fifo.io.deq.ready := false.B - mstate := Mux(fifo.io.deq.valid, mCollect, mIdle) - collect_counter := 0.U - } - is (mCollect) { - // either we have collected enough data or that's all the messages for now - mstate := Mux(collect_advance, mWrite, mCollect) - collect_counter := Mux(fifo.io.deq.fire, collect_counter + 1.U, collect_counter) - msg_buffer(collect_counter) := Mux(fifo.io.deq.fire, fifo.io.deq.bits, msg_buffer(collect_counter)) - fifo.io.deq.ready := collect_counter < (busWidth / 8).U - } - // potentially, optimize this by pipelining collect and write - is (mWrite) { - // we need to write the collected data to the memory - fifo.io.deq.ready := false.B - mstate := Mux(mem.a.fire, mResp, mWrite) - } - is (mResp) { - fifo.io.deq.ready := false.B - mstate := Mux(mem.d.fire, mIdle, mResp) - addr_counter := Mux(mem.d.fire, addr_counter + collect_counter, addr_counter) - } - } - - // regmap handler functions - def traceSinkDMARegWrite(valid: Bool, bits: UInt): Bool = { - dma_addr_write_valid := valid && mstate === mIdle - when (dma_addr_write_valid) { - dma_start_addr := bits - } - true.B - } - - def traceSinkDMARegRead(ready: Bool): (Bool, UInt) = { - (true.B, dma_start_addr) - } - - val regmap = regnode.regmap( - Seq( - 0x00 -> Seq( - RegField(1, flush_reg, - RegFieldDesc("flush_reg", "Flush register")) - ), - 0x04 -> Seq( - RegField.r(1, done_reg, - RegFieldDesc("done_reg", "Done register")) - ), - 0x08 -> Seq( - RegField(64, traceSinkDMARegRead(_), traceSinkDMARegWrite(_, _), - RegFieldDesc("dma_start_addr", "DMA start address")) - ), - 0x10 -> Seq(RegField(64, addr_counter, - RegFieldDesc("addr_counter", "Address counter")) - ) - ):_* - ) - } -} - -class WithTraceSinkDMA(targetId: Int = 1) extends Config((site, here, up) => { - case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map { - case tp: RocketTileAttachParams => { - // redefine tile level constants - val xBytes = tp.tileParams.core.xLen / 8 - tp.copy(tileParams = tp.tileParams.copy( - traceParams = Some(tp.tileParams.traceParams.get.copy(buildSinks = - tp.tileParams.traceParams.get.buildSinks :+ (p => - (LazyModule(new TraceSinkDMA(TraceSinkDMAParams( - regNodeBaseAddr = 0x3010000 + tp.tileParams.tileId * 0x1000, - beatBytes = xBytes - ))(p)), targetId))))) - ) - } - case other => other - } -}) - -trait CanHaveTraceSinkDMA {this: BaseSubsystem with InstantiatesHierarchicalElements => - val traceSinkDMAs = totalTiles.values.map { t => t match { - case r: RocketTile => r.trace_sinks.collect { case r: TraceSinkDMA => (t, r) } - case _ => Nil - }}.flatten - val mbus = locateTLBusWrapper(MBUS) - traceSinkDMAs.foreach { case (t, s) => - t { // in the implicit clock domain of tile - mbus.coupleFrom(t.tileParams.baseName) { bus => - bus := mbus.crossOut(s.node)(ValName("trace_sink_dma"))(AsynchronousCrossing()) - } - t.connectTLSlave(s.regnode, t.xBytes) - } - } -} diff --git a/src/main/scala/trace/TraceSinkMonitor.scala b/src/main/scala/trace/TraceSinkMonitor.scala index 111a21fdb69..529f3c11271 100644 --- a/src/main/scala/trace/TraceSinkMonitor.scala +++ b/src/main/scala/trace/TraceSinkMonitor.scala @@ -6,7 +6,7 @@ import chisel3.experimental.StringParam class TraceSinkMonitor(name: String) extends BlackBox( Map( - "FILE_NAME" -> StringParam(s"tacit_${name}_trace.out") + "FILE_NAME" -> StringParam(s"${name}_trace.out") ) ) with HasBlackBoxResource { val io = IO(new Bundle { From 8db9f452dbc37bd16dcf7fbdb7e461b24265c618 Mon Sep 17 00:00:00 2001 From: Lux Date: Tue, 28 Jan 2025 14:11:23 -0800 Subject: [PATCH 20/22] FIX: make arbiter not lazy --- src/main/scala/tile/RocketTile.scala | 18 +++++----- src/main/scala/trace/TraceSinkArbiter.scala | 40 ++++++++++----------- 2 files changed, 27 insertions(+), 31 deletions(-) diff --git a/src/main/scala/tile/RocketTile.scala b/src/main/scala/tile/RocketTile.scala index ae9dd0fa2a4..1664aa7349a 100644 --- a/src/main/scala/tile/RocketTile.scala +++ b/src/main/scala/tile/RocketTile.scala @@ -107,11 +107,6 @@ class RocketTile private( case None => (Nil, Nil) } - val trace_sink_arbiter = rocketParams.traceParams.map { t => - val arb = LazyModule(new TraceSinkArbiter(traceSinkIds, use_monitor = t.useArbiterMonitor, monitor_name = rocketParams.uniqueName)) - arb - } - val tile_master_blocker = tileParams.blockerCtrlAddr .map(BasicBusBlockerParams(_, xBytes, masterPortBeatBytes, deadlock = true)) @@ -182,15 +177,20 @@ class RocketTileModuleImp(outer: RocketTile) extends BaseTileModuleImp(outer) // reset vector is connected in the Frontend to s2_pc core.io.reset_vector := DontCare + val trace_sink_arbiter = outer.rocketParams.traceParams.map { t => + val arb = Module(new TraceSinkArbiter(outer.traceSinkIds, use_monitor = t.useArbiterMonitor, monitor_name = outer.rocketParams.uniqueName)) + arb + } + 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 } - outer.trace_sink_arbiter.foreach { lm => - lm.module.io.target := outer.trace_encoder.get.module.io.control.target - lm.module.io.in <> outer.trace_encoder.get.module.io.out + trace_sink_arbiter.foreach { arb => + arb.io.target := outer.trace_encoder.get.module.io.control.target + arb.io.in <> outer.trace_encoder.get.module.io.out } core.io.traceStall := outer.traceAuxSinkNode.bundle.stall || outer.trace_encoder.get.module.io.stall @@ -200,7 +200,7 @@ class RocketTileModuleImp(outer: RocketTile) extends BaseTileModuleImp(outer) outer.trace_sinks.zip(outer.traceSinkIds).foreach { case (sink, id) => val index = outer.traceSinkIds.indexOf(id) - sink.module.io.trace_in <> outer.trace_sink_arbiter.get.module.io.out(index) + sink.module.io.trace_in <> trace_sink_arbiter.get.io.out(index) } // Report unrecoverable error conditions; for now the only cause is cache ECC errors diff --git a/src/main/scala/trace/TraceSinkArbiter.scala b/src/main/scala/trace/TraceSinkArbiter.scala index aaa3d5f33bc..ac50eae6451 100644 --- a/src/main/scala/trace/TraceSinkArbiter.scala +++ b/src/main/scala/trace/TraceSinkArbiter.scala @@ -12,28 +12,24 @@ 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")(implicit p: Parameters) extends LazyModule { - override lazy val module = new TraceSinkArbiterModuleImp(this) - override def shouldBeInlined = false - class TraceSinkArbiterModuleImp(outer: TraceSinkArbiter) extends LazyModuleImp(outer) { - 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 - } +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 - } + 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 } } From d2bddb8ae8af6c510a228c0e352c2a07cd807aa6 Mon Sep 17 00:00:00 2001 From: Lux Date: Wed, 29 Jan 2025 11:28:41 -0800 Subject: [PATCH 21/22] FIX: move arbiter into inner scope --- src/main/scala/tile/RocketTile.scala | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/src/main/scala/tile/RocketTile.scala b/src/main/scala/tile/RocketTile.scala index 1664aa7349a..4ec2211358b 100644 --- a/src/main/scala/tile/RocketTile.scala +++ b/src/main/scala/tile/RocketTile.scala @@ -177,32 +177,30 @@ class RocketTileModuleImp(outer: RocketTile) extends BaseTileModuleImp(outer) // reset vector is connected in the Frontend to s2_pc core.io.reset_vector := DontCare - val trace_sink_arbiter = outer.rocketParams.traceParams.map { t => - val arb = Module(new TraceSinkArbiter(outer.traceSinkIds, use_monitor = t.useArbiterMonitor, monitor_name = outer.rocketParams.uniqueName)) - arb - } - 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 } - trace_sink_arbiter.foreach { arb => - arb.io.target := outer.trace_encoder.get.module.io.control.target - arb.io.in <> outer.trace_encoder.get.module.io.out - } + 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 } - outer.trace_sinks.zip(outer.traceSinkIds).foreach { case (sink, id) => - val index = outer.traceSinkIds.indexOf(id) - sink.module.io.trace_in <> trace_sink_arbiter.get.io.out(index) - } - // Report unrecoverable error conditions; for now the only cause is cache ECC errors outer.reportHalt(List(outer.dcache.module.io.errors)) From 0dd7e794064a1280c9d919f41f2454fbaf29f52f Mon Sep 17 00:00:00 2001 From: Jerry Zhao Date: Wed, 29 Jan 2025 14:44:52 -0800 Subject: [PATCH 22/22] Fix DMCONTROLNxt naming --- src/main/scala/devices/debug/Debug.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/scala/devices/debug/Debug.scala b/src/main/scala/devices/debug/Debug.scala index 95982b84690..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) := DMCONTROLNext.hartreset & hartSelected(component) + hartResetNxt(component) := DMCONTROLNxt.hartreset & hartSelected(component) io.hartResetReq.get(component) := hartResetReg(component) } }