Revert "Expand TracerV to support more than 7 IPC (#1383)"

This reverts commit 0e77b74a1a.
This commit is contained in:
abejgonzalez 2023-06-01 10:45:42 -07:00
parent cd9a02fb95
commit f7d9e060f0
6 changed files with 82 additions and 144 deletions

View File

@ -35,6 +35,9 @@ tracerv_t::tracerv_t(simif_t &sim,
: streaming_bridge_driver_t(sim, stream, &KIND), mmio_addrs(mmio_addrs), : streaming_bridge_driver_t(sim, stream, &KIND), mmio_addrs(mmio_addrs),
stream_idx(stream_idx), stream_depth(stream_depth), stream_idx(stream_idx), stream_depth(stream_depth),
max_core_ipc(max_core_ipc), clock_info(clock_info) { 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 *tracefilename = nullptr;
const char *dwarf_file_name = nullptr; const char *dwarf_file_name = nullptr;
this->tracefile = nullptr; this->tracefile = nullptr;
@ -271,6 +274,8 @@ void tracerv_t::serialize(
OUTBUF[i + 0], OUTBUF[i + 0],
q, q,
OUTBUF[i + q + 1] & (~valid_mask)); OUTBUF[i + q + 1] & (~valid_mask));
} else {
break;
} }
} }
} }

View File

@ -5,6 +5,7 @@
#include "core/bridge_driver.h" #include "core/bridge_driver.h"
#include "core/clock_info.h" #include "core/clock_info.h"
#include <functional> #include <functional>
#include <iostream>
#include <vector> #include <vector>
class TraceTracker; class TraceTracker;

View File

@ -16,17 +16,18 @@ class TracerVTargetIO(widths: TraceBundleWidths) extends Bundle {
val triggerCredit = Output(Bool()) 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 * @param insnWidths A case class containing the widths of configurable-length
* A case class containing the widths of configurable-length fields in the trace interface. * fields in the trace interface.
* *
* @param numInsns * @param numInsns The number of instructions captured in a single a cycle
* The number of instructions captured in a single a cycle (generally, the commit width of the pipeline) * (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 * Warning: If you're not going to use the companion object to instantiate
* [[TracerVBridge.generateTriggerAnnotations] _in the parent module_. * this bridge you must call [[TracerVBridge.generateTriggerAnnotations] _in
* the parent module_.
*/ */
class TracerVBridge(widths: TraceBundleWidths) class TracerVBridge(widths: TraceBundleWidths)
extends BlackBox extends BlackBox
@ -86,6 +87,7 @@ class TracerVBridgeModule(key: TraceBundleWidths)(implicit p: Parameters)
val io = IO(new WidgetIO) val io = IO(new WidgetIO)
val hPort = IO(HostPort(new TracerVTargetIO(key))) val hPort = IO(HostPort(new TracerVTargetIO(key)))
// Mask off valid committed instructions when under reset // Mask off valid committed instructions when under reset
val traces = hPort.hBits.trace.trace.insns.map({ unmasked => val traces = hPort.hBits.trace.trace.insns.map({ unmasked =>
val masked = WireDefault(unmasked) val masked = WireDefault(unmasked)
@ -126,8 +128,7 @@ class TracerVBridgeModule(key: TraceBundleWidths)(implicit p: Parameters)
//Cycle count trigger //Cycle count trigger
val hostTriggerCycleCountWidthOffset = 64 - p(CtrlNastiKey).dataBits val hostTriggerCycleCountWidthOffset = 64 - p(CtrlNastiKey).dataBits
val hostTriggerCycleCountLowWidth = if (hostTriggerCycleCountWidthOffset > 0) p(CtrlNastiKey).dataBits else 64 val hostTriggerCycleCountLowWidth = if (hostTriggerCycleCountWidthOffset > 0) p(CtrlNastiKey).dataBits else 64
val hostTriggerCycleCountHighWidth = val hostTriggerCycleCountHighWidth = if (hostTriggerCycleCountWidthOffset > 0) hostTriggerCycleCountWidthOffset else 0
if (hostTriggerCycleCountWidthOffset > 0) hostTriggerCycleCountWidthOffset else 0
val hostTriggerCycleCountStartHigh = RegInit(0.U(hostTriggerCycleCountHighWidth.W)) val hostTriggerCycleCountStartHigh = RegInit(0.U(hostTriggerCycleCountHighWidth.W))
val hostTriggerCycleCountStartLow = RegInit(0.U(hostTriggerCycleCountLowWidth.W)) val hostTriggerCycleCountStartLow = RegInit(0.U(hostTriggerCycleCountLowWidth.W))
@ -190,16 +191,11 @@ class TracerVBridgeModule(key: TraceBundleWidths)(implicit p: Parameters)
} }
} }
val trigger = MuxLookup( val trigger = MuxLookup(triggerSelector, false.B, Seq(
triggerSelector,
false.B,
Seq(
0.U -> true.B, 0.U -> true.B,
1.U -> triggerCycleCountVal, 1.U -> triggerCycleCountVal,
2.U -> triggerPCValVec.reduce(_ || _), 2.U -> triggerPCValVec.reduce(_ || _),
3.U -> triggerInstValVec.reduce(_ || _), 3.U -> triggerInstValVec.reduce(_ || _)))
),
)
val tFireHelper = DecoupledHelper(streamEnq.ready, hPort.toHost.hValid, hPort.fromHost.hReady, initDone) val tFireHelper = DecoupledHelper(streamEnq.ready, hPort.toHost.hValid, hPort.fromHost.hReady, initDone)
@ -207,60 +203,15 @@ class TracerVBridgeModule(key: TraceBundleWidths)(implicit p: Parameters)
hPort.hBits.triggerDebit := !trigger && triggerReg hPort.hBits.triggerDebit := !trigger && triggerReg
hPort.hBits.triggerCredit := 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.toHost.hReady := tFireHelper.fire(hPort.toHost.hValid)
hPort.fromHost.hValid := tFireHelper.fire(hPort.fromHost.hReady) hPort.fromHost.hValid := tFireHelper.fire(hPort.fromHost.hReady)
// the maximum width of a single arm, this is determined by the 512 bit width of a single beat streamEnq.valid := tFireHelper.fire(streamEnq.ready, trigger) && traceEnable
val armWidth = 7
// divide with a ceiling round, to get the total number of arms when (tFireHelper.fire()) {
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 do_enq_helper = DecoupledHelper(hPort.toHost.hValid, streamEnq.ready, maybeEnq, traceEnable)
val do_fire_helper = DecoupledHelper(hPort.toHost.hValid, streamEnq.ready, maybeFire)
// 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)
when(hPort.toHost.fire) {
trace_cycle_counter := trace_cycle_counter + 1.U trace_cycle_counter := trace_cycle_counter + 1.U
} }
@ -276,9 +227,9 @@ class TracerVBridgeModule(key: TraceBundleWidths)(implicit p: Parameters)
UInt32(toHostStreamIdx), UInt32(toHostStreamIdx),
UInt32(toHostCPUQueueDepth), UInt32(toHostCPUQueueDepth),
UInt32(traces.size), UInt32(traces.size),
Verbatim(clockDomainInfo.toC), Verbatim(clockDomainInfo.toC)
), ),
hasStreams = true, hasStreams = true
) )
} }
} }

View File

@ -10,12 +10,10 @@
#include <iostream> #include <iostream>
#include <string_view> #include <string_view>
static std::vector<bool> get_valids(uint64_t seed, unsigned total) { static std::vector<bool> get_contiguous(unsigned bits, unsigned total) {
assert(total <= 64 && "This test does not support more than 64 IPC");
std::vector<bool> ret; std::vector<bool> ret;
for (unsigned i = 0; i < total; i++) { for (unsigned i = 0; i < total; i++) {
const bool value = seed & (1 << i); const bool value = (i < bits);
ret.emplace_back(value); ret.emplace_back(value);
} }
@ -170,16 +168,12 @@ public:
// calculate what TraverV should output, and save it // calculate what TraverV should output, and save it
if (bit[i]) { if (bit[i]) {
valid_i.emplace_back(iad[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 // place instructions onto the vector 7 at a time
for (size_t i = 0; i < valid_i.size(); i += 7) { for (size_t i = 0; i < valid_i.size(); i += 7) {
const auto last = std::min(valid_i.size(), i + 7); auto last = std::min(valid_i.size(), i + 7);
std::vector<uint64_t> chunk = std::vector<uint64_t> chunk =
std::vector<uint64_t>(valid_i.begin() + i, valid_i.begin() + last); std::vector<uint64_t>(valid_i.begin() + i, valid_i.begin() + last);
expected_pair.emplace_back(std::make_pair(e_cycle, chunk)); expected_pair.emplace_back(std::make_pair(e_cycle, chunk));
@ -193,10 +187,10 @@ public:
for (unsigned test_step = 0, total = get_total_trace_tests(); for (unsigned test_step = 0, total = get_total_trace_tests();
test_step < total; test_step < total;
++test_step) { ++test_step) {
const uint64_t pull = rand_next(); const uint64_t pull = rand_next(tracerv_width + 1);
const auto pull_bits = get_valids(pull, tracerv_width); auto pull_iaddr = get_iaddrs(test_step, tracerv_width);
const auto pull_iaddr = get_iaddrs(test_step, tracerv_width); auto pull_bits = get_contiguous(pull, tracerv_width);
load(pull_iaddr, pull_bits); load(pull_iaddr, pull_bits);
steps(1); steps(1);
@ -316,12 +310,7 @@ public:
assert(insns.size() < 8 && "Internal test error, filtered cannot " assert(insns.size() < 8 && "Internal test error, filtered cannot "
"have more than 8 instructions at once"); "have more than 8 instructions at once");
for (int i = 0; i < insns.size(); i++) { for (int i = 0; i < insns.size(); i++) {
// valid instruction, or invalid placeholder
if (insns[i] != -1) {
buffer[i + 1] = insns[i] | tracerv_t::valid_mask; buffer[i + 1] = insns[i] | tracerv_t::valid_mask;
} else {
buffer[i + 1] = 0;
}
} }
// because filtered doesn't contain the instruction value for non // because filtered doesn't contain the instruction value for non
@ -350,7 +339,7 @@ public:
/** /**
* Returns the next available random number, modulo limit. * Returns the next available random number, modulo limit.
*/ */
uint64_t rand_next() { return gen(); } uint64_t rand_next(uint64_t limit) { return gen() % limit; }
private: private:
unsigned get_total_trace_tests() const { return 128; } unsigned get_total_trace_tests() const { return 128; }

View File

@ -34,11 +34,6 @@ class TracerVModuleTestCount7
7 7
}) })
class TracerVModuleTestCount9
extends Config((site, here, up) => { case TracerVModuleInstructionCount =>
9
})
class TracerVModuleTestCount14 class TracerVModuleTestCount14
extends Config((site, here, up) => { case TracerVModuleInstructionCount => extends Config((site, here, up) => { case TracerVModuleInstructionCount =>
14 14

View File

@ -60,8 +60,5 @@ class TracerVF1TestCount1 extends TracerVTestBase(BaseConfigs.F1, 1);
// This test is disabled until FireSim issue #1428 is resolved // This test is disabled until FireSim issue #1428 is resolved
// class TracerVF1TestCount5 extends TracerVTestBase(BaseConfigs.F1, 5, Some(3), Some("FF0000001C")); // in hex // 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 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 TracerVF1TestCount7 extends TracerVTestBase(BaseConfigs.F1, 7, Some(1), Some("9")); // in decimala
class TracerVF1TestCount9 extends TracerVTestBase(BaseConfigs.F1, 9); class TracerVVitisTest extends TracerVTestBase(BaseConfigs.Vitis, 7);
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"));