address David PR comments
This commit is contained in:
parent
c78bc1df53
commit
372dec10a3
|
@ -100,7 +100,7 @@ class RuntimeHWConfig:
|
|||
runtime parameters currently. """
|
||||
|
||||
tracefile = "+tracefile0=TRACEFILE" if trace_enable else ""
|
||||
autocounterfile = "+autocounter-filename=AUTOCOUNTERFILE"
|
||||
autocounterfile = "+autocounter-filename0=AUTOCOUNTERFILE"
|
||||
|
||||
# this monstrosity boots the simulator, inside screen, inside script
|
||||
# the sed is in there to get rid of newlines in runtime confs
|
||||
|
@ -123,7 +123,7 @@ class RuntimeHWConfig:
|
|||
command_bootbinaries = array_to_plusargs(all_bootbinaries, "+prog")
|
||||
zero_out_dram = "+zero-out-dram"
|
||||
|
||||
basecommand = """screen -S fsim{slotid} -d -m bash -c "script -f -c 'stty intr ^] && sudo ./{driver} +permissive $(sed \':a;N;$!ba;s/\\n/ /g\' {runtimeconf}) +slotid={slotid} +profile-interval={profile_interval} {zero_out_dram} {command_macs} {command_rootfses} +niclog0=niclog {tracefile} +trace-select0={trace_select} +trace-start0={trace_start} +trace-end0={trace_end} +autocounter-readrate={autocounter_readrate} {autocounterfile} {command_linklatencies} {command_netbws} {command_shmemportnames} +permissive-off {command_bootbinaries} && stty intr ^c' uartlog"; sleep 1""".format(
|
||||
basecommand = """screen -S fsim{slotid} -d -m bash -c "script -f -c 'stty intr ^] && sudo ./{driver} +permissive $(sed \':a;N;$!ba;s/\\n/ /g\' {runtimeconf}) +slotid={slotid} +profile-interval={profile_interval} {zero_out_dram} {command_macs} {command_rootfses} +niclog0=niclog {tracefile} +trace-select0={trace_select} +trace-start0={trace_start} +trace-end0={trace_end} +autocounter-readrate0={autocounter_readrate} {autocounterfile} {command_linklatencies} {command_netbws} {command_shmemportnames} +permissive-off {command_bootbinaries} && stty intr ^c' uartlog"; sleep 1""".format(
|
||||
slotid=slotid, driver=driver, runtimeconf=runtimeconf,
|
||||
command_macs=command_macs,
|
||||
command_rootfses=command_rootfses,
|
||||
|
|
|
@ -1,21 +1,14 @@
|
|||
Debugging Using AutoCounter
|
||||
================================
|
||||
|
||||
FireSim can provide visibility into the CPU's architectural state
|
||||
over the course of execution through the use of counters. These are
|
||||
FireSim can provide visibility into the CPU's architectural and microarchitectural
|
||||
state over the course of execution through the use of counters. These are
|
||||
similar to performance counters provided by processor vendors, and more
|
||||
general counters provided by architectural simulators.
|
||||
This functionality is provided by the AutoCounter feature, and can be used
|
||||
for profiling and debugging.
|
||||
|
||||
|
||||
Building a Design with AutoCounter
|
||||
-------------------------------------
|
||||
|
||||
To enable AutoCounter when building a design, prepend ``WithAutoCounterCover`` Config to your
|
||||
PLATFORM_CONFIG. During compilation, FireSim will print the
|
||||
signals it is generating counters for. If AutoCounter has been enabled, the
|
||||
``autocounter_t`` bridge driver will be automatically instantiated.
|
||||
Since AutoCounter injects counters only in simulation (unlike target-level performance
|
||||
counters), these counters do not affect the behavior of the simulated machine.
|
||||
|
||||
|
||||
Ad-hoc Performance Counters
|
||||
|
@ -28,11 +21,20 @@ and the counter description. An example counter declaration would be:
|
|||
midas.targetutils.PerfCounter(s1_pc, "s1_pc", "stage 1 program counter")
|
||||
|
||||
|
||||
Building a Design with AutoCounter
|
||||
-------------------------------------
|
||||
|
||||
To enable AutoCounter when building a design, prepend ``WithAutoCounterCover`` Config to your
|
||||
PLATFORM_CONFIG. During compilation, FireSim will print the
|
||||
signals it is generating counters for. If AutoCounter has been enabled, the
|
||||
``autocounter_t`` bridge driver will be automatically instantiated.
|
||||
|
||||
|
||||
Rocket Chip Cover Functions
|
||||
------------------------------
|
||||
Cover functions are unimplemented function interfaces embedded in the Rocket Chip generator
|
||||
repository to represent points of interest for coverage. In FireSim, these functions are used as
|
||||
indicators for automatic generation of counters.
|
||||
repository to represent points of interest for coverage. In FireSim, these functions can be used
|
||||
as a hook for automatic generation of counters.
|
||||
|
||||
Since cover functions are embedded throughout the code of Rocket Chip (and possibly other code repositories),
|
||||
AutoCounter provides a filtering mechanism based on module granulariy. As such, only cover functions that appear
|
||||
|
@ -60,7 +62,7 @@ The filtered modules can be indicated using one of two methods:
|
|||
chisel3.experimental.annotate(AutoCounterCoverModuleAnnotation("StreamWriter"))
|
||||
}
|
||||
|
||||
2. An input file with a list of module names. This input file is nameed ``autocounter-covermodules.txt``,
|
||||
2. An input file with a list of module names. This input file is named ``autocounter-covermodules.txt``,
|
||||
an includes a list of module names separated by new lines (no commas).
|
||||
|
||||
|
||||
|
@ -69,7 +71,7 @@ AutoCounter Runtime Parameters
|
|||
AutoCounter currently takes a single runtime configurable parameter, defined under the ``[autocounter]``
|
||||
section in the ``config_runtime.ini`` file.
|
||||
The ``readrate`` parameter defines the rate at which the counters should be read,
|
||||
and is measured in cycles. Hence, if the read-rate is defined to be 100,
|
||||
and is measured in target-cycles. Hence, if the read-rate is defined to be 100,
|
||||
the simulator will read and print the values of the counters every 100 cycles.
|
||||
By default, the read-rate is set to 0 cycles, which is equivalent to disabling AutoCounter.
|
||||
|
||||
|
@ -81,7 +83,7 @@ By default, the read-rate is set to 0 cycles, which is equivalent to disabling A
|
|||
Now when you run a workload, an AutoCounter output file will be placed in the
|
||||
`sim_slot_<slot #>` directory on the F1 instance under the name AUTOCOUNTERFILE.
|
||||
|
||||
.. Note:: AutoCounter is designed as a coarse-grained observability mechanism. It assumes the counters will be read at intervals greater than O(1000) cycles. If you intened on reading counters at a finer granularity, please consider using synthesizable printfs (otherwise, simulation performance may degrade more than neccessary)
|
||||
.. Note:: AutoCounter is designed as a coarse-grained observability mechanism. It assumes the counters will be read at intervals greater than O(10000) cycles. If you intend on reading counters at a finer granularity, please consider using synthesizable printfs (otherwise, simulation performance may degrade more than necessary)
|
||||
|
||||
Using TracerV Trigger with AutoCounter
|
||||
-----------------------------------------
|
||||
|
@ -91,7 +93,7 @@ enabling a TracerV trigger condition, the selected region of interest will autom
|
|||
reflected in the AutoCounter output file as well.
|
||||
|
||||
|
||||
Legacy AutoCounter using Synthesizable Printfs
|
||||
AutoCounter using Synthesizable Printfs
|
||||
------------------------------------------------
|
||||
The AutoCounter transformation in the Golden Gate compiler includes a legacy mode that uses
|
||||
Synthesizable Printfs to export counter results rather than a dedicated Bridge. This mode can
|
||||
|
|
|
@ -15,16 +15,16 @@
|
|||
#include <sys/mman.h>
|
||||
|
||||
autocounter_t::autocounter_t(
|
||||
simif_t *sim, std::vector<std::string> &args, AUTOCOUNTERBRIDGEMODULE_struct * mmio_addrs, AddressMap addr_map) : bridge_driver_t(sim), addr_map(addr_map)
|
||||
simif_t *sim, std::vector<std::string> &args, AUTOCOUNTERBRIDGEMODULE_struct * mmio_addrs, AddressMap addr_map, int autocounterno) : bridge_driver_t(sim), addr_map(addr_map)
|
||||
{
|
||||
this->mmio_addrs = mmio_addrs;
|
||||
|
||||
this->readrate = 0;
|
||||
this->autocounter_filename = "AUTOCOUNTER";
|
||||
const char *autocounter_filename_in = NULL;
|
||||
//std::string num_equals = std::to_string(coreno) + std::string("=");
|
||||
std::string readrate_arg = std::string("+autocounter-readrate=");
|
||||
std::string filename_arg = std::string("+autocounter-filename=");
|
||||
std::string num_equals = std::to_string(autocounterno) + std::string("=");
|
||||
std::string readrate_arg = std::string("+autocounter-readrate") + num_equals;
|
||||
std::string filename_arg = std::string("+autocounter-filename") + num_equals;
|
||||
|
||||
for (auto &arg: args) {
|
||||
if (arg.find(readrate_arg) == 0) {
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
class autocounter_t: public bridge_driver_t {
|
||||
public:
|
||||
autocounter_t(simif_t *sim, std::vector<std::string> &args,
|
||||
AUTOCOUNTERBRIDGEMODULE_struct * mmio_addrs, AddressMap addr_map);
|
||||
AUTOCOUNTERBRIDGEMODULE_struct * mmio_addrs, AddressMap addr_map, int autocounterno);
|
||||
~autocounter_t();
|
||||
|
||||
virtual void init();
|
||||
|
|
|
@ -50,8 +50,6 @@ class AutoCounterBridgeModule(constructorArg: AutoCounterBridgeConstArgs)(implic
|
|||
|
||||
val readrate_low = RegInit(0.U(hostReadrateLowWidth.W))
|
||||
val readrate_high = RegInit(0.U(hostReadrateHighWidth.W))
|
||||
chisel3.core.dontTouch(readrate_low)
|
||||
chisel3.core.dontTouch(readrate_high)
|
||||
val readrate = Wire(UInt(64.W))
|
||||
val readrate_dly = RegInit(0.U(64.W))
|
||||
readrate := Cat(readrate_high, readrate_low)
|
||||
|
@ -99,11 +97,11 @@ class AutoCounterBridgeModule(constructorArg: AutoCounterBridgeConstArgs)(implic
|
|||
|
||||
|
||||
//communication with the driver
|
||||
val readdone = RegInit(0.U(true.B))
|
||||
val readdone_dly = RegInit(0.U(true.B))
|
||||
val readdone = RegInit(false.B)
|
||||
val readdone_dly = RegInit(false.B)
|
||||
val readdone_negedge = Wire(Bool())
|
||||
val readdone_posedge = Wire(Bool())
|
||||
val med = RegInit(0.U(true.B))
|
||||
val med = RegInit(false.B)
|
||||
readdone_dly := readdone
|
||||
readdone_posedge := readdone & ~readdone_dly
|
||||
readdone_negedge := readdone_dly & ~readdone
|
||||
|
@ -123,7 +121,7 @@ class AutoCounterBridgeModule(constructorArg: AutoCounterBridgeConstArgs)(implic
|
|||
|
||||
|
||||
labels.keys.foreach {
|
||||
case(index) => {
|
||||
case (index) => {
|
||||
attach(acc_counters(index)(hostCounterLowWidth-1, 0), s"autocounter_low_${labels(index)}", ReadOnly)
|
||||
attach(acc_counters(index) >> hostCounterLowWidth, s"autocounter_high_${labels(index)}", ReadOnly)
|
||||
}
|
||||
|
|
|
@ -161,8 +161,6 @@ class TracerVBridgeModule(key: TracerVKey)(implicit p: Parameters) extends Bridg
|
|||
} .otherwise {
|
||||
trace_cycle_counter := trace_cycle_counter
|
||||
}
|
||||
val wide_cycles_counter = RegInit(0.U((outgoingPCISdat.io.enq.bits.getWidth).W))
|
||||
wide_cycles_counter := trace_cycle_counter << (outgoingPCISdat.io.enq.bits.getWidth - 64)
|
||||
|
||||
//target instruction type trigger (trigger through target software)
|
||||
//can configure the trigger instruction type externally though simulation driver
|
||||
|
@ -223,8 +221,10 @@ class TracerVBridgeModule(key: TracerVKey)(implicit p: Parameters) extends Bridg
|
|||
lazy val toHostCPUQueueDepth = TOKEN_QUEUE_DEPTH
|
||||
lazy val dmaSize = BigInt((BIG_TOKEN_WIDTH / 8) * TOKEN_QUEUE_DEPTH)
|
||||
|
||||
val uint_traces = traces map (trace => (UInt(0, 64.W) | Cat(trace.valid, trace.iaddr)))
|
||||
outgoingPCISdat.io.enq.bits := wide_cycles_counter | Cat(uint_traces)
|
||||
val uint_traces = traces map (trace => Cat(trace.valid, trace.iaddr).pad(64))
|
||||
outgoingPCISdat.io.enq.bits := Cat(Cat(trace_cycle_counter,
|
||||
0.U((outgoingPCISdat.io.enq.bits.getWidth - Cat(uint_traces).getWidth - trace_cycle_counter.getWidth).W)),
|
||||
Cat(uint_traces))
|
||||
|
||||
val tFireHelper = DecoupledHelper(outgoingPCISdat.io.enq.ready,
|
||||
hPort.toHost.hValid, hPort.fromHost.hReady)
|
||||
|
|
|
@ -386,7 +386,7 @@ uint64_t host_mem_offset = -0x80000000LL;
|
|||
(const char* const*) AUTOCOUNTERBRIDGEMODULE_0_R_names,
|
||||
AUTOCOUNTERBRIDGEMODULE_0_W_num_registers,
|
||||
(const unsigned int*) AUTOCOUNTERBRIDGEMODULE_0_W_addrs,
|
||||
(const char* const*) AUTOCOUNTERBRIDGEMODULE_0_W_names)));
|
||||
(const char* const*) AUTOCOUNTERBRIDGEMODULE_0_W_names), 0));
|
||||
#endif
|
||||
#ifdef AUTOCOUNTERBRIDGEMODULE_1_PRESENT
|
||||
AUTOCOUNTERBRIDGEMODULE_1_substruct_create;
|
||||
|
@ -397,7 +397,7 @@ uint64_t host_mem_offset = -0x80000000LL;
|
|||
(const char* const*) AUTOCOUNTERBRIDGEMODULE_1_R_names,
|
||||
AUTOCOUNTERBRIDGEMODULE_1_W_num_registers,
|
||||
(const unsigned int*) AUTOCOUNTERBRIDGEMODULE_1_W_addrs,
|
||||
(const char* const*) AUTOCOUNTERBRIDGEMODULE_1_W_names)));
|
||||
(const char* const*) AUTOCOUNTERBRIDGEMODULE_1_W_names), 1));
|
||||
#endif
|
||||
#ifdef AUTOCOUNTERBRIDGEMODULE_2_PRESENT
|
||||
AUTOCOUNTERBRIDGEMODULE_2_substruct_create;
|
||||
|
@ -408,7 +408,7 @@ uint64_t host_mem_offset = -0x80000000LL;
|
|||
(const char* const*) AUTOCOUNTERBRIDGEMODULE_2_R_names,
|
||||
AUTOCOUNTERBRIDGEMODULE_2_W_num_registers,
|
||||
(const unsigned int*) AUTOCOUNTERBRIDGEMODULE_2_W_addrs,
|
||||
(const char* const*) AUTOCOUNTERBRIDGEMODULE_2_W_names)));
|
||||
(const char* const*) AUTOCOUNTERBRIDGEMODULE_2_W_names), 2));
|
||||
#endif
|
||||
#ifdef AUTCOUNTERBRIDGEMODULE_3_PRESENT
|
||||
AUTOCOUNTERBRIDGEMODULE_3_substruct_create;
|
||||
|
@ -419,7 +419,7 @@ uint64_t host_mem_offset = -0x80000000LL;
|
|||
(const char* const*) AUTOCOUNTERBRIDGEMODULE_3_R_names,
|
||||
AUTOCOUNTERBRIDGEMODULE_3_W_num_registers,
|
||||
(const unsigned int*) AUTOCOUNTERBRIDGEMODULE_3_W_addrs,
|
||||
(const char* const*) AUTOCOUNTERBRIDGEMODULE_3_W_names)));
|
||||
(const char* const*) AUTOCOUNTERBRIDGEMODULE_3_W_names), 3));
|
||||
#endif
|
||||
#ifdef AUTOCOUNTERBRIDGEMODULE_4_PRESENT
|
||||
AUTOCOUNTERBRIDGEMODULE_4_substruct_create;
|
||||
|
@ -430,7 +430,7 @@ uint64_t host_mem_offset = -0x80000000LL;
|
|||
(const char* const*) AUTOCOUNTERBRIDGEMODULE_4_R_names,
|
||||
AUTOCOUNTERBRIDGEMODULE_4_W_num_registers,
|
||||
(const unsigned int*) AUTOCOUNTERBRIDGEMODULE_4_W_addrs,
|
||||
(const char* const*) AUTOCOUNTERBRIDGEMODULE_4_W_names)));
|
||||
(const char* const*) AUTOCOUNTERBRIDGEMODULE_4_W_names), 4));
|
||||
#endif
|
||||
#ifdef AUTOCOUNTERBRIDGEMODULE_5_PRESENT
|
||||
AUTOCOUNTERBRIDGEMODULE_5_substruct_create;
|
||||
|
@ -441,7 +441,7 @@ uint64_t host_mem_offset = -0x80000000LL;
|
|||
(const char* const*) AUTOCOUNTERBRIDGEMODULE_5_R_names,
|
||||
AUTOCOUNTERBRIDGEMODULE_5_W_num_registers,
|
||||
(const unsigned int*) AUTOCOUNTERBRIDGEMODULE_5_W_addrs,
|
||||
(const char* const*) AUTOCOUNTERBRIDGEMODULE_5_W_names)));
|
||||
(const char* const*) AUTOCOUNTERBRIDGEMODULE_5_W_names), 5));
|
||||
#endif
|
||||
#ifdef AUTOCOUNTERBRIDGEMODULE_6_PRESENT
|
||||
AUTOCOUNTERBRIDGEMODULE_6_substruct_create;
|
||||
|
@ -452,7 +452,7 @@ uint64_t host_mem_offset = -0x80000000LL;
|
|||
(const char* const*) AUTOCOUNTERBRIDGEMODULE_6_R_names,
|
||||
AUTOCOUNTERBRIDGEMODULE_6_W_num_registers,
|
||||
(const unsigned int*) AUTOCOUNTERBRIDGEMODULE_6_W_addrs,
|
||||
(const char* const*) AUTOCOUNTERBRIDGEMODULE_6_W_names)));
|
||||
(const char* const*) AUTOCOUNTERBRIDGEMODULE_6_W_names), 6));
|
||||
#endif
|
||||
#ifdef AUTOCOUNTERBRIDGEMODULE_7_PRESENT
|
||||
AUTOCOUNTERBRIDGEMODULE_7_substruct_create;
|
||||
|
@ -463,7 +463,7 @@ uint64_t host_mem_offset = -0x80000000LL;
|
|||
(const char* const*) AUTOCOUNTERBRIDGEMODULE_7_R_names,
|
||||
AUTOCOUNTERBRIDGEMODULE_7_W_num_registers,
|
||||
(const unsigned int*) AUTOCOUNTERBRIDGEMODULE_7_W_addrs,
|
||||
(const char* const*) AUTOCOUNTERBRIDGEMODULE_7_W_names)));
|
||||
(const char* const*) AUTOCOUNTERBRIDGEMODULE_7_W_names), 7));
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ class autocounter_module_t: virtual simif_t
|
|||
(const char* const*) AUTOCOUNTERBRIDGEMODULE_0_R_names,
|
||||
AUTOCOUNTERBRIDGEMODULE_0_W_num_registers,
|
||||
(const unsigned int*) AUTOCOUNTERBRIDGEMODULE_0_W_addrs,
|
||||
(const char* const*) AUTOCOUNTERBRIDGEMODULE_0_W_names)));
|
||||
(const char* const*) AUTOCOUNTERBRIDGEMODULE_0_W_names), 0));
|
||||
};
|
||||
void run_and_collect(int cycles) {
|
||||
step(cycles, false);
|
||||
|
|
|
@ -75,7 +75,7 @@ nic_args = +shmemportname0=$(NET_SHMEMPORTNAME) +macaddr0=$(NET_MACADDR) \
|
|||
+niclog0=niclog$(NET_SLOT) +linklatency0=$(NET_LINK_LATENCY) \
|
||||
+netbw0=$(NET_BW) +netburst0=8 $(NET_LOOPBACK)
|
||||
tracer_args = +tracefile0=TRACEFILE
|
||||
autocounter_args = +autocounter-readrate=1000 +autocounter-filename=AUTOCOUNTERFILE
|
||||
autocounter_args = +autocounter-readrate0=1000 +autocounter-filename0=AUTOCOUNTERFILE
|
||||
|
||||
SIM_RUNTIME_CONF ?= $(GENERATED_DIR)/$(CONF_NAME)
|
||||
mem_model_args = $(shell cat $(SIM_RUNTIME_CONF))
|
||||
|
|
|
@ -23,7 +23,7 @@ class AutoCounterModuleDUT extends Module {
|
|||
|
||||
enabled4 := ~enabled_cycles(1) & ~enabled_cycles(0) & io.a
|
||||
|
||||
PerfCounter(enabled4, "ENABLED_DIV_4", "Count the number of times the enabled cycle count is divisable by 4. Should be equval to number of cycles minus reset cycles divided by 4")
|
||||
PerfCounter(enabled4, "ENABLED_DIV_4", "Count the number of times the enabled cycle count is divisible by 4. Should be equal to number of cycles minus reset cycles divided by 4")
|
||||
|
||||
val childInst = Module(new AutoCounterModuleChild)
|
||||
childInst.io.c := io.a
|
||||
|
|
|
@ -133,11 +133,11 @@ class RiscF1Test extends TutorialSuite("Risc")
|
|||
class RiscSRAMF1Test extends TutorialSuite("RiscSRAM")
|
||||
class AssertModuleF1Test extends TutorialSuite("AssertModule")
|
||||
class AutoCounterModuleF1Test extends TutorialSuite("AutoCounterModule",
|
||||
simulationArgs = Seq("+autocounter-readrate=1000", "+autocounter-filename=AUTOCOUNTERFILE")) {
|
||||
simulationArgs = Seq("+autocounter-readrate0=1000", "+autocounter-filename0=AUTOCOUNTERFILE")) {
|
||||
diffAutoCounterOutput("AUTOCOUNTERFILE", "AutoCounterModule.autocounter.out")
|
||||
}
|
||||
class AutoCounterCoverModuleF1Test extends TutorialSuite("AutoCounterCoverModule",
|
||||
simulationArgs = Seq("+autocounter-readrate=1000", "+autocounter-filename=AUTOCOUNTERFILE")) {
|
||||
simulationArgs = Seq("+autocounter-readrate0=1000", "+autocounter-filename0=AUTOCOUNTERFILE")) {
|
||||
diffAutoCounterOutput("AUTOCOUNTERFILE", "AutoCounterCoverModule.autocounter.out")
|
||||
}
|
||||
class PrintfModuleF1Test extends TutorialSuite("PrintfModule",
|
||||
|
|
Loading…
Reference in New Issue