* Revert "Expand TracerV to support more than 7 IPC (#1383)"
This reverts commit 0e77b74a1a
.
* Update AGFI(s) [ci skip]
---------
Co-authored-by: abejgonzalez <abejgonzalez@users.noreply.github.com>
This commit is contained in:
parent
9a66e00612
commit
274b867362
|
@ -73,8 +73,3 @@ alveo_u280_firesim_rocket_singlecore_no_nic:
|
||||||
deploy_quintuplet_override: null
|
deploy_quintuplet_override: null
|
||||||
custom_runtime_config: null
|
custom_runtime_config: null
|
||||||
# DOCREF END: Xilinx Alveo HWDB Entries
|
# DOCREF END: Xilinx Alveo HWDB Entries
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
@ -269,6 +272,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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
@ -65,7 +66,7 @@ object TracerVBridge {
|
||||||
tracerv
|
tracerv
|
||||||
}
|
}
|
||||||
|
|
||||||
def apply(tracedInsns: TileTraceIO)(implicit p: Parameters): TracerVBridge = {
|
def apply(tracedInsns: TileTraceIO)(implicit p:Parameters): TracerVBridge = {
|
||||||
val tracerv = withClockAndReset(tracedInsns.clock, tracedInsns.reset) {
|
val tracerv = withClockAndReset(tracedInsns.clock, tracedInsns.reset) {
|
||||||
TracerVBridge(tracedInsns.traceBundleWidths)
|
TracerVBridge(tracedInsns.traceBundleWidths)
|
||||||
}
|
}
|
||||||
|
@ -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))
|
||||||
|
@ -170,10 +171,10 @@ class TracerVBridgeModule(key: TraceBundleWidths)(implicit p: Parameters)
|
||||||
|
|
||||||
val triggerPCValVec = RegInit(VecInit(Seq.fill(traces.length)(false.B)))
|
val triggerPCValVec = RegInit(VecInit(Seq.fill(traces.length)(false.B)))
|
||||||
traces.zipWithIndex.foreach { case (trace, i) =>
|
traces.zipWithIndex.foreach { case (trace, i) =>
|
||||||
when(trace.valid) {
|
when (trace.valid) {
|
||||||
when(triggerPCStart === trace.iaddr) {
|
when (triggerPCStart === trace.iaddr) {
|
||||||
triggerPCValVec(i) := true.B
|
triggerPCValVec(i) := true.B
|
||||||
}.elsewhen((triggerPCEnd === trace.iaddr) && triggerPCValVec(i)) {
|
} .elsewhen ((triggerPCEnd === trace.iaddr) && triggerPCValVec(i)) {
|
||||||
triggerPCValVec(i) := false.B
|
triggerPCValVec(i) := false.B
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -181,25 +182,20 @@ class TracerVBridgeModule(key: TraceBundleWidths)(implicit p: Parameters)
|
||||||
|
|
||||||
val triggerInstValVec = RegInit(VecInit(Seq.fill(traces.length)(false.B)))
|
val triggerInstValVec = RegInit(VecInit(Seq.fill(traces.length)(false.B)))
|
||||||
traces.zipWithIndex.foreach { case (trace, i) =>
|
traces.zipWithIndex.foreach { case (trace, i) =>
|
||||||
when(trace.valid) {
|
when (trace.valid) {
|
||||||
when(!((hostTriggerStartInst ^ trace.insn) & hostTriggerStartInstMask).orR) {
|
when (!((hostTriggerStartInst ^ trace.insn) & hostTriggerStartInstMask).orR) {
|
||||||
triggerInstValVec(i) := true.B
|
triggerInstValVec(i) := true.B
|
||||||
}.elsewhen(!((hostTriggerEndInst ^ trace.insn) & hostTriggerEndInstMask).orR) {
|
} .elsewhen (!((hostTriggerEndInst ^ trace.insn) & hostTriggerEndInstMask).orR) {
|
||||||
triggerInstValVec(i) := false.B
|
triggerInstValVec(i) := false.B
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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; }
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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"));
|
|
||||||
|
|
Loading…
Reference in New Issue