From 7f1d3c445fbed98e4e16c508a23b92a90e349c3b Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Thu, 18 May 2017 22:49:59 -0700 Subject: [PATCH] Plusargs -- tilelink timeout detection from the command line (#752) * util: PlusArg gives Chisel access to the command-line * tilelink2: add a progress watchdog to Monitors --- csrc/emulator.cc | 1 + src/main/scala/uncore/tilelink2/Monitor.scala | 7 ++++++ src/main/scala/util/PlusArg.scala | 21 ++++++++++++++++++ vsim/Makefrag | 1 + vsrc/plusarg_reader.v | 22 +++++++++++++++++++ 5 files changed, 52 insertions(+) create mode 100644 src/main/scala/util/PlusArg.scala create mode 100644 vsrc/plusarg_reader.v diff --git a/csrc/emulator.cc b/csrc/emulator.cc index 04c4fedb..46841617 100644 --- a/csrc/emulator.cc +++ b/csrc/emulator.cc @@ -155,6 +155,7 @@ done_processing: srand48(random_seed); Verilated::randReset(2); + Verilated::commandArgs(argc, argv); TEST_HARNESS *tile = new TEST_HARNESS; #if VM_TRACE diff --git a/src/main/scala/uncore/tilelink2/Monitor.scala b/src/main/scala/uncore/tilelink2/Monitor.scala index 0ad17c27..0fb7b575 100644 --- a/src/main/scala/uncore/tilelink2/Monitor.scala +++ b/src/main/scala/uncore/tilelink2/Monitor.scala @@ -435,6 +435,13 @@ class TLMonitor(args: TLMonitorArgs) extends TLMonitorBase(args) } inflight := (inflight | a_set) & ~d_clr + + val watchdog = RegInit(UInt(0, width = 32)) + val limit = util.PlusArg("tilelink_timeout") + assert (!inflight.orR || limit === UInt(0) || watchdog < limit, "TileLink timeout expired" + extra) + + watchdog := watchdog + UInt(1) + when (bundle.a.fire() || bundle.d.fire()) { watchdog := UInt(0) } } def legalizeDESink(bundle: TLBundleSnoop, edge: TLEdge)(implicit sourceInfo: SourceInfo) { diff --git a/src/main/scala/util/PlusArg.scala b/src/main/scala/util/PlusArg.scala new file mode 100644 index 00000000..d902558d --- /dev/null +++ b/src/main/scala/util/PlusArg.scala @@ -0,0 +1,21 @@ +// See LICENSE.SiFive for license details. + +package util +import Chisel._ + +class plusarg_reader(format: String, default: Int) extends BlackBox(Map( + "FORMAT" -> chisel3.core.StringParam(format), + "DEFAULT" -> chisel3.core.IntParam(default))) { + val io = new Bundle { + val out = UInt(OUTPUT, width = 32) + } +} + +object PlusArg +{ + // PlusArg("foo") will return 42 if the simulation is run with +foo=42 + // Do not use this as an initial register value. The value is set in an + // initial block and thus accessing it from another initial is racey. + def apply(name: String, default: Int = 0): UInt = + Module(new plusarg_reader(name + "=%d", default)).io.out +} diff --git a/vsim/Makefrag b/vsim/Makefrag index 50e3a1a3..2fd3b076 100644 --- a/vsim/Makefrag +++ b/vsim/Makefrag @@ -6,6 +6,7 @@ bb_vsrcs = \ $(base_dir)/vsrc/jtag_vpi.v \ + $(base_dir)/vsrc/plusarg_reader.v \ $(base_dir)/vsrc/ClockDivider2.v \ $(base_dir)/vsrc/ClockDivider3.v \ $(base_dir)/vsrc/AsyncResetReg.v \ diff --git a/vsrc/plusarg_reader.v b/vsrc/plusarg_reader.v new file mode 100644 index 00000000..19191421 --- /dev/null +++ b/vsrc/plusarg_reader.v @@ -0,0 +1,22 @@ +// See LICENSE.SiFive for license details. + +// No default parameter values are intended, nor does IEEE 1800-2012 require them (clause A.2.4 param_assignment), +// but Incisive demands them. These default values should never be used. +module plusarg_reader #(string FORMAT="borked", int DEFAULT=0) ( + output [31:0] out +); + +reg [31:0] myplus; +assign out = myplus; + +initial begin + myplus = DEFAULT; +`ifndef SYNTHESIS +`ifndef verilator + // Work-around for https://www.veripool.org/issues/1165 + if (!$value$plusargs(FORMAT, myplus)) myplus = DEFAULT; +`endif +`endif +end + +endmodule