Link PlusArg to emulator command line options
- adds a mutable singleton (PlusArgArtefacts) to store information about Rocket PlusArgs - adds methods to PlusArgArtefacts to emit C snippets that are consumed by emulator.cc for correct argument parsing and help text generation - emits snippets in $(CONFIG).plusArgs via BaseCoreplex-set ElaborationArtefacts - modify emulator/Makefrag-verilator to include $(CONFIG).plusArgs - cleanup help text (docstring) for existing PlusArgs Signed-off-by: Schuyler Eldridge <schuyler.eldridge@gmail.com>
This commit is contained in:
		| @@ -21,6 +21,7 @@ abstract class BareCoreplexModule[+L <: BareCoreplex](_outer: L) extends LazyMod | ||||
|   ElaborationArtefacts.add("graphml", outer.graphML) | ||||
|   ElaborationArtefacts.add("dts", outer.dts) | ||||
|   ElaborationArtefacts.add("json", outer.json) | ||||
|   ElaborationArtefacts.add("plusArgs", PlusArgArtefacts.serialize) | ||||
|   println(outer.dts) | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -286,7 +286,7 @@ class Rocket(implicit p: Parameters) extends CoreModule()(p) | ||||
|   alu.io.fn := ex_ctrl.alu_fn | ||||
|   alu.io.in2 := ex_op2.asUInt | ||||
|   alu.io.in1 := ex_op1.asUInt | ||||
|    | ||||
|  | ||||
|   // multiplier and divider | ||||
|   val div = Module(new MulDiv(mulDivParams, width = xLen)) | ||||
|   div.io.req.valid := ex_reg_valid && ex_ctrl.div | ||||
| @@ -525,7 +525,7 @@ class Rocket(implicit p: Parameters) extends CoreModule()(p) | ||||
|  | ||||
|   val wb_valid = wb_reg_valid && !replay_wb && !wb_xcpt | ||||
|   val wb_wen = wb_valid && wb_ctrl.wxd | ||||
|   val rf_wen = wb_wen || ll_wen  | ||||
|   val rf_wen = wb_wen || ll_wen | ||||
|   val rf_waddr = Mux(ll_wen, ll_waddr, wb_waddr) | ||||
|   val rf_wdata = Mux(dmem_resp_valid && dmem_resp_xpu, io.dmem.resp.bits.data, | ||||
|                  Mux(ll_wen, ll_wdata, | ||||
| @@ -724,7 +724,7 @@ class Rocket(implicit p: Parameters) extends CoreModule()(p) | ||||
|  | ||||
|   val max_core_cycles = PlusArg("max-core-cycles", | ||||
|     default = 0, | ||||
|     docstring = "Maximum Core Clock cycles simulation may run before timeout. Ignored if 0 (Default).") | ||||
|     docstring = "Kill the emulation after INT rdtime cycles. Off if 0.") | ||||
|   when (max_core_cycles > UInt(0)) { | ||||
|     assert (csr.io.time < max_core_cycles, "Maximum Core Cycles reached.") | ||||
|   } | ||||
|   | ||||
| @@ -442,7 +442,8 @@ class TLMonitor(args: TLMonitorArgs) extends TLMonitorBase(args) | ||||
|     inflight := (inflight | a_set) & ~d_clr | ||||
|  | ||||
|     val watchdog = RegInit(UInt(0, width = 32)) | ||||
|     val limit = PlusArg("tilelink_timeout") | ||||
|     val limit = PlusArg("tilelink_timeout", | ||||
|       docstring="Kill emulation after INT waiting TileLink cycles. Off if 0.") | ||||
|     assert (!inflight.orR || limit === UInt(0) || watchdog < limit, "TileLink timeout expired" + extra) | ||||
|  | ||||
|     watchdog := watchdog + UInt(1) | ||||
|   | ||||
| @@ -4,6 +4,8 @@ package freechips.rocketchip.util | ||||
|  | ||||
| import Chisel._ | ||||
|  | ||||
| case class PlusArgInfo(default: Int, docstring: String) | ||||
|  | ||||
| class plusarg_reader(val format: String, val default: Int, val docstring: String) extends BlackBox(Map( | ||||
|     "FORMAT"  -> chisel3.core.StringParam(format), | ||||
|     "DEFAULT" -> chisel3.core.IntParam(default))) { | ||||
| @@ -20,6 +22,42 @@ object PlusArg | ||||
|   // Add a docstring to document the arg, which can be dumped in an elaboration | ||||
|   // pass. | ||||
|  | ||||
|   def apply(name: String, default: Int = 0, docstring: String = ""): UInt = | ||||
|   def apply(name: String, default: Int = 0, docstring: String = ""): UInt = { | ||||
|     PlusArgArtefacts.append(name, default, docstring) | ||||
|     Module(new plusarg_reader(name + "=%d", default, docstring)).io.out | ||||
|   } | ||||
| } | ||||
|  | ||||
| object PlusArgArtefacts { | ||||
|   private var artefacts: Map[String, PlusArgInfo] = Map.empty | ||||
|  | ||||
|   /* Add a new PlusArg */ | ||||
|   def append(name: String, default: Int, docstring: String): Unit = | ||||
|     artefacts = artefacts ++ Map(name -> PlusArgInfo(default, docstring)) | ||||
|  | ||||
|   /* From plus args, generate help text */ | ||||
|   private def serializeHelp(tab: String = ""): String = artefacts | ||||
|     .map{ case(arg, PlusArgInfo(default, docstring)) => | ||||
|       s"""|$tab+$arg=INT\\n\\ | ||||
|           |$tab${" "*20}$docstring\\n\\ | ||||
|           |$tab${" "*22}(default=$default)""".stripMargin }.toSeq | ||||
|     .mkString("\\n\\\n") ++ "\"" | ||||
|  | ||||
|   /* From plus args, generate a char array of their names */ | ||||
|   private def serializeArray(tab: String = ""): String = { | ||||
|     val prettyTab = tab + " " * 44 // Length of 'static const ...' | ||||
|     s"${tab}static const char * verilog_plusargs [] = {\\\n" ++ | ||||
|       artefacts | ||||
|         .map{ case(arg, _) => s"""$prettyTab"$arg",\\\n""" } | ||||
|         .mkString("")++ | ||||
|     s"${prettyTab}0};" | ||||
|   } | ||||
|  | ||||
|   /* Generate C code to be included in emulator.cc that helps with | ||||
|    * argument parsing based on available Verilog PlusArgs */ | ||||
|   def serialize(): String = | ||||
|     s"""|#define PLUSARG_USAGE_OPTIONS \"EMULATOR VERILOG PLUSARGS\\n\\ | ||||
|         |${serializeHelp(" "*7)} | ||||
|         |${serializeArray()} | ||||
|         |""".stripMargin | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user