diff --git a/deploy/sample-backup-configs/sample_config_hwdb.yaml b/deploy/sample-backup-configs/sample_config_hwdb.yaml index 7b550d0d..d232726d 100644 --- a/deploy/sample-backup-configs/sample_config_hwdb.yaml +++ b/deploy/sample-backup-configs/sample_config_hwdb.yaml @@ -11,12 +11,12 @@ # DOCREF START: Example HWDB Entry firesim_boom_singlecore_nic_l2_llc4mb_ddr3: - agfi: agfi-03332c26b0bfef9cf + agfi: agfi-0d721e90da766a06a deploy_quintuplet_override: null custom_runtime_config: null # DOCREF END: Example HWDB Entry firesim_boom_singlecore_no_nic_l2_llc4mb_ddr3: - agfi: agfi-0b01cb001eb3db84b + agfi: agfi-0d851f557081a438e deploy_quintuplet_override: null custom_runtime_config: null firesim_gemmini_printf_rocket_singlecore_no_nic: @@ -28,11 +28,11 @@ firesim_gemmini_rocket_singlecore_no_nic: deploy_quintuplet_override: null custom_runtime_config: null firesim_rocket_quadcore_nic_l2_llc4mb_ddr3: - agfi: agfi-0d37db88b8d6a9ea9 + agfi: agfi-09c450553a29c35a6 deploy_quintuplet_override: null custom_runtime_config: null firesim_rocket_quadcore_no_nic_l2_llc4mb_ddr3: - agfi: agfi-05ad3a0d05b659fe8 + agfi: agfi-0f48d70c4d1f9a228 deploy_quintuplet_override: null custom_runtime_config: null firesim_rocket_singlecore_no_nic_l2_lbp: @@ -52,11 +52,11 @@ firesim_rocket_singlecore_sha3_no_nic_l2_llc4mb_ddr3_printf: deploy_quintuplet_override: null custom_runtime_config: null firesim_supernode_rocket_singlecore_nic_l2_lbp: - agfi: agfi-0541dd890b2b59bd5 + agfi: agfi-02b5300c4b1808434 deploy_quintuplet_override: null custom_runtime_config: null vitis_firesim_rocket_singlecore_no_nic: - bitstream_tar: https://raw.githubusercontent.com/firesim/firesim-public-bitstreams/f17bff0afb96d278c3cd199a72d9317b1bebbb2a/vitis/vitis_firesim_rocket_singlecore_no_nic.tar.gz + bitstream_tar: https://raw.githubusercontent.com/firesim/firesim-public-bitstreams/d967f09bdd1b673dba274233e5027583f3c97347/vitis/vitis_firesim_rocket_singlecore_no_nic.tar.gz deploy_quintuplet_override: null custom_runtime_config: null vitis_firesim_gemmini_rocket_singlecore_no_nic: @@ -64,26 +64,26 @@ vitis_firesim_gemmini_rocket_singlecore_no_nic: deploy_quintuplet_override: null custom_runtime_config: null alveo_u250_firesim_rocket_singlecore_no_nic: - bitstream_tar: https://raw.githubusercontent.com/firesim/firesim-public-bitstreams/9543b082437e3ec2c3ecc863da4e06a19597e5e6/xilinx_alveo_u250/alveo_u250_firesim_rocket_singlecore_no_nic.tar.gz + bitstream_tar: https://raw.githubusercontent.com/firesim/firesim-public-bitstreams/2c884a48426bfcdcae9ed037169ee2e7d31f22e5/xilinx_alveo_u250/alveo_u250_firesim_rocket_singlecore_no_nic.tar.gz deploy_quintuplet_override: null custom_runtime_config: null alveo_u250_firesim_gemmini_rocket_singlecore_no_nic: - bitstream_tar: https://raw.githubusercontent.com/firesim/firesim-public-bitstreams/933a8726645fd7241f019463df86f3d117a7d714/xilinx_alveo_u250/alveo_u250_firesim_gemmini_rocket_singlecore_no_nic.tar.gz + bitstream_tar: https://raw.githubusercontent.com/firesim/firesim-public-bitstreams/3322efdde5e5ff131e39e7054c45c2c346f1c6ea/xilinx_alveo_u250/alveo_u250_firesim_gemmini_rocket_singlecore_no_nic.tar.gz deploy_quintuplet_override: null custom_runtime_config: null alveo_u200_firesim_rocket_singlecore_no_nic: - bitstream_tar: https://raw.githubusercontent.com/firesim/firesim-public-bitstreams/0d91a839113ab048abfed7e79fe2b0d1097f2807/xilinx_alveo_u200/alveo_u200_firesim_rocket_singlecore_no_nic.tar.gz + bitstream_tar: https://raw.githubusercontent.com/firesim/firesim-public-bitstreams/5c779585c0b2fb79a4ce2f9fdf244160077b5885/xilinx_alveo_u200/alveo_u200_firesim_rocket_singlecore_no_nic.tar.gz deploy_quintuplet_override: null custom_runtime_config: null alveo_u280_firesim_rocket_singlecore_no_nic: - bitstream_tar: https://raw.githubusercontent.com/firesim/firesim-public-bitstreams/a8b9ffaeb4d243292c04eb13857a7daa8ac6d897/xilinx_alveo_u280/alveo_u280_firesim_rocket_singlecore_no_nic.tar.gz + bitstream_tar: https://raw.githubusercontent.com/firesim/firesim-public-bitstreams/2e27a107fb86ea050db6dbb4afd22a4730b92974/xilinx_alveo_u280/alveo_u280_firesim_rocket_singlecore_no_nic.tar.gz deploy_quintuplet_override: null custom_runtime_config: null xilinx_vcu118_firesim_rocket_singlecore_4GB_no_nic: - bitstream_tar: https://raw.githubusercontent.com/firesim/firesim-public-bitstreams/48934d5a7b6b5869b446378656cf61824961471e/xilinx_vcu118/xilinx_vcu118_firesim_rocket_singlecore_4GB_no_nic.tar.gz + bitstream_tar: https://raw.githubusercontent.com/firesim/firesim-public-bitstreams/64970aad241c29d05c000b8c6516a98b37ba2517/xilinx_vcu118/xilinx_vcu118_firesim_rocket_singlecore_4GB_no_nic.tar.gz deploy_quintuplet_override: null custom_runtime_config: null nitefury_firesim_rocket_singlecore_no_nic: - bitstream_tar: https://raw.githubusercontent.com/firesim/firesim-public-bitstreams/f228aa51f95c3a7022444516051fd2fe346cc48d/rhsresearch_nitefury_ii/nitefury_firesim_rocket_singlecore_no_nic.tar.gz + bitstream_tar: https://raw.githubusercontent.com/firesim/firesim-public-bitstreams/2901ab775feee3565975075733a340af01db8921/rhsresearch_nitefury_ii/nitefury_firesim_rocket_singlecore_no_nic.tar.gz deploy_quintuplet_override: null custom_runtime_config: null \ No newline at end of file diff --git a/sim/firesim-lib/src/main/cc/bridges/tracerv.cc b/sim/firesim-lib/src/main/cc/bridges/tracerv.cc index dc81b904..46fb722e 100644 --- a/sim/firesim-lib/src/main/cc/bridges/tracerv.cc +++ b/sim/firesim-lib/src/main/cc/bridges/tracerv.cc @@ -35,9 +35,6 @@ tracerv_t::tracerv_t(simif_t &sim, : streaming_bridge_driver_t(sim, stream, &KIND), mmio_addrs(mmio_addrs), stream_idx(stream_idx), stream_depth(stream_depth), max_core_ipc(max_core_ipc), clock_info(clock_info) { - // Biancolin: move into elaboration - assert(this->max_core_ipc <= 7 && - "TracerV only supports cores with a maximum IPC <= 7"); const char *tracefilename = nullptr; const char *dwarf_file_name = nullptr; this->tracefile = nullptr; @@ -272,8 +269,6 @@ void tracerv_t::serialize( OUTBUF[i + 0], q, OUTBUF[i + q + 1] & (~valid_mask)); - } else { - break; } } } diff --git a/sim/firesim-lib/src/main/cc/bridges/tracerv.h b/sim/firesim-lib/src/main/cc/bridges/tracerv.h index 33989c96..db8e68f1 100644 --- a/sim/firesim-lib/src/main/cc/bridges/tracerv.h +++ b/sim/firesim-lib/src/main/cc/bridges/tracerv.h @@ -5,7 +5,6 @@ #include "core/bridge_driver.h" #include "core/clock_info.h" #include -#include #include class TraceTracker; diff --git a/sim/firesim-lib/src/main/scala/bridges/TracerVBridge.scala b/sim/firesim-lib/src/main/scala/bridges/TracerVBridge.scala index 4a0353e5..391d548d 100644 --- a/sim/firesim-lib/src/main/scala/bridges/TracerVBridge.scala +++ b/sim/firesim-lib/src/main/scala/bridges/TracerVBridge.scala @@ -14,20 +14,19 @@ import midas.widgets._ class TracerVTargetIO(widths: TraceBundleWidths) extends Bundle { val trace = Input(new SerializableTileTraceIO(widths)) val triggerCredit = Output(Bool()) - val triggerDebit = Output(Bool()) + val triggerDebit = Output(Bool()) } -/** - * Target-side module for the TracerV Bridge. + +/** Target-side module for the TracerV Bridge. * - * @param insnWidths A case class containing the widths of configurable-length - * fields in the trace interface. + * @param insnWidths + * A case class containing the widths of configurable-length fields in the trace interface. * - * @param numInsns The number of instructions captured in a single a cycle - * (generally, the commit width of the pipeline) + * @param numInsns + * The number of instructions captured in a single a cycle (generally, the commit width of the pipeline) * - * Warning: If you're not going to use the companion object to instantiate - * this bridge you must call [[TracerVBridge.generateTriggerAnnotations] _in - * the parent module_. + * Warning: If you're not going to use the companion object to instantiate this bridge you must call + * [[TracerVBridge.generateTriggerAnnotations] _in the parent module_. */ class TracerVBridge(widths: TraceBundleWidths) extends BlackBox @@ -66,7 +65,7 @@ object TracerVBridge { tracerv } - def apply(tracedInsns: TileTraceIO)(implicit p:Parameters): TracerVBridge = { + def apply(tracedInsns: TileTraceIO)(implicit p: Parameters): TracerVBridge = { val tracerv = withClockAndReset(tracedInsns.clock, tracedInsns.reset) { TracerVBridge(tracedInsns.traceBundleWidths) } @@ -87,75 +86,75 @@ class TracerVBridgeModule(key: TraceBundleWidths)(implicit p: Parameters) val io = IO(new WidgetIO) val hPort = IO(HostPort(new TracerVTargetIO(key))) - // Mask off valid committed instructions when under reset val traces = hPort.hBits.trace.trace.insns.map({ unmasked => val masked = WireDefault(unmasked) masked.valid := unmasked.valid && !hPort.hBits.trace.reset.asBool masked }) - private val pcWidth = traces.map(_.iaddr.getWidth).max + private val pcWidth = traces.map(_.iaddr.getWidth).max private val insnWidth = traces.map(_.insn.getWidth).max - val cycleCountWidth = 64 + val cycleCountWidth = 64 // Set after trigger-dependent memory-mapped registers have been set, to // prevent spurious credits - val initDone = genWORegInit(Wire(Bool()), "initDone", false.B) + val initDone = genWORegInit(Wire(Bool()), "initDone", false.B) // When unset, diables token capture to improve FMR, while still enabling the // use of TracerV-based triggers - val traceEnable = genWORegInit(Wire(Bool()), "traceEnable", true.B) + val traceEnable = genWORegInit(Wire(Bool()), "traceEnable", true.B) //Program Counter trigger value can be configured externally val hostTriggerPCWidthOffset = pcWidth - p(CtrlNastiKey).dataBits - val hostTriggerPCLowWidth = if (hostTriggerPCWidthOffset > 0) p(CtrlNastiKey).dataBits else pcWidth - val hostTriggerPCHighWidth = if (hostTriggerPCWidthOffset > 0) hostTriggerPCWidthOffset else 0 + val hostTriggerPCLowWidth = if (hostTriggerPCWidthOffset > 0) p(CtrlNastiKey).dataBits else pcWidth + val hostTriggerPCHighWidth = if (hostTriggerPCWidthOffset > 0) hostTriggerPCWidthOffset else 0 val hostTriggerPCStartHigh = RegInit(0.U(hostTriggerPCHighWidth.W)) - val hostTriggerPCStartLow = RegInit(0.U(hostTriggerPCLowWidth.W)) + val hostTriggerPCStartLow = RegInit(0.U(hostTriggerPCLowWidth.W)) attach(hostTriggerPCStartHigh, "hostTriggerPCStartHigh", WriteOnly) attach(hostTriggerPCStartLow, "hostTriggerPCStartLow", WriteOnly) - val hostTriggerPCStart = Cat(hostTriggerPCStartHigh, hostTriggerPCStartLow) - val triggerPCStart = RegInit(0.U(pcWidth.W)) + val hostTriggerPCStart = Cat(hostTriggerPCStartHigh, hostTriggerPCStartLow) + val triggerPCStart = RegInit(0.U(pcWidth.W)) triggerPCStart := hostTriggerPCStart val hostTriggerPCEndHigh = RegInit(0.U(hostTriggerPCHighWidth.W)) - val hostTriggerPCEndLow = RegInit(0.U(hostTriggerPCLowWidth.W)) + val hostTriggerPCEndLow = RegInit(0.U(hostTriggerPCLowWidth.W)) attach(hostTriggerPCEndHigh, "hostTriggerPCEndHigh", WriteOnly) attach(hostTriggerPCEndLow, "hostTriggerPCEndLow", WriteOnly) - val hostTriggerPCEnd = Cat(hostTriggerPCEndHigh, hostTriggerPCEndLow) - val triggerPCEnd = RegInit(0.U(pcWidth.W)) + val hostTriggerPCEnd = Cat(hostTriggerPCEndHigh, hostTriggerPCEndLow) + val triggerPCEnd = RegInit(0.U(pcWidth.W)) triggerPCEnd := hostTriggerPCEnd //Cycle count trigger val hostTriggerCycleCountWidthOffset = 64 - p(CtrlNastiKey).dataBits - val hostTriggerCycleCountLowWidth = if (hostTriggerCycleCountWidthOffset > 0) p(CtrlNastiKey).dataBits else 64 - val hostTriggerCycleCountHighWidth = if (hostTriggerCycleCountWidthOffset > 0) hostTriggerCycleCountWidthOffset else 0 + val hostTriggerCycleCountLowWidth = if (hostTriggerCycleCountWidthOffset > 0) p(CtrlNastiKey).dataBits else 64 + val hostTriggerCycleCountHighWidth = + if (hostTriggerCycleCountWidthOffset > 0) hostTriggerCycleCountWidthOffset else 0 val hostTriggerCycleCountStartHigh = RegInit(0.U(hostTriggerCycleCountHighWidth.W)) - val hostTriggerCycleCountStartLow = RegInit(0.U(hostTriggerCycleCountLowWidth.W)) + val hostTriggerCycleCountStartLow = RegInit(0.U(hostTriggerCycleCountLowWidth.W)) attach(hostTriggerCycleCountStartHigh, "hostTriggerCycleCountStartHigh", WriteOnly) attach(hostTriggerCycleCountStartLow, "hostTriggerCycleCountStartLow", WriteOnly) - val hostTriggerCycleCountStart = Cat(hostTriggerCycleCountStartHigh, hostTriggerCycleCountStartLow) - val triggerCycleCountStart = RegInit(0.U(cycleCountWidth.W)) + val hostTriggerCycleCountStart = Cat(hostTriggerCycleCountStartHigh, hostTriggerCycleCountStartLow) + val triggerCycleCountStart = RegInit(0.U(cycleCountWidth.W)) triggerCycleCountStart := hostTriggerCycleCountStart val hostTriggerCycleCountEndHigh = RegInit(0.U(hostTriggerCycleCountHighWidth.W)) - val hostTriggerCycleCountEndLow = RegInit(0.U(hostTriggerCycleCountLowWidth.W)) + val hostTriggerCycleCountEndLow = RegInit(0.U(hostTriggerCycleCountLowWidth.W)) attach(hostTriggerCycleCountEndHigh, "hostTriggerCycleCountEndHigh", WriteOnly) attach(hostTriggerCycleCountEndLow, "hostTriggerCycleCountEndLow", WriteOnly) - val hostTriggerCycleCountEnd = Cat(hostTriggerCycleCountEndHigh, hostTriggerCycleCountEndLow) - val triggerCycleCountEnd = RegInit(0.U(cycleCountWidth.W)) + val hostTriggerCycleCountEnd = Cat(hostTriggerCycleCountEndHigh, hostTriggerCycleCountEndLow) + val triggerCycleCountEnd = RegInit(0.U(cycleCountWidth.W)) triggerCycleCountEnd := hostTriggerCycleCountEnd val trace_cycle_counter = RegInit(0.U(cycleCountWidth.W)) //target instruction type trigger (trigger through target software) //can configure the trigger instruction type externally though simulation driver - val hostTriggerStartInst = RegInit(0.U(insnWidth.W)) + val hostTriggerStartInst = RegInit(0.U(insnWidth.W)) val hostTriggerStartInstMask = RegInit(0.U(insnWidth.W)) attach(hostTriggerStartInst, "hostTriggerStartInst", WriteOnly) attach(hostTriggerStartInstMask, "hostTriggerStartInstMask", WriteOnly) - val hostTriggerEndInst = RegInit(0.U(insnWidth.W)) + val hostTriggerEndInst = RegInit(0.U(insnWidth.W)) val hostTriggerEndInstMask = RegInit(0.U(insnWidth.W)) attach(hostTriggerEndInst, "hostTriggerEndInst", WriteOnly) attach(hostTriggerEndInstMask, "hostTriggerEndInstMask", WriteOnly) @@ -171,10 +170,10 @@ class TracerVBridgeModule(key: TraceBundleWidths)(implicit p: Parameters) val triggerPCValVec = RegInit(VecInit(Seq.fill(traces.length)(false.B))) traces.zipWithIndex.foreach { case (trace, i) => - when (trace.valid) { - when (triggerPCStart === trace.iaddr) { + when(trace.valid) { + when(triggerPCStart === trace.iaddr) { triggerPCValVec(i) := true.B - } .elsewhen ((triggerPCEnd === trace.iaddr) && triggerPCValVec(i)) { + }.elsewhen((triggerPCEnd === trace.iaddr) && triggerPCValVec(i)) { triggerPCValVec(i) := false.B } } @@ -182,36 +181,86 @@ class TracerVBridgeModule(key: TraceBundleWidths)(implicit p: Parameters) val triggerInstValVec = RegInit(VecInit(Seq.fill(traces.length)(false.B))) traces.zipWithIndex.foreach { case (trace, i) => - when (trace.valid) { - when (!((hostTriggerStartInst ^ trace.insn) & hostTriggerStartInstMask).orR) { + when(trace.valid) { + when(!((hostTriggerStartInst ^ trace.insn) & hostTriggerStartInstMask).orR) { triggerInstValVec(i) := true.B - } .elsewhen (!((hostTriggerEndInst ^ trace.insn) & hostTriggerEndInstMask).orR) { + }.elsewhen(!((hostTriggerEndInst ^ trace.insn) & hostTriggerEndInstMask).orR) { triggerInstValVec(i) := false.B } } } - val trigger = MuxLookup(triggerSelector, false.B, Seq( - 0.U -> true.B, - 1.U -> triggerCycleCountVal, - 2.U -> triggerPCValVec.reduce(_ || _), - 3.U -> triggerInstValVec.reduce(_ || _))) + val trigger = MuxLookup( + triggerSelector, + false.B, + Seq( + 0.U -> true.B, + 1.U -> triggerCycleCountVal, + 2.U -> triggerPCValVec.reduce(_ || _), + 3.U -> triggerInstValVec.reduce(_ || _), + ), + ) - val tFireHelper = DecoupledHelper(streamEnq.ready, hPort.toHost.hValid, hPort.fromHost.hReady, initDone) + // the maximum width of a single arm, this is determined by the 512 bit width of a single beat + val armWidth = 7 - val triggerReg = RegEnable(trigger, false.B, tFireHelper.fire()) - hPort.hBits.triggerDebit := !trigger && triggerReg + // divide with a ceiling round, to get the total number of arms + val armCount = (traces.length + armWidth - 1) / armWidth + + // A Seq of Seq which represents each arm of the mux + val allTraceArms = traces.grouped(armWidth).toSeq + + // an intermediate value used to build allStreamBits + val allUintTraces = allTraceArms.map(arm => arm.map((trace => Cat(trace.valid, trace.iaddr).pad(64))).reverse) + + // Literally each arm of the mux, these are directly the bits that get put into the bump + val allStreamBits = + allUintTraces.map(uarm => Cat(uarm :+ trace_cycle_counter.pad(64)).pad(BridgeStreamConstants.streamWidthBits)) + + // Number of bits to use for the counter, the +1 is required because the counter will count 1 past the number of arms + val counterBits = log2Ceil(armCount + 1) + + // This counter acts to select the mux arm + val counter = RegInit(0.U(counterBits.W)) + + // The main mux where the input arms are different possible valid traces, and the output goes to streamEnq + val streamMux = MuxLookup(counter, allStreamBits(0), Seq.tabulate(armCount)(x => x.U -> allStreamBits(x))) + + // a parallel set of arms to a parallel mux, true if any instructions in the arm are valid (OR reduction) + val anyValid = allTraceArms.map(arm => arm.map(trace => trace.valid).reduce((a, b) => (a | b))) + + // all of the valids of the larger indexed arms are OR reduced + val anyValidRemain = + Seq.tabulate(armCount)(idx => (idx until armCount).map(x => anyValid(x)).reduce((a, b) => (a | b))) + val anyValidRemainMux = MuxLookup(counter, false.B, Seq.tabulate(armCount)(x => x.U -> anyValidRemain(x))) + + streamEnq.bits := streamMux + + val maybeFire = !anyValidRemainMux || (counter === (armCount - 1).U) + val maybeEnq = anyValidRemainMux + + val commonPredicates = Seq(hPort.toHost.hValid, hPort.fromHost.hReady, streamEnq.ready, initDone) + val do_enq_helper = DecoupledHelper((Seq(maybeEnq, traceEnable) ++ commonPredicates):_*) + val do_fire_helper = DecoupledHelper((maybeFire +: commonPredicates):_*) + + // Note, if we dequeue a token that wins out over the increment below + when(do_fire_helper.fire()) { + counter := 0.U + }.elsewhen(do_enq_helper.fire()) { + counter := counter + 1.U + } + + streamEnq.valid := do_enq_helper.fire(streamEnq.ready, trigger) + hPort.toHost.hReady := do_fire_helper.fire(hPort.toHost.hValid) + + // Output token (back to hub model) handling. + val triggerReg = RegEnable(trigger, false.B, do_fire_helper.fire()) + hPort.hBits.triggerDebit := !trigger && triggerReg hPort.hBits.triggerCredit := trigger && !triggerReg - val uint_traces = (traces map (trace => Cat(trace.valid, trace.iaddr).pad(64))).reverse - streamEnq.bits := Cat(uint_traces :+ trace_cycle_counter.pad(64)).pad(BridgeStreamConstants.streamWidthBits) + hPort.fromHost.hValid := do_fire_helper.fire(hPort.fromHost.hReady) - hPort.toHost.hReady := tFireHelper.fire(hPort.toHost.hValid) - hPort.fromHost.hValid := tFireHelper.fire(hPort.fromHost.hReady) - - streamEnq.valid := tFireHelper.fire(streamEnq.ready, trigger) && traceEnable - - when (tFireHelper.fire()) { + when(hPort.toHost.fire) { trace_cycle_counter := trace_cycle_counter + 1.U } @@ -219,17 +268,17 @@ class TracerVBridgeModule(key: TraceBundleWidths)(implicit p: Parameters) override def genHeader(base: BigInt, memoryRegions: Map[String, BigInt], sb: StringBuilder): Unit = { genConstructor( - base, - sb, - "tracerv_t", - "tracerv", - Seq( - UInt32(toHostStreamIdx), - UInt32(toHostCPUQueueDepth), - UInt32(traces.size), - Verbatim(clockDomainInfo.toC) - ), - hasStreams = true + base, + sb, + "tracerv_t", + "tracerv", + Seq( + UInt32(toHostStreamIdx), + UInt32(toHostCPUQueueDepth), + UInt32(traces.size), + Verbatim(clockDomainInfo.toC), + ), + hasStreams = true, ) } } diff --git a/sim/src/main/cc/bridges/TracerVModule.cc b/sim/src/main/cc/bridges/TracerVModule.cc index 280e2bb2..777f9e91 100644 --- a/sim/src/main/cc/bridges/TracerVModule.cc +++ b/sim/src/main/cc/bridges/TracerVModule.cc @@ -10,10 +10,12 @@ #include #include -static std::vector get_contiguous(unsigned bits, unsigned total) { +static std::vector get_valids(uint64_t seed, unsigned total) { + assert(total <= 64 && "This test does not support more than 64 IPC"); + std::vector ret; for (unsigned i = 0; i < total; i++) { - const bool value = (i < bits); + const bool value = seed & (1 << i); ret.emplace_back(value); } @@ -168,12 +170,16 @@ public: // calculate what TraverV should output, and save it if (bit[i]) { valid_i.emplace_back(iad[i]); + } else { + // write a magic value to signify an invalid instruction + // this magic value is test only and is not passed to the DUT + valid_i.emplace_back(-1); } } // place instructions onto the vector 7 at a time for (size_t i = 0; i < valid_i.size(); i += 7) { - auto last = std::min(valid_i.size(), i + 7); + const auto last = std::min(valid_i.size(), i + 7); std::vector chunk = std::vector(valid_i.begin() + i, valid_i.begin() + last); expected_pair.emplace_back(std::make_pair(e_cycle, chunk)); @@ -187,10 +193,10 @@ public: for (unsigned test_step = 0, total = get_total_trace_tests(); test_step < total; ++test_step) { - const uint64_t pull = rand_next(tracerv_width + 1); + const uint64_t pull = rand_next(); - auto pull_iaddr = get_iaddrs(test_step, tracerv_width); - auto pull_bits = get_contiguous(pull, tracerv_width); + const auto pull_bits = get_valids(pull, tracerv_width); + const auto pull_iaddr = get_iaddrs(test_step, tracerv_width); load(pull_iaddr, pull_bits); steps(1); @@ -310,7 +316,12 @@ public: assert(insns.size() < 8 && "Internal test error, filtered cannot " "have more than 8 instructions at once"); for (int i = 0; i < insns.size(); i++) { - buffer[i + 1] = insns[i] | tracerv_t::valid_mask; + // valid instruction, or invalid placeholder + if (insns[i] != -1) { + buffer[i + 1] = insns[i] | tracerv_t::valid_mask; + } else { + buffer[i + 1] = 0; + } } // because filtered doesn't contain the instruction value for non @@ -339,7 +350,7 @@ public: /** * Returns the next available random number, modulo limit. */ - uint64_t rand_next(uint64_t limit) { return gen() % limit; } + uint64_t rand_next() { return gen(); } private: unsigned get_total_trace_tests() const { return 128; } diff --git a/sim/src/main/scala/bridges/TracerVModule.scala b/sim/src/main/scala/bridges/TracerVModule.scala index 225e3ad5..d5ca9708 100644 --- a/sim/src/main/scala/bridges/TracerVModule.scala +++ b/sim/src/main/scala/bridges/TracerVModule.scala @@ -34,6 +34,11 @@ class TracerVModuleTestCount7 7 }) +class TracerVModuleTestCount9 + extends Config((site, here, up) => { case TracerVModuleInstructionCount => + 9 + }) + class TracerVModuleTestCount14 extends Config((site, here, up) => { case TracerVModuleInstructionCount => 14 diff --git a/sim/src/test/scala/bridges/TracerVSuite.scala b/sim/src/test/scala/bridges/TracerVSuite.scala index eb5cb8ad..7d386366 100644 --- a/sim/src/test/scala/bridges/TracerVSuite.scala +++ b/sim/src/test/scala/bridges/TracerVSuite.scala @@ -56,9 +56,12 @@ abstract class TracerVTestBase( } } -class TracerVF1TestCount1 extends TracerVTestBase(BaseConfigs.F1, 1); +class TracerVF1TestCount1 extends TracerVTestBase(BaseConfigs.F1, 1); // This test is disabled until FireSim issue #1428 is resolved // class TracerVF1TestCount5 extends TracerVTestBase(BaseConfigs.F1, 5, Some(3), Some("FF0000001C")); // in hex -class TracerVF1TestCount6 extends TracerVTestBase(BaseConfigs.F1, 6, Some(2), Some("3000")); // in hex -class TracerVF1TestCount7 extends TracerVTestBase(BaseConfigs.F1, 7, Some(1), Some("9")); // in decimala -class TracerVVitisTest extends TracerVTestBase(BaseConfigs.Vitis, 7); +class TracerVF1TestCount6 extends TracerVTestBase(BaseConfigs.F1, 6, Some(2), Some("3000")); // in hex +class TracerVF1TestCount7 extends TracerVTestBase(BaseConfigs.F1, 7, Some(1), Some("9")); // in decimal +class TracerVF1TestCount9 extends TracerVTestBase(BaseConfigs.F1, 9); +class TracerVVitisTest extends TracerVTestBase(BaseConfigs.Vitis, 14); +class TracerVF1TestCount14 extends TracerVTestBase(BaseConfigs.F1, 14, Some(1), Some("10")); // in decimal +class TracerVF1TestCount15 extends TracerVTestBase(BaseConfigs.F1, 15, Some(2), Some("4000"));