From 50a6870fc1c53771fab334206e1058a89f1f54cb Mon Sep 17 00:00:00 2001 From: Lux Date: Sun, 5 Oct 2025 17:02:59 -0700 Subject: [PATCH 01/11] bump: submodules --- generators/rocket-chip | 2 +- generators/shuttle | 2 +- generators/tacit | 2 +- software/baremetal-ide | 2 +- software/firemarshal | 2 +- software/spec2017 | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/generators/rocket-chip b/generators/rocket-chip index 8f1e33b253..f82a9d4747 160000 --- a/generators/rocket-chip +++ b/generators/rocket-chip @@ -1 +1 @@ -Subproject commit 8f1e33b253e3bce741861c0a2e3ba8b7ff85b292 +Subproject commit f82a9d4747c66a871a697c261ccd5cb503c2f3df diff --git a/generators/shuttle b/generators/shuttle index cb9313d036..51f59f6387 160000 --- a/generators/shuttle +++ b/generators/shuttle @@ -1 +1 @@ -Subproject commit cb9313d03637ca52d0ccf27ac8e986a0d454befb +Subproject commit 51f59f63879d3317c8e1f05af0e3a96cafb5b27d diff --git a/generators/tacit b/generators/tacit index fe61365292..1ce2313236 160000 --- a/generators/tacit +++ b/generators/tacit @@ -1 +1 @@ -Subproject commit fe61365292ef1fa60410a2a91c48a3e3d22b1a75 +Subproject commit 1ce2313236c3a3878787dc7c195a2437352e0c99 diff --git a/software/baremetal-ide b/software/baremetal-ide index 6e01715bea..601b2f0d3c 160000 --- a/software/baremetal-ide +++ b/software/baremetal-ide @@ -1 +1 @@ -Subproject commit 6e01715bea3e4a4015138e9583e40caa08205408 +Subproject commit 601b2f0d3cc834ac04720c8fc35c56bdb8124003 diff --git a/software/firemarshal b/software/firemarshal index 21119e5ce9..2fdfae665d 160000 --- a/software/firemarshal +++ b/software/firemarshal @@ -1 +1 @@ -Subproject commit 21119e5ce922ff9302f0bc9d2d7349c77f7ac064 +Subproject commit 2fdfae665d2d97b170e1aee5866084941aa14257 diff --git a/software/spec2017 b/software/spec2017 index 83e3311047..2e99bf7cf2 160000 --- a/software/spec2017 +++ b/software/spec2017 @@ -1 +1 @@ -Subproject commit 83e33110472c47aaa762257ed7c053ff1278834c +Subproject commit 2e99bf7cf27905e2bdaa8931d31e1eedbd608f1a From c05b42e78823f6ea5e33b96df664ca4c53ffef3e Mon Sep 17 00:00:00 2001 From: Lux Date: Sun, 5 Oct 2025 17:03:36 -0700 Subject: [PATCH 02/11] bump: submodule --- software/tacit_decoder | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/software/tacit_decoder b/software/tacit_decoder index acbbd2e2e5..0a3222b21e 160000 --- a/software/tacit_decoder +++ b/software/tacit_decoder @@ -1 +1 @@ -Subproject commit acbbd2e2e5344548a464460bff9ee9b9ff437209 +Subproject commit 0a3222b21e3228700450ec2146e8daa21034c9e9 From c35d2e04721722fe2c3fc79d63c4881ecc869011 Mon Sep 17 00:00:00 2001 From: Lux Date: Tue, 7 Oct 2025 18:02:20 -0700 Subject: [PATCH 03/11] add: wip: raw byte bridge and io binder --- build.sbt | 2 +- .../chipyard/src/main/scala/DigitalTop.scala | 1 + .../main/scala/config/AbstractConfig.scala | 2 ++ .../main/scala/harness/HarnessBinders.scala | 6 ++++ .../src/main/scala/iobinders/IOBinders.scala | 13 +++++++ .../src/main/scala/iobinders/Ports.scala | 4 +++ .../src/main/scala/Byte.scala | 15 ++++++++ .../src/main/scala/tacit/TacitBridge.scala | 36 +++++++++++++++++++ .../src/main/scala/tacit/TacitModule.scala | 16 +++++++++ .../chip/src/main/scala/BridgeBinders.scala | 6 ++++ .../chip/src/main/scala/TargetConfigs.scala | 9 +++++ 11 files changed, 109 insertions(+), 1 deletion(-) create mode 100644 generators/firechip/bridgeinterfaces/src/main/scala/Byte.scala create mode 100644 generators/firechip/bridgestubs/src/main/scala/tacit/TacitBridge.scala create mode 100644 generators/firechip/bridgestubs/src/main/scala/tacit/TacitModule.scala diff --git a/build.sbt b/build.sbt index c4197aba77..f19038ec59 100644 --- a/build.sbt +++ b/build.sbt @@ -173,7 +173,7 @@ lazy val chipyard = { Seq( testchipip, rocketchip, boom, rocketchip_blocks, rocketchip_inclusive_cache, icenet, tracegen, - constellation, barf, shuttle, rerocc, + constellation, barf, shuttle, rerocc, tacit, ).map(sbt.Project.projectToRef) ++ (if (useChisel7) Seq() else Seq(sbt.Project.projectToRef(firrtl2_bridge))) ++ (if (useChisel7) Seq() else Seq(sbt.Project.projectToRef(dsptools), sbt.Project.projectToRef(rocket_dsp_utils))) diff --git a/generators/chipyard/src/main/scala/DigitalTop.scala b/generators/chipyard/src/main/scala/DigitalTop.scala index ef1882bf9a..5ad9ca84cb 100644 --- a/generators/chipyard/src/main/scala/DigitalTop.scala +++ b/generators/chipyard/src/main/scala/DigitalTop.scala @@ -14,6 +14,7 @@ import freechips.rocketchip.devices.tilelink._ // DOC include start: DigitalTop class DigitalTop(implicit p: Parameters) extends ChipyardSystem + with tacit.CanHaveTraceSinkRawByte // Enables optionally adding the trace sink raw byte with testchipip.tsi.CanHavePeripheryUARTTSI // Enables optional UART-based TSI transport with testchipip.boot.CanHavePeripheryCustomBootPin // Enables optional custom boot pin with testchipip.cosim.CanHaveTraceIO // Enables optionally adding trace IO diff --git a/generators/chipyard/src/main/scala/config/AbstractConfig.scala b/generators/chipyard/src/main/scala/config/AbstractConfig.scala index 490b8ebca9..8dad151846 100644 --- a/generators/chipyard/src/main/scala/config/AbstractConfig.scala +++ b/generators/chipyard/src/main/scala/config/AbstractConfig.scala @@ -15,6 +15,7 @@ class AbstractConfig extends Config( // Set up TestHarness // ================================================ // The HarnessBinders control generation of hardware in the TestHarness + new chipyard.harness.WithTraceSinkRawByteHarnessTieOff ++ /** tie-off trace-sink-raw-byte port, if present */ new chipyard.harness.WithUARTAdapter ++ /** add UART adapter to display UART on stdout, if uart is present */ new chipyard.harness.WithBlackBoxSimMem ++ /** add SimDRAM DRAM model for axi4 backing memory, if axi4 mem is enabled */ new chipyard.harness.WithSimTSIOverSerialTL ++ /** add external serial-adapter and RAM */ @@ -62,6 +63,7 @@ class AbstractConfig extends Config( new chipyard.iobinders.WithTraceIOPunchthrough ++ new chipyard.iobinders.WithUARTTSIPunchthrough ++ new chipyard.iobinders.WithGCDIOPunchthrough ++ + new chipyard.iobinders.WithTraceSinkRawBytePunchthrough ++ new chipyard.iobinders.WithNMITiedOff ++ new chipyard.iobinders.WithOffchipBusSel ++ diff --git a/generators/chipyard/src/main/scala/harness/HarnessBinders.scala b/generators/chipyard/src/main/scala/harness/HarnessBinders.scala index 0ba96dbccb..14d83ede07 100644 --- a/generators/chipyard/src/main/scala/harness/HarnessBinders.scala +++ b/generators/chipyard/src/main/scala/harness/HarnessBinders.scala @@ -334,6 +334,12 @@ class WithResetFromHarness extends HarnessBinder({ } }) +class WithTraceSinkRawByteHarnessTieOff extends HarnessBinder({ + case (th: HasHarnessInstantiators, port: TraceSinkRawBytePort, chipId: Int) => { + port.io.out.ready := false.B + } +}) + class WithOffchipBusSelPlusArg extends HarnessBinder({ case (th: HasHarnessInstantiators, port: OffchipSelPort, chipId: Int) => { val pin = PlusArg("offchip_sel", width=port.io.getWidth) diff --git a/generators/chipyard/src/main/scala/iobinders/IOBinders.scala b/generators/chipyard/src/main/scala/iobinders/IOBinders.scala index a923247617..b550bdd819 100644 --- a/generators/chipyard/src/main/scala/iobinders/IOBinders.scala +++ b/generators/chipyard/src/main/scala/iobinders/IOBinders.scala @@ -40,6 +40,7 @@ import testchipip.tsi.{CanHavePeripheryUARTTSI, UARTTSIIO} import icenet.{CanHavePeripheryIceNIC, SimNetwork, NicLoopback, NICKey, NICIOvonly} import chipyard.{CanHaveMasterTLMemPort, ChipyardSystem, ChipyardSystemModule} import chipyard.example.{CanHavePeripheryGCD} +import tacit.{CanHaveTraceSinkRawByte, TraceSinkRawByteBundle} import scala.reflect.{ClassTag} @@ -598,6 +599,18 @@ class WithGCDIOPunchthrough extends OverrideIOBinder({ } }) +class WithTraceSinkRawBytePunchthrough extends OverrideIOBinder({ + (system: CanHaveTraceSinkRawByte) => { + val tacit_byte_ports = system.tacit_bytes.map { case s => + // a seq of decoupled bytes + val tacit_byte = IO(new TraceSinkRawByteBundle) + tacit_byte <> s + TraceSinkRawBytePort(() => tacit_byte) + } + (tacit_byte_ports, Nil) + } +}) + class WithOffchipBusSel extends OverrideIOBinder({ (system: CanHaveSwitchableOffchipBus) => { system.io_obus_sel.getWrappedValue.map { sel => diff --git a/generators/chipyard/src/main/scala/iobinders/Ports.scala b/generators/chipyard/src/main/scala/iobinders/Ports.scala index 93c95416f9..c5b4e32087 100644 --- a/generators/chipyard/src/main/scala/iobinders/Ports.scala +++ b/generators/chipyard/src/main/scala/iobinders/Ports.scala @@ -18,6 +18,7 @@ import freechips.rocketchip.subsystem.{MemoryPortParams, MasterPortParams, Slave import freechips.rocketchip.devices.debug.{ClockedDMIIO} import freechips.rocketchip.tilelink.{TLBundle} import org.chipsalliance.diplomacy.nodes.{HeterogeneousBag} +import tacit.TraceSinkRawByteBundle trait Port[T <: Data] { val getIO: () => T @@ -112,6 +113,9 @@ case class TLMemPort (val getIO: () => HeterogeneousBag[TLBundle]) case class GCDBusyPort (val getIO: () => Bool) extends Port[Bool] +case class TraceSinkRawBytePort(val getIO: () => TraceSinkRawByteBundle) + extends Port[TraceSinkRawByteBundle] + case class OffchipSelPort (val getIO: () => UInt) extends Port[UInt] diff --git a/generators/firechip/bridgeinterfaces/src/main/scala/Byte.scala b/generators/firechip/bridgeinterfaces/src/main/scala/Byte.scala new file mode 100644 index 0000000000..5133487fc5 --- /dev/null +++ b/generators/firechip/bridgeinterfaces/src/main/scala/Byte.scala @@ -0,0 +1,15 @@ +package firechip.bridgeinterfaces + +import chisel3._ + +class ByteIO extends Bundle { + val out = Output(UInt(8.W)) +} + +class ByteBridgeTargetIO extends Bundle { + val byte = Flipped(new ByteIO) + val reset = Input(Bool()) + val clock = Input(Clock()) +} + +case class ByteKey() // intentionally empty \ No newline at end of file diff --git a/generators/firechip/bridgestubs/src/main/scala/tacit/TacitBridge.scala b/generators/firechip/bridgestubs/src/main/scala/tacit/TacitBridge.scala new file mode 100644 index 0000000000..1537a536f0 --- /dev/null +++ b/generators/firechip/bridgestubs/src/main/scala/tacit/TacitBridge.scala @@ -0,0 +1,36 @@ +// see LICENSE for license details + +package firechip.bridgestubs + +import chisel3._ +import chisel3.util._ + +import org.chipsalliance.cde.config.Parameters + +import firesim.lib.bridgeutils._ + +import firechip.bridgeinterfaces._ + +class TacitBridge(implicit p: Parameters) extends BlackBox + with Bridge[HostPortIO[ByteBridgeTargetIO]] { + + + val moduleName = "firechip.goldengateimplementations.TacitBridgeModule" + + val io = IO(new ByteBridgeTargetIO) + val bridgeIO = HostPort(io) + + val constructorArg = Some(ByteKey()) + + generateAnnotations() +} + +object TacitBridge { + def apply(clock: Clock, byte: UInt, reset: Bool)(implicit p: Parameters): TacitBridge = { + val ep = Module(new TacitBridge) + ep.io.byte := byte + ep.io.reset := reset + ep.io.clock := clock + ep + } +} \ No newline at end of file diff --git a/generators/firechip/bridgestubs/src/main/scala/tacit/TacitModule.scala b/generators/firechip/bridgestubs/src/main/scala/tacit/TacitModule.scala new file mode 100644 index 0000000000..337d0aa08e --- /dev/null +++ b/generators/firechip/bridgestubs/src/main/scala/tacit/TacitModule.scala @@ -0,0 +1,16 @@ +// See LICENSE for license details. + +package firechip.bridgestubs + +import chisel3._ + +import org.chipsalliance.cde.config.Parameters + +class TacitDUT(implicit val p: Parameters) extends Module { + val ep = Module(new TacitBridge) + ep.io.byte := byte + ep.io.reset := reset + ep.io.clock := clock +} + +class TacitModule(implicit p: Parameters) extends firesim.lib.testutils.PeekPokeHarness(() => new TacitDUT) diff --git a/generators/firechip/chip/src/main/scala/BridgeBinders.scala b/generators/firechip/chip/src/main/scala/BridgeBinders.scala index 5a05550fc2..dbdc63c236 100644 --- a/generators/firechip/chip/src/main/scala/BridgeBinders.scala +++ b/generators/firechip/chip/src/main/scala/BridgeBinders.scala @@ -141,6 +141,12 @@ class WithSuccessBridge extends HarnessBinder({ } }) +class WithTacitBridge extends HarnessBinder({ + case (th: FireSim, port: TraceSinkRawBytePort, chipId: Int) => { + TacitBridge(th.harnessBinderClock, port.io, th.harnessBinderReset.asBool) + } +}) + // Shorthand to register all of the provided bridges above class WithDefaultFireSimBridges extends Config( new WithTSIBridgeAndHarnessRAMOverSerialTL ++ diff --git a/generators/firechip/chip/src/main/scala/TargetConfigs.scala b/generators/firechip/chip/src/main/scala/TargetConfigs.scala index 879ac198b6..9c396607f6 100644 --- a/generators/firechip/chip/src/main/scala/TargetConfigs.scala +++ b/generators/firechip/chip/src/main/scala/TargetConfigs.scala @@ -352,3 +352,12 @@ class FireSimLargeBoomSV39CospikeConfig extends Config( new WithFireSimConfigTweaks++ new freechips.rocketchip.rocket.WithSV39 ++ new chipyard.LargeBoomV3Config) + +//********************************************************************************** +// Tacit Configurations +//*********************************************************************************/ +class FireSimRocketTacitConfig extends Config( + new WithTacitBridge ++ + new WithDefaultFireSimBridges ++ + new WithFireSimConfigTweaks++ + new chipyard.TacitRocketRawByteConfig) From f3d49e4488f6c24e67bae7bff97050b066f25fbf Mon Sep 17 00:00:00 2001 From: Lux Date: Tue, 7 Oct 2025 18:04:59 -0700 Subject: [PATCH 04/11] refactor: renaming --- .../bridgeinterfaces/src/main/scala/Byte.scala | 15 --------------- .../src/main/scala/TraceRawByte.scala | 15 +++++++++++++++ .../src/main/scala/tacit/TacitBridge.scala | 6 +++--- 3 files changed, 18 insertions(+), 18 deletions(-) delete mode 100644 generators/firechip/bridgeinterfaces/src/main/scala/Byte.scala create mode 100644 generators/firechip/bridgeinterfaces/src/main/scala/TraceRawByte.scala diff --git a/generators/firechip/bridgeinterfaces/src/main/scala/Byte.scala b/generators/firechip/bridgeinterfaces/src/main/scala/Byte.scala deleted file mode 100644 index 5133487fc5..0000000000 --- a/generators/firechip/bridgeinterfaces/src/main/scala/Byte.scala +++ /dev/null @@ -1,15 +0,0 @@ -package firechip.bridgeinterfaces - -import chisel3._ - -class ByteIO extends Bundle { - val out = Output(UInt(8.W)) -} - -class ByteBridgeTargetIO extends Bundle { - val byte = Flipped(new ByteIO) - val reset = Input(Bool()) - val clock = Input(Clock()) -} - -case class ByteKey() // intentionally empty \ No newline at end of file diff --git a/generators/firechip/bridgeinterfaces/src/main/scala/TraceRawByte.scala b/generators/firechip/bridgeinterfaces/src/main/scala/TraceRawByte.scala new file mode 100644 index 0000000000..439dc210e7 --- /dev/null +++ b/generators/firechip/bridgeinterfaces/src/main/scala/TraceRawByte.scala @@ -0,0 +1,15 @@ +package firechip.bridgeinterfaces + +import chisel3._ + +class TraceRawBytePortIO extends Bundle { + val out = Decoupled(UInt(8.W)) +} + +class TraceRawByteBridgeTargetIO extends Bundle { + val byte = Flipped(new TraceRawBytePortIO) + val reset = Input(Bool()) + val clock = Input(Clock()) +} + +case class TraceRawByteKey() // intentionally empty \ No newline at end of file diff --git a/generators/firechip/bridgestubs/src/main/scala/tacit/TacitBridge.scala b/generators/firechip/bridgestubs/src/main/scala/tacit/TacitBridge.scala index 1537a536f0..de80c1d0e3 100644 --- a/generators/firechip/bridgestubs/src/main/scala/tacit/TacitBridge.scala +++ b/generators/firechip/bridgestubs/src/main/scala/tacit/TacitBridge.scala @@ -12,12 +12,12 @@ import firesim.lib.bridgeutils._ import firechip.bridgeinterfaces._ class TacitBridge(implicit p: Parameters) extends BlackBox - with Bridge[HostPortIO[ByteBridgeTargetIO]] { + with Bridge[HostPortIO[TraceRawByteBridgeTargetIO]] { val moduleName = "firechip.goldengateimplementations.TacitBridgeModule" - val io = IO(new ByteBridgeTargetIO) + val io = IO(new TraceRawByteBridgeTargetIO) val bridgeIO = HostPort(io) val constructorArg = Some(ByteKey()) @@ -26,7 +26,7 @@ class TacitBridge(implicit p: Parameters) extends BlackBox } object TacitBridge { - def apply(clock: Clock, byte: UInt, reset: Bool)(implicit p: Parameters): TacitBridge = { + def apply(clock: Clock, byte: TraceRawBytePortIO, reset: Bool)(implicit p: Parameters): TacitBridge = { val ep = Module(new TacitBridge) ep.io.byte := byte ep.io.reset := reset From cbe4048f9615ee6b953f741532b93dc8c9310244 Mon Sep 17 00:00:00 2001 From: Lux Date: Wed, 8 Oct 2025 17:16:14 -0700 Subject: [PATCH 05/11] add: tacit bridge --- .../src/main/scala/TraceRawByte.scala | 1 + .../bridgestubs/src/main/cc/bridges/tacit.cc | 66 +++++++++++++++++++ .../bridgestubs/src/main/cc/bridges/tacit.h | 58 ++++++++++++++++ .../src/main/scala/tacit/TacitBridge.scala | 8 +-- .../src/main/scala/tacit/TacitModule.scala | 6 +- .../src/main/scala/TacitBridge.scala | 48 ++++++++++++++ 6 files changed, 180 insertions(+), 7 deletions(-) create mode 100644 generators/firechip/bridgestubs/src/main/cc/bridges/tacit.cc create mode 100644 generators/firechip/bridgestubs/src/main/cc/bridges/tacit.h create mode 100644 generators/firechip/goldengateimplementations/src/main/scala/TacitBridge.scala diff --git a/generators/firechip/bridgeinterfaces/src/main/scala/TraceRawByte.scala b/generators/firechip/bridgeinterfaces/src/main/scala/TraceRawByte.scala index 439dc210e7..c79881720b 100644 --- a/generators/firechip/bridgeinterfaces/src/main/scala/TraceRawByte.scala +++ b/generators/firechip/bridgeinterfaces/src/main/scala/TraceRawByte.scala @@ -1,6 +1,7 @@ package firechip.bridgeinterfaces import chisel3._ +import chisel3.util._ class TraceRawBytePortIO extends Bundle { val out = Decoupled(UInt(8.W)) diff --git a/generators/firechip/bridgestubs/src/main/cc/bridges/tacit.cc b/generators/firechip/bridgestubs/src/main/cc/bridges/tacit.cc new file mode 100644 index 0000000000..116c685ada --- /dev/null +++ b/generators/firechip/bridgestubs/src/main/cc/bridges/tacit.cc @@ -0,0 +1,66 @@ +// See LICENSE for license details + +#include "tacit.h" +#include "core/simif.h" + +#include +#include + +#include +#include + +char tacit_t::KIND; + +class tacit_handler_impl final : public tacit_handler { +public: + tacit_handler_impl(int tacitno, int tacitlogfd) { + this->tacitlogfd = tacitlogfd; + } +protected: + int tacitlogfd; + + void put(uint8_t data) override; +}; + +void tacit_handler_impl::put(uint8_t data) { + write(tacitlogfd, &data, 1); +} + +static std::unique_ptr +create_handler(const std::vector &args, int tacitno) { + // open a new file for dumping the bytes + std::string tacitlogname = std::string("tacit") + std::to_string(tacitno) + ".out"; + int tacitlogfd = open(tacitlogname.c_str(), O_WRONLY | O_CREAT, 0644); + if (tacitlogfd == -1) { + fprintf(stderr, "Failed to open TACIT%d log file: %s\n", tacitno, tacitlogname.c_str()); + return nullptr; + } + return std::make_unique(tacitno, tacitlogfd); +} + +tacit_t::tacit_t(simif_t &simif, + const TACITBRIDGEMODULE_struct &mmio_addrs, + int tacitno, + const std::vector &args) + : bridge_driver_t(simif, &KIND), mmio_addrs(mmio_addrs), + handler(create_handler(args, tacitno)) {} + +tacit_t::~tacit_t() = default; + +void tacit_t::recv() { + data.out.valid = read(mmio_addrs.out_valid); + if (data.out.valid) { + data.out.bits = read(mmio_addrs.out_bits); + } +} + +void tacit_t::tick() { + data.out.ready = true; + do { + this->recv(); + + if (data.out.fire()) { + handler->put(data.out.bits); + } + } while (data.out.fire()); +} \ No newline at end of file diff --git a/generators/firechip/bridgestubs/src/main/cc/bridges/tacit.h b/generators/firechip/bridgestubs/src/main/cc/bridges/tacit.h new file mode 100644 index 0000000000..85cc5dc52c --- /dev/null +++ b/generators/firechip/bridgestubs/src/main/cc/bridges/tacit.h @@ -0,0 +1,58 @@ +// See LICENSE for license details + +#ifndef __TACITBRIDGE_H +#define __TACITBRIDGE_H + +#include "bridges/serial_data.h" +#include "core/bridge_driver.h" + +#include +#include +#include +#include +#include +#include + +/** + * Structure carrying the addresses of all fixed MMIO ports. + * + * This structure is instantiated when all bridges are populated based on + * the target configuration. + */ +struct TACITBRIDGEMODULE_struct { + uint64_t out_bits; + uint64_t out_valid; + uint64_t out_ready; +}; + +class tacit_handler { +public: + virtual ~tacit_handler() = default; + virtual void put(uint8_t data) = 0; +}; + +class tacit_t final : public bridge_driver_t { +public: + /// The identifier for the bridge type used for casts. + static char KIND; + + /// Creates a bridge which interacts with standard streams or PTY. + tacit_t(simif_t &simif, + const TACITBRIDGEMODULE_struct &mmio_addrs, + int tacitno, + const std::vector &args); + + ~tacit_t() override; + + void tick() override; + +private: + const TACITBRIDGEMODULE_struct mmio_addrs; + std::unique_ptr handler; + + serial_data_t data; + + void recv(); +}; + +#endif // __TACITBRIDGE_H diff --git a/generators/firechip/bridgestubs/src/main/scala/tacit/TacitBridge.scala b/generators/firechip/bridgestubs/src/main/scala/tacit/TacitBridge.scala index de80c1d0e3..e6ccb7ca7c 100644 --- a/generators/firechip/bridgestubs/src/main/scala/tacit/TacitBridge.scala +++ b/generators/firechip/bridgestubs/src/main/scala/tacit/TacitBridge.scala @@ -11,7 +11,7 @@ import firesim.lib.bridgeutils._ import firechip.bridgeinterfaces._ -class TacitBridge(implicit p: Parameters) extends BlackBox +class TacitBridge() extends BlackBox with Bridge[HostPortIO[TraceRawByteBridgeTargetIO]] { @@ -20,15 +20,15 @@ class TacitBridge(implicit p: Parameters) extends BlackBox val io = IO(new TraceRawByteBridgeTargetIO) val bridgeIO = HostPort(io) - val constructorArg = Some(ByteKey()) + val constructorArg = Some(TraceRawByteKey()) generateAnnotations() } object TacitBridge { - def apply(clock: Clock, byte: TraceRawBytePortIO, reset: Bool)(implicit p: Parameters): TacitBridge = { + def apply(clock: Clock, byte: tacit.TraceSinkRawByteBundle, reset: Bool): TacitBridge = { val ep = Module(new TacitBridge) - ep.io.byte := byte + ep.io.byte.out <> byte.out ep.io.reset := reset ep.io.clock := clock ep diff --git a/generators/firechip/bridgestubs/src/main/scala/tacit/TacitModule.scala b/generators/firechip/bridgestubs/src/main/scala/tacit/TacitModule.scala index 337d0aa08e..311d193040 100644 --- a/generators/firechip/bridgestubs/src/main/scala/tacit/TacitModule.scala +++ b/generators/firechip/bridgestubs/src/main/scala/tacit/TacitModule.scala @@ -8,9 +8,9 @@ import org.chipsalliance.cde.config.Parameters class TacitDUT(implicit val p: Parameters) extends Module { val ep = Module(new TacitBridge) - ep.io.byte := byte - ep.io.reset := reset - ep.io.clock := clock + ep.io.byte.out := ep.io.byte.out + ep.io.reset := reset + ep.io.clock := clock } class TacitModule(implicit p: Parameters) extends firesim.lib.testutils.PeekPokeHarness(() => new TacitDUT) diff --git a/generators/firechip/goldengateimplementations/src/main/scala/TacitBridge.scala b/generators/firechip/goldengateimplementations/src/main/scala/TacitBridge.scala new file mode 100644 index 0000000000..af879c2ca0 --- /dev/null +++ b/generators/firechip/goldengateimplementations/src/main/scala/TacitBridge.scala @@ -0,0 +1,48 @@ +// See LICENSE for license details + +package firechip.goldengateimplementations + +import chisel3._ +import chisel3.util._ + +import org.chipsalliance.cde.config.Parameters + +import midas.widgets._ +import firesim.lib.bridgeutils._ + +import firechip.bridgeinterfaces._ + +class TacitBridgeModule(key: TraceRawByteKey)(implicit p: Parameters) extends BridgeModule[HostPortIO[TraceRawByteBridgeTargetIO]]()(p) { + lazy val module = new BridgeModuleImp(this) { + val io = IO(new WidgetIO()) + + val hPort = IO(HostPort(new TraceRawByteBridgeTargetIO)) + + val txfifo = Module(new Queue(UInt(8.W), 128)) + + val target = hPort.hBits.byte + + val fire = hPort.toHost.hValid && + hPort.fromHost.hReady && + txfifo.io.enq.ready + + val targetReset = fire & hPort.hBits.reset + txfifo.reset := reset.asBool || targetReset + + hPort.toHost.hReady := fire + hPort.fromHost.hValid := fire + + txfifo.io.enq <> target.out + + genROReg(txfifo.io.deq.bits, "out_bits") + genROReg(txfifo.io.deq.valid, "out_valid") + + Pulsify(genWORegInit(txfifo.io.deq.ready, "out_ready", false.B), pulseLength = 1) + + genCRFile() + + override def genHeader(base: BigInt, memoryRegions: Map[String, BigInt], sb: StringBuilder): Unit = { + genConstructor(base, sb, "tacit_t", "tacit") + } + } +} \ No newline at end of file From 6641acf12222934af257b54280f39504cbff98aa Mon Sep 17 00:00:00 2001 From: Lux Date: Thu, 9 Oct 2025 16:48:41 -0700 Subject: [PATCH 06/11] fix: properly fire during receiving --- .../bridgestubs/src/main/cc/bridges/tacit.cc | 18 ++++++++++++++++-- .../bridgestubs/src/main/cc/bridges/tacit.h | 1 + .../src/main/scala/TacitBridge.scala | 4 +++- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/generators/firechip/bridgestubs/src/main/cc/bridges/tacit.cc b/generators/firechip/bridgestubs/src/main/cc/bridges/tacit.cc index 116c685ada..8529d3093f 100644 --- a/generators/firechip/bridgestubs/src/main/cc/bridges/tacit.cc +++ b/generators/firechip/bridgestubs/src/main/cc/bridges/tacit.cc @@ -9,6 +9,8 @@ #include #include +// #define DEBUG + char tacit_t::KIND; class tacit_handler_impl final : public tacit_handler { @@ -24,13 +26,17 @@ class tacit_handler_impl final : public tacit_handler { void tacit_handler_impl::put(uint8_t data) { write(tacitlogfd, &data, 1); + #ifdef DEBUG + fprintf(stderr, "TACIT%d: %02x\n", tacitlogfd, data); + #endif } static std::unique_ptr create_handler(const std::vector &args, int tacitno) { // open a new file for dumping the bytes std::string tacitlogname = std::string("tacit") + std::to_string(tacitno) + ".out"; - int tacitlogfd = open(tacitlogname.c_str(), O_WRONLY | O_CREAT, 0644); + // create if non-existent, truncate if exists + int tacitlogfd = open(tacitlogname.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0644); if (tacitlogfd == -1) { fprintf(stderr, "Failed to open TACIT%d log file: %s\n", tacitno, tacitlogname.c_str()); return nullptr; @@ -54,13 +60,21 @@ void tacit_t::recv() { } } +void tacit_t::send() { + if (data.out.fire()) { + write(mmio_addrs.out_ready, data.out.ready); + } +} + void tacit_t::tick() { data.out.ready = true; do { this->recv(); - + // data serves as an intermediate buffer + // between the bridge and the handler if (data.out.fire()) { handler->put(data.out.bits); } + this->send(); } while (data.out.fire()); } \ No newline at end of file diff --git a/generators/firechip/bridgestubs/src/main/cc/bridges/tacit.h b/generators/firechip/bridgestubs/src/main/cc/bridges/tacit.h index 85cc5dc52c..829e815a89 100644 --- a/generators/firechip/bridgestubs/src/main/cc/bridges/tacit.h +++ b/generators/firechip/bridgestubs/src/main/cc/bridges/tacit.h @@ -53,6 +53,7 @@ class tacit_t final : public bridge_driver_t { serial_data_t data; void recv(); + void send(); }; #endif // __TACITBRIDGE_H diff --git a/generators/firechip/goldengateimplementations/src/main/scala/TacitBridge.scala b/generators/firechip/goldengateimplementations/src/main/scala/TacitBridge.scala index af879c2ca0..6f873ce12d 100644 --- a/generators/firechip/goldengateimplementations/src/main/scala/TacitBridge.scala +++ b/generators/firechip/goldengateimplementations/src/main/scala/TacitBridge.scala @@ -32,7 +32,9 @@ class TacitBridgeModule(key: TraceRawByteKey)(implicit p: Parameters) extends Br hPort.toHost.hReady := fire hPort.fromHost.hValid := fire - txfifo.io.enq <> target.out + txfifo.io.enq.bits := target.out.bits + txfifo.io.enq.valid := target.out.valid && fire + target.out.ready := txfifo.io.enq.ready && fire genROReg(txfifo.io.deq.bits, "out_bits") genROReg(txfifo.io.deq.valid, "out_valid") From 8c14ddc75a530b3f91ef07024966ba883f54719c Mon Sep 17 00:00:00 2001 From: Lux Date: Tue, 21 Oct 2025 14:22:11 -0700 Subject: [PATCH 07/11] add: enhance spike flow --- software/embench/run_all_spike.sh | 20 +++++++ software/embench/scripts/draw_bar.py | 85 +++++++++++++++++++++++++++ software/embench/scripts/parse_log.py | 45 ++++++++++++++ 3 files changed, 150 insertions(+) create mode 100755 software/embench/run_all_spike.sh create mode 100644 software/embench/scripts/draw_bar.py create mode 100644 software/embench/scripts/parse_log.py diff --git a/software/embench/run_all_spike.sh b/software/embench/run_all_spike.sh new file mode 100755 index 0000000000..4265e94a5f --- /dev/null +++ b/software/embench/run_all_spike.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash +set -e + +OUTPUT_DIR=$(pwd)/logs +RESULTS_DIR=$(pwd)/results +SCRIPTS_DIR=$(pwd)/scripts + +mkdir -p $OUTPUT_DIR +mkdir -p $RESULTS_DIR + +bmarks=("aha-mont64" "crc32" "cubic" "edn" "huffbench" + "matmult-int" "minver" "nbody" "nettle-aes" + "nettle-sha256" "nsichneu" "picojpeg" + "qrduino" "sglib-combined" "slre" "st" + "statemate" "ud" "wikisort") +for bmark in "${bmarks[@]}" +do + spike -l build/$bmark 2>$OUTPUT_DIR/$bmark.log + python3 $SCRIPTS_DIR/parse_log.py $OUTPUT_DIR/$bmark.log > $RESULTS_DIR/$bmark.txt +done \ No newline at end of file diff --git a/software/embench/scripts/draw_bar.py b/software/embench/scripts/draw_bar.py new file mode 100644 index 0000000000..d8e52a4703 --- /dev/null +++ b/software/embench/scripts/draw_bar.py @@ -0,0 +1,85 @@ +#!/usr/bin/env python3 +""" +Generate a stacked bar chart summarising control-flow instruction counts per benchmark. +""" + +import re +from pathlib import Path + +import matplotlib.pyplot as plt + + +LINE_RE = re.compile(r"^(.*?):\s+(\d+)\s*$") + + +def parse_counts(path: Path) -> dict[str, int]: + data: dict[str, int] = {} + for raw_line in path.read_text().splitlines(): + match = LINE_RE.match(raw_line) + if not match: + continue + key = match.group(1).strip().lower() + value = int(match.group(2)) + data[key] = value + required_keys = {"total control flow change counts", "branch counts", "ij counts", "uj counts"} + missing = required_keys - data.keys() + if missing: + raise ValueError(f"{path.name} is missing keys: {', '.join(sorted(missing))}") + return data + + +def main() -> None: + script_dir = Path(__file__).resolve().parent + results_dir = script_dir.parent / "results" + result_files = sorted(results_dir.glob("*.txt")) + if not result_files: + raise SystemExit(f"No .txt result files found in {results_dir}") + + benchmarks: list[str] = [] + branch_pct: list[float] = [] + ij_pct: list[float] = [] + uj_pct: list[float] = [] + + for result_file in result_files: + counts = parse_counts(result_file) + branch = counts["branch counts"] + ij = counts["ij counts"] + uj = counts["uj counts"] + total = branch + ij + uj + if total == 0: + raise ValueError(f"{result_file.name} reports zero aggregated control-flow counts") + benchmarks.append(result_file.stem) + branch_pct.append((branch / total) * 100.0) + ij_pct.append((ij / total) * 100.0) + uj_pct.append((uj / total) * 100.0) + + indices = range(len(benchmarks)) + branch_array = branch_pct + ij_array = ij_pct + uj_array = uj_pct + + plt.rc('font', size = 14) + fig, ax = plt.subplots(figsize=(max(6, len(benchmarks) * 0.5), 6)) + + ax.bar(indices, branch_array, label="Branch") + ax.bar(indices, ij_array, bottom=branch_array, label="Inferable Jumps") + cumulative = [b + i for b, i in zip(branch_array, ij_array)] + ax.bar(indices, uj_array, bottom=cumulative, label="Uninferable Jumps") + + ax.set_xticks(list(indices)) + ax.set_xticklabels(benchmarks, rotation=45, ha="right") + ax.set_ylabel("Percentage of control-flow instructions") + ax.set_title("Control-flow instruction breakdown per benchmark") + ax.set_ylim(0, 100) + ax.legend() + ax.margins(x=0.01) + fig.tight_layout() + + output_path = results_dir / "control_flow_counts.png" + fig.savefig(output_path, dpi=300) + plt.close(fig) + print(f"Saved stacked bar chart to {output_path}") + + +if __name__ == "__main__": + main() diff --git a/software/embench/scripts/parse_log.py b/software/embench/scripts/parse_log.py new file mode 100644 index 0000000000..650b60be9a --- /dev/null +++ b/software/embench/scripts/parse_log.py @@ -0,0 +1,45 @@ +# first arg is the log file +import re +import sys + +BRANCH_OPCODES = ["beq", "bge", "bgeu", "blt", "bltu", "bne", "beqz", "bnez", + "bgez", "blez", "bltz", "bgtz", "bgt", "ble", "bgtu", "bleu", + "c.beqz", "c.bnez", "c.bltz", "c.bgez"] +IJ_OPCODES = ["jal", "j", "call", "tail", "c.j", "c.jal"] +UJ_OPCODES = ["jalr", "jr", "c.jr", "c.jalr", "ret"] + +# example line: +# core 0: 0x0000000080000000 (0x00004081) c.li ra, 0 +# extract PC and opcode +pattern = r'core\s+0:\s+0x([0-9a-fA-F]+)\s+\((0x[0-9a-fA-F]+)\)\s+([a-zA-Z0-9_.]+)\s*(.*)' + + +log_file = sys.argv[1] + +with open(log_file, 'r') as f: + lines = f.readlines() + + +total_control_flow_change_counts = 0 +branch_counts = 0 +ij_counts = 0 +uj_counts = 0 + +for line in lines: + match = re.match(pattern, line) + if match: + pc = match.group(1) + opcode = match.group(3) + # print(f"PC: {pc}, Opcode: {opcode}") + if opcode in BRANCH_OPCODES: + total_control_flow_change_counts += 1 + branch_counts += 1 + elif opcode in IJ_OPCODES: + ij_counts += 1 + elif opcode in UJ_OPCODES: + uj_counts += 1 + +print(f"Total control flow change counts: {total_control_flow_change_counts}") +print(f"Branch counts: {branch_counts}") +print(f"IJ counts: {ij_counts}") +print(f"UJ counts: {uj_counts}") \ No newline at end of file From e8049cce5b6d5a0352392b69d53e789e2648a201 Mon Sep 17 00:00:00 2001 From: Lux Date: Tue, 2 Dec 2025 15:27:56 -0800 Subject: [PATCH 08/11] add: asidlen config fragment --- .../main/scala/config/fragments/TileFragments.scala | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/generators/chipyard/src/main/scala/config/fragments/TileFragments.scala b/generators/chipyard/src/main/scala/config/fragments/TileFragments.scala index da36e52bbe..4b37a76fb4 100644 --- a/generators/chipyard/src/main/scala/config/fragments/TileFragments.scala +++ b/generators/chipyard/src/main/scala/config/fragments/TileFragments.scala @@ -170,3 +170,14 @@ class WithSV48 extends Config((site, here, up) => { tp.tileParams.core.copy(pgLevels = 4))) } }) + +class WithAsidLen(n: Int = 0) extends Config((site, here, up) => { + case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map { + case tp: RocketTileAttachParams => tp.copy(tileParams = tp.tileParams.copy(core = + tp.tileParams.core.copy(asidLen = n))) + // case tp: boom.v3.common.BoomTileAttachParams => tp.copy(tileParams = tp.tileParams.copy(core = + // tp.tileParams.core.copy(nAsidBits = n))) + // case tp: boom.v4.common.BoomTileAttachParams => tp.copy(tileParams = tp.tileParams.copy(core = + // tp.tileParams.core.copy(nAsidBits = n))) + } +}) \ No newline at end of file From de945b15bb9ec820f1b22317bedbbd36763e97e7 Mon Sep 17 00:00:00 2001 From: Lux Date: Tue, 2 Dec 2025 15:28:26 -0800 Subject: [PATCH 09/11] add: tacit 4 firesim io punchthrough --- .../src/main/scala/iobinders/IOBinders.scala | 4 +- .../chip/src/main/scala/TargetConfigs.scala | 19 +++++++ .../src/main/scala/TacitBridge.scala | 55 +++++++++++++++---- 3 files changed, 66 insertions(+), 12 deletions(-) diff --git a/generators/chipyard/src/main/scala/iobinders/IOBinders.scala b/generators/chipyard/src/main/scala/iobinders/IOBinders.scala index b550bdd819..b5629001e9 100644 --- a/generators/chipyard/src/main/scala/iobinders/IOBinders.scala +++ b/generators/chipyard/src/main/scala/iobinders/IOBinders.scala @@ -601,9 +601,9 @@ class WithGCDIOPunchthrough extends OverrideIOBinder({ class WithTraceSinkRawBytePunchthrough extends OverrideIOBinder({ (system: CanHaveTraceSinkRawByte) => { - val tacit_byte_ports = system.tacit_bytes.map { case s => + val tacit_byte_ports = system.tacit_bytes.zipWithIndex.map { case (s, i) => // a seq of decoupled bytes - val tacit_byte = IO(new TraceSinkRawByteBundle) + val tacit_byte = IO(new TraceSinkRawByteBundle).suggestName(s"tacit_byte_${i}") tacit_byte <> s TraceSinkRawBytePort(() => tacit_byte) } diff --git a/generators/firechip/chip/src/main/scala/TargetConfigs.scala b/generators/firechip/chip/src/main/scala/TargetConfigs.scala index 9c396607f6..34de3a5985 100644 --- a/generators/firechip/chip/src/main/scala/TargetConfigs.scala +++ b/generators/firechip/chip/src/main/scala/TargetConfigs.scala @@ -361,3 +361,22 @@ class FireSimRocketTacitConfig extends Config( new WithDefaultFireSimBridges ++ new WithFireSimConfigTweaks++ new chipyard.TacitRocketRawByteConfig) + +class FireSimDualRocketTacitConfig extends Config( + new WithTacitBridge ++ + new WithDefaultFireSimBridges ++ + new WithFireSimConfigTweaks++ + new chipyard.TacitDualRocketRawByteConfig) + +class FireSimRocketTacitNICConfig extends Config( + new WithNIC ++ + new WithTacitBridge ++ + new WithDefaultFireSimBridges ++ + new WithFireSimConfigTweaks++ + new chipyard.TacitRocketRawByteConfig) + +class FireSimRocketTacitPrefetchConfig extends Config( + new WithTacitBridge ++ + new WithDefaultFireSimBridges ++ + new WithFireSimConfigTweaks++ + new chipyard.TacitRocketRawBytePrefetchConfig) \ No newline at end of file diff --git a/generators/firechip/goldengateimplementations/src/main/scala/TacitBridge.scala b/generators/firechip/goldengateimplementations/src/main/scala/TacitBridge.scala index 6f873ce12d..1100352c2a 100644 --- a/generators/firechip/goldengateimplementations/src/main/scala/TacitBridge.scala +++ b/generators/firechip/goldengateimplementations/src/main/scala/TacitBridge.scala @@ -12,13 +12,42 @@ import firesim.lib.bridgeutils._ import firechip.bridgeinterfaces._ -class TacitBridgeModule(key: TraceRawByteKey)(implicit p: Parameters) extends BridgeModule[HostPortIO[TraceRawByteBridgeTargetIO]]()(p) { +// copied from testchipip.serdes.SerialWidthAggregator +class SerialWidthAggregator(narrowW: Int, wideW: Int) extends Module { + require(wideW > narrowW) + require(wideW % narrowW == 0) + val io = IO(new Bundle { + val narrow = Flipped(Decoupled(UInt(narrowW.W))) + val wide = Decoupled(UInt(wideW.W)) + }) + + val beats = wideW / narrowW + + val narrow_beats = RegInit(0.U(log2Ceil(beats).W)) + val narrow_last_beat = narrow_beats === (beats-1).U + val narrow_data = Reg(Vec(beats-1, UInt(narrowW.W))) + + io.narrow.ready := Mux(narrow_last_beat, io.wide.ready, true.B) + when (io.narrow.fire) { + narrow_beats := Mux(narrow_last_beat, 0.U, narrow_beats + 1.U) + when (!narrow_last_beat) { narrow_data(narrow_beats) := io.narrow.bits } + } + io.wide.valid := narrow_last_beat && io.narrow.valid + io.wide.bits := Cat(io.narrow.bits, narrow_data.asUInt) +} + +class TacitBridgeModule(key: TraceRawByteKey)(implicit p: Parameters) + extends BridgeModule[HostPortIO[TraceRawByteBridgeTargetIO]]()(p) + with StreamToHostCPU { + + val toHostCPUQueueDepth = 6144 lazy val module = new BridgeModuleImp(this) { val io = IO(new WidgetIO()) val hPort = IO(HostPort(new TraceRawByteBridgeTargetIO)) - val txfifo = Module(new Queue(UInt(8.W), 128)) + val aggregator = Module(new SerialWidthAggregator(8, BridgeStreamConstants.streamWidthBits)) + val txfifo = Module(new Queue(UInt(BridgeStreamConstants.streamWidthBits.W), 3072)) val target = hPort.hBits.byte @@ -32,19 +61,25 @@ class TacitBridgeModule(key: TraceRawByteKey)(implicit p: Parameters) extends Br hPort.toHost.hReady := fire hPort.fromHost.hValid := fire - txfifo.io.enq.bits := target.out.bits - txfifo.io.enq.valid := target.out.valid && fire - target.out.ready := txfifo.io.enq.ready && fire - - genROReg(txfifo.io.deq.bits, "out_bits") - genROReg(txfifo.io.deq.valid, "out_valid") + aggregator.io.narrow.bits := target.out.bits + aggregator.io.narrow.valid := target.out.valid && fire + target.out.ready := aggregator.io.narrow.ready && fire - Pulsify(genWORegInit(txfifo.io.deq.ready, "out_ready", false.B), pulseLength = 1) + txfifo.io.enq <> aggregator.io.wide + streamEnq <> txfifo.io.deq genCRFile() override def genHeader(base: BigInt, memoryRegions: Map[String, BigInt], sb: StringBuilder): Unit = { - genConstructor(base, sb, "tacit_t", "tacit") + genConstructor( + base, + sb, + "tacit_t", + "tacit", Seq( + UInt32(toHostStreamIdx), + UInt32(toHostCPUQueueDepth), + ), + hasStreams = true) } } } \ No newline at end of file From 1f1a2ae9ae040c35bff4437d9abc47d1c5d48db6 Mon Sep 17 00:00:00 2001 From: Lux Date: Tue, 2 Dec 2025 15:28:55 -0800 Subject: [PATCH 10/11] feat: switch to streaming engine interface --- .../bridgestubs/src/main/cc/bridges/tacit.cc | 128 ++++++++++++++---- .../bridgestubs/src/main/cc/bridges/tacit.h | 25 ++-- 2 files changed, 113 insertions(+), 40 deletions(-) diff --git a/generators/firechip/bridgestubs/src/main/cc/bridges/tacit.cc b/generators/firechip/bridgestubs/src/main/cc/bridges/tacit.cc index 8529d3093f..cce575aa41 100644 --- a/generators/firechip/bridgestubs/src/main/cc/bridges/tacit.cc +++ b/generators/firechip/bridgestubs/src/main/cc/bridges/tacit.cc @@ -8,6 +8,10 @@ #include #include +#include +#include +#include +#include // #define DEBUG @@ -15,22 +19,72 @@ char tacit_t::KIND; class tacit_handler_impl final : public tacit_handler { public: - tacit_handler_impl(int tacitno, int tacitlogfd) { - this->tacitlogfd = tacitlogfd; - } + tacit_handler_impl(int tacitno, int tacitlogfd); + ~tacit_handler_impl() override; + protected: int tacitlogfd; + static constexpr size_t BUFFER_SIZE = 4096; + std::array buffer{}; + size_t buffered_bytes = 0; void put(uint8_t data) override; + void flush_buffer(); }; +static void fatal_io_error(int fd, const char *operation) { + fprintf(stderr, + "TACIT log fd %d: failed to %s: %s\n", + fd, + operation, + strerror(errno)); + abort(); +} + +tacit_handler_impl::tacit_handler_impl(int tacitno, int tacitlogfd) { + (void)tacitno; + this->tacitlogfd = tacitlogfd; +} + +tacit_handler_impl::~tacit_handler_impl() { + if (buffered_bytes) { + flush_buffer(); + } + while (::close(tacitlogfd) == -1) { + if (errno == EINTR) { + continue; + } + fatal_io_error(tacitlogfd, "close"); + } +} + void tacit_handler_impl::put(uint8_t data) { - write(tacitlogfd, &data, 1); + buffer[buffered_bytes++] = data; + if (buffered_bytes == BUFFER_SIZE) { + flush_buffer(); + } #ifdef DEBUG fprintf(stderr, "TACIT%d: %02x\n", tacitlogfd, data); #endif } +void tacit_handler_impl::flush_buffer() { + size_t offset = 0; + while (offset < buffered_bytes) { + ssize_t bytes_written = + ::write(tacitlogfd, buffer.data() + offset, buffered_bytes - offset); + if (bytes_written > 0) { + offset += static_cast(bytes_written); + continue; + } + if (bytes_written == -1 && errno == EINTR) { + continue; + } + fatal_io_error(tacitlogfd, "write"); + } + buffered_bytes = 0; +} + static std::unique_ptr create_handler(const std::vector &args, int tacitno) { // open a new file for dumping the bytes @@ -45,36 +99,54 @@ create_handler(const std::vector &args, int tacitno) { } tacit_t::tacit_t(simif_t &simif, - const TACITBRIDGEMODULE_struct &mmio_addrs, + StreamEngine &stream, int tacitno, - const std::vector &args) - : bridge_driver_t(simif, &KIND), mmio_addrs(mmio_addrs), - handler(create_handler(args, tacitno)) {} + const std::vector &args, + int stream_idx, + int stream_depth) + : streaming_bridge_driver_t(simif, stream, &KIND), + handler(create_handler(args, tacitno)), + stream_idx(stream_idx), + stream_depth(stream_depth) {} tacit_t::~tacit_t() = default; -void tacit_t::recv() { - data.out.valid = read(mmio_addrs.out_valid); - if (data.out.valid) { - data.out.bits = read(mmio_addrs.out_bits); - } +void tacit_t::tick() { + drain_stream(STREAM_WIDTH_BYTES); } -void tacit_t::send() { - if (data.out.fire()) { - write(mmio_addrs.out_ready, data.out.ready); - } +void tacit_t::finish() { + pull_flush(stream_idx); + drain_stream(0); + handler->flush_buffer(); } -void tacit_t::tick() { - data.out.ready = true; - do { - this->recv(); - // data serves as an intermediate buffer - // between the bridge and the handler - if (data.out.fire()) { - handler->put(data.out.bits); +void tacit_t::drain_stream(size_t minimum_batch_bytes) { + const size_t max_batch_bytes = + static_cast(stream_depth) * STREAM_WIDTH_BYTES; + if (!handler || stream_depth == 0 || max_batch_bytes == 0) { + return; + } + + page_aligned_sized_array(outbuf, STREAM_WIDTH_BYTES * stream_depth); + + size_t min_bytes = minimum_batch_bytes; + while (true) { + const size_t bytes_received = + pull(stream_idx, outbuf, max_batch_bytes, min_bytes); + if (bytes_received == 0) { + break; } - this->send(); - } while (data.out.fire()); -} \ No newline at end of file + + auto *byte_buf = reinterpret_cast(outbuf); + for (size_t i = 0; i < bytes_received; ++i) { + handler->put(byte_buf[i]); + } + + if (bytes_received < max_batch_bytes && min_bytes == 0) { + break; + } + + min_bytes = 0; + } +} diff --git a/generators/firechip/bridgestubs/src/main/cc/bridges/tacit.h b/generators/firechip/bridgestubs/src/main/cc/bridges/tacit.h index 829e815a89..8e83f78f21 100644 --- a/generators/firechip/bridgestubs/src/main/cc/bridges/tacit.h +++ b/generators/firechip/bridgestubs/src/main/cc/bridges/tacit.h @@ -3,7 +3,6 @@ #ifndef __TACITBRIDGE_H #define __TACITBRIDGE_H -#include "bridges/serial_data.h" #include "core/bridge_driver.h" #include @@ -13,6 +12,8 @@ #include #include +class StreamEngine; + /** * Structure carrying the addresses of all fixed MMIO ports. * @@ -20,40 +21,40 @@ * the target configuration. */ struct TACITBRIDGEMODULE_struct { - uint64_t out_bits; - uint64_t out_valid; - uint64_t out_ready; }; class tacit_handler { public: virtual ~tacit_handler() = default; virtual void put(uint8_t data) = 0; + virtual void flush_buffer() = 0; }; -class tacit_t final : public bridge_driver_t { +class tacit_t final : public streaming_bridge_driver_t { public: /// The identifier for the bridge type used for casts. static char KIND; /// Creates a bridge which interacts with standard streams or PTY. tacit_t(simif_t &simif, - const TACITBRIDGEMODULE_struct &mmio_addrs, - int tacitno, - const std::vector &args); + StreamEngine &stream, + int tacitno, + const std::vector &args, + int stream_idx, + int stream_depth); ~tacit_t() override; void tick() override; + void finish() override; private: - const TACITBRIDGEMODULE_struct mmio_addrs; std::unique_ptr handler; - serial_data_t data; + const int stream_idx; + const int stream_depth; - void recv(); - void send(); + void drain_stream(size_t minimum_batch_bytes); }; #endif // __TACITBRIDGE_H From 5b6d050b8cfc68b455ec9235361931e5371295db Mon Sep 17 00:00:00 2001 From: Lux Date: Tue, 2 Dec 2025 15:31:12 -0800 Subject: [PATCH 11/11] add: common ignore for python --- software/embench/.gitignore | 217 ++++++++++++++++++++++++++++++++++++ 1 file changed, 217 insertions(+) diff --git a/software/embench/.gitignore b/software/embench/.gitignore index 378eac25d3..4265d2f494 100644 --- a/software/embench/.gitignore +++ b/software/embench/.gitignore @@ -1 +1,218 @@ build + +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[codz] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py.cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +# Pipfile.lock + +# UV +# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# uv.lock + +# poetry +# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control +# poetry.lock +# poetry.toml + +# pdm +# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. +# pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python. +# https://pdm-project.org/en/latest/usage/project/#working-with-version-control +# pdm.lock +# pdm.toml +.pdm-python +.pdm-build/ + +# pixi +# Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control. +# pixi.lock +# Pixi creates a virtual environment in the .pixi directory, just like venv module creates one +# in the .venv directory. It is recommended not to include this directory in version control. +.pixi + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# Redis +*.rdb +*.aof +*.pid + +# RabbitMQ +mnesia/ +rabbitmq/ +rabbitmq-data/ + +# ActiveMQ +activemq-data/ + +# SageMath parsed files +*.sage.py + +# Environments +.env +.envrc +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# PyCharm +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +# .idea/ + +# Abstra +# Abstra is an AI-powered process automation framework. +# Ignore directories containing user credentials, local state, and settings. +# Learn more at https://abstra.io/docs +.abstra/ + +# Visual Studio Code +# Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore +# that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore +# and can be added to the global gitignore or merged into this file. However, if you prefer, +# you could uncomment the following to ignore the entire vscode folder +# .vscode/ + +# Ruff stuff: +.ruff_cache/ + +# PyPI configuration file +.pypirc + +# Marimo +marimo/_static/ +marimo/_lsp/ +__marimo__/ + +# Streamlit +.streamlit/secrets.toml \ No newline at end of file