diff --git a/generators/chipyard/src/main/scala/Clocks.scala b/generators/chipyard/src/main/scala/Clocks.scala index 70fe38e7..e4d48b59 100644 --- a/generators/chipyard/src/main/scala/Clocks.scala +++ b/generators/chipyard/src/main/scala/Clocks.scala @@ -15,40 +15,6 @@ import testchipip.{TLTileResetCtrl} import chipyard.clocking._ -/** - * Chipyard provides three baseline, top-level reset schemes, set using the - * [[GlobalResetSchemeKey]] in a Parameters instance. These are: - * - * 1) Synchronous: The input coming to the chip is synchronous to the provided - * clocks and will be used without modification as a synchronous reset. - * This is safe only for use in FireSim and SW simulation. - * - * 2) Asynchronous: The input reset is asynchronous to the input clock, but it - * is caught and synchronized to that clock before it is dissemenated. - * Thus, downsteam modules will be emitted with synchronously reset state - * elements. - * - * 3) Asynchronous Full: The input reset is asynchronous to the input clock, - * and is used globally as an async reset. Downstream modules will be emitted - * with asynchronously reset state elements. - * - */ -sealed trait GlobalResetScheme { - def pinIsAsync: Boolean -} -sealed trait HasAsyncInput { self: GlobalResetScheme => - def pinIsAsync = true -} - -sealed trait HasSyncInput { self: GlobalResetScheme => - def pinIsAsync = false -} - -case object GlobalResetSynchronous extends GlobalResetScheme with HasSyncInput -case object GlobalResetAsynchronous extends GlobalResetScheme with HasAsyncInput -case object GlobalResetAsynchronousFull extends GlobalResetScheme with HasAsyncInput -case object GlobalResetSchemeKey extends Field[GlobalResetScheme](GlobalResetSynchronous) - /** * A simple reset implementation that punches out reset ports * for standard Module classes. Three basic reset schemes @@ -58,24 +24,16 @@ object GenerateReset { def apply(chiptop: ChipTop, clock: Clock): Reset = { implicit val p = chiptop.p // this needs directionality so generateIOFromSignal works - val reset_wire = Wire(Input(Reset())) - val (reset_io, resetIOCell) = p(GlobalResetSchemeKey) match { - case GlobalResetSynchronous => - IOCell.generateIOFromSignal(reset_wire, "reset") - case GlobalResetAsynchronousFull => - IOCell.generateIOFromSignal(reset_wire, "reset", abstractResetAsAsync = true) - case GlobalResetAsynchronous => { - val async_reset_wire = Wire(Input(AsyncReset())) - reset_wire := ResetCatchAndSync(clock, async_reset_wire.asBool()) - IOCell.generateIOFromSignal(async_reset_wire, "reset", abstractResetAsAsync = true) - } - } + val async_reset_wire = Wire(Input(AsyncReset())) + val (reset_io, resetIOCell) = IOCell.generateIOFromSignal(async_reset_wire, "reset", + abstractResetAsAsync = true) + chiptop.iocells ++= resetIOCell chiptop.harnessFunctions += ((th: HasHarnessSignalReferences) => { reset_io := th.dutReset Nil }) - reset_wire + async_reset_wire } } diff --git a/generators/chipyard/src/main/scala/ConfigFragments.scala b/generators/chipyard/src/main/scala/ConfigFragments.scala index e66dfb4a..68c41724 100644 --- a/generators/chipyard/src/main/scala/ConfigFragments.scala +++ b/generators/chipyard/src/main/scala/ConfigFragments.scala @@ -18,6 +18,7 @@ import testchipip._ import tracegen.{TraceGenSystem} import hwacha.{Hwacha} +import gemmini.{Gemmini, GemminiConfigs} import boom.common.{BoomTileAttachParams} import ariane.{ArianeTileAttachParams} @@ -105,6 +106,16 @@ class WithMultiRoCCHwacha(harts: Int*) extends Config( }) ) +class WithMultiRoCCGemmini(harts: Int*) extends Config((site, here, up) => { + case MultiRoCCKey => up(MultiRoCCKey, site) ++ harts.distinct.map { i => + (i -> Seq((p: Parameters) => { + implicit val q = p + val gemmini = LazyModule(new Gemmini(OpcodeSet.custom3, GemminiConfigs.defaultConfig)) + gemmini + })) + } +}) + class WithTraceIO extends Config((site, here, up) => { case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map { case tp: BoomTileAttachParams => tp.copy(tileParams = tp.tileParams.copy( diff --git a/generators/chipyard/src/main/scala/IOBinders.scala b/generators/chipyard/src/main/scala/IOBinders.scala index 46bed169..ab6ccdf8 100644 --- a/generators/chipyard/src/main/scala/IOBinders.scala +++ b/generators/chipyard/src/main/scala/IOBinders.scala @@ -24,8 +24,6 @@ import barstools.iocell.chisel._ import testchipip._ import icenet.{CanHavePeripheryIceNIC, SimNetwork, NicLoopback, NICKey, NICIOvonly} -import chipyard.GlobalResetSchemeKey - import scala.reflect.{ClassTag} object IOBinderTypes { @@ -154,7 +152,7 @@ class WithGPIOCells extends OverrideIOBinder({ class WithUARTIOCells extends OverrideIOBinder({ (system: HasPeripheryUARTModuleImp) => { val (ports: Seq[UARTPortIO], cells2d) = system.uart.zipWithIndex.map({ case (u, i) => - val (port, ios) = IOCell.generateIOFromSignal(u, s"uart_${i}", system.p(IOCellKey)) + val (port, ios) = IOCell.generateIOFromSignal(u, s"uart_${i}", system.p(IOCellKey), abstractResetAsAsync = true) (port, ios) }).unzip (ports, cells2d.flatten) @@ -170,8 +168,8 @@ class WithSPIIOCells extends OverrideIOBinder({ val iocellBase = s"iocell_${name}" // SCK and CS are unidirectional outputs - val sckIOs = IOCell.generateFromSignal(s.sck, port.sck, Some(s"${iocellBase}_sck"), system.p(IOCellKey)) - val csIOs = IOCell.generateFromSignal(s.cs, port.cs, Some(s"${iocellBase}_cs"), system.p(IOCellKey)) + val sckIOs = IOCell.generateFromSignal(s.sck, port.sck, Some(s"${iocellBase}_sck"), system.p(IOCellKey), IOCell.toAsyncReset) + val csIOs = IOCell.generateFromSignal(s.cs, port.cs, Some(s"${iocellBase}_cs"), system.p(IOCellKey), IOCell.toAsyncReset) // DQ are bidirectional, so then need special treatment val dqIOs = s.dq.zip(port.dq).zipWithIndex.map { case ((pin, ana), j) => @@ -193,7 +191,7 @@ class WithSPIIOCells extends OverrideIOBinder({ class WithExtInterruptIOCells extends OverrideIOBinder({ (system: HasExtInterruptsModuleImp) => { if (system.outer.nExtInterrupts > 0) { - val (port: UInt, cells) = IOCell.generateIOFromSignal(system.interrupts, "ext_interrupts", system.p(IOCellKey)) + val (port: UInt, cells) = IOCell.generateIOFromSignal(system.interrupts, "ext_interrupts", system.p(IOCellKey), abstractResetAsAsync = true) (Seq(port), cells) } else { (Nil, Nil) @@ -236,15 +234,15 @@ class WithDebugIOCells extends OverrideLazyIOBinder({ // Add IOCells for the DMI/JTAG/APB ports val dmiTuple = debug.clockeddmi.map { d => - IOCell.generateIOFromSignal(d, "dmi", p(IOCellKey), abstractResetAsAsync = p(GlobalResetSchemeKey).pinIsAsync) + IOCell.generateIOFromSignal(d, "dmi", p(IOCellKey), abstractResetAsAsync = true) } val jtagTuple = debug.systemjtag.map { j => - IOCell.generateIOFromSignal(j.jtag, "jtag", p(IOCellKey), abstractResetAsAsync = p(GlobalResetSchemeKey).pinIsAsync) + IOCell.generateIOFromSignal(j.jtag, "jtag", p(IOCellKey), abstractResetAsAsync = true) } val apbTuple = debug.apb.map { a => - IOCell.generateIOFromSignal(a, "apb", p(IOCellKey), abstractResetAsAsync = p(GlobalResetSchemeKey).pinIsAsync) + IOCell.generateIOFromSignal(a, "apb", p(IOCellKey), abstractResetAsAsync = true) } val allTuples = (dmiTuple ++ jtagTuple ++ apbTuple).toSeq @@ -257,7 +255,7 @@ class WithDebugIOCells extends OverrideLazyIOBinder({ class WithSerialTLIOCells extends OverrideIOBinder({ (system: CanHavePeripheryTLSerial) => system.serial_tl.map({ s => val sys = system.asInstanceOf[BaseSubsystem] - val (port, cells) = IOCell.generateIOFromSignal(s.getWrappedValue, "serial_tl", sys.p(IOCellKey)) + val (port, cells) = IOCell.generateIOFromSignal(s.getWrappedValue, "serial_tl", sys.p(IOCellKey), abstractResetAsAsync = true) (Seq(port), cells) }).getOrElse((Nil, Nil)) }) diff --git a/generators/chipyard/src/main/scala/TestHarness.scala b/generators/chipyard/src/main/scala/TestHarness.scala index 9c5c9d2c..c638c081 100644 --- a/generators/chipyard/src/main/scala/TestHarness.scala +++ b/generators/chipyard/src/main/scala/TestHarness.scala @@ -38,8 +38,7 @@ class TestHarness(implicit val p: Parameters) extends Module with HasHarnessSign val harnessReset = WireInit(reset) val success = io.success - // dutReset assignment can be overridden via a harnessFunction, but by default it is just reset - val dutReset = WireDefault(if (p(GlobalResetSchemeKey).pinIsAsync) reset.asAsyncReset else reset) + val dutReset = reset.asAsyncReset lazyDut match { case d: HasTestHarnessFunctions => d.harnessFunctions.foreach(_(this)) diff --git a/generators/chipyard/src/main/scala/clocking/ResetSynchronizer.scala b/generators/chipyard/src/main/scala/clocking/ResetSynchronizer.scala index 13a593c5..2ba8e855 100644 --- a/generators/chipyard/src/main/scala/clocking/ResetSynchronizer.scala +++ b/generators/chipyard/src/main/scala/clocking/ResetSynchronizer.scala @@ -12,7 +12,7 @@ import freechips.rocketchip.util.{ResetCatchAndSync} * Instantiates a reset synchronizer on all clock-reset pairs in a clock group */ class ClockGroupResetSynchronizer(implicit p: Parameters) extends LazyModule { - val node = ClockGroupIdentityNode() + val node = ClockGroupAdapterNode() lazy val module = new LazyRawModuleImp(this) { (node.out zip node.in).map { case ((oG, _), (iG, _)) => (oG.member.data zip iG.member.data).foreach { case (o, i) => diff --git a/generators/utilities/src/main/resources/csrc/emulator.cc b/generators/utilities/src/main/resources/csrc/emulator.cc index 5e0ea38b..40b5a2fa 100644 --- a/generators/utilities/src/main/resources/csrc/emulator.cc +++ b/generators/utilities/src/main/resources/csrc/emulator.cc @@ -123,6 +123,10 @@ int main(int argc, char** argv) #endif int verilog_plusargs_legal = 1; + int verilated_argc = 1; + char** verilated_argv = new char*[argc]; + verilated_argv[0] = argv[0]; + opterr = 1; while (1) { @@ -195,9 +199,15 @@ int main(int argc, char** argv) else if (arg.substr(0, 12) == "+cycle-count") c = 'c'; else if (arg == "+permissive") + { c = 'p'; + verilated_argv[verilated_argc++] = optarg; + } else if (arg == "+permissive-off") + { c = 'o'; + verilated_argv[verilated_argc++] = optarg; + } // If we don't find a legacy '+' EMULATOR argument, it still could be // a VERILOG_PLUSARG and not an error. else if (verilog_plusargs_legal) { @@ -234,12 +244,14 @@ int main(int argc, char** argv) << arg << "\"\n"; c = '?'; } else { - c = 'p'; + c = 'P'; } } goto retry; } - case 'P': break; // Nothing to do here, Verilog PlusArg + case 'P': // Verilog PlusArg, add to the argument list for verilator environment + verilated_argv[verilated_argc++] = optarg; + break; // Realize that we've hit HTIF (HOST) arguments or error out default: if (c >= HTIF_LONG_OPTIONS_OPTIND) { @@ -258,6 +270,9 @@ done_processing: return 1; } + // Copy remaining HTIF arguments (if any) and the binary file name into the verilator argument stack + while (optind < argc) verilated_argv[verilated_argc++] = argv[optind++]; + if (verbose) fprintf(stderr, "using random seed %u\n", random_seed); @@ -265,7 +280,7 @@ done_processing: srand48(random_seed); Verilated::randReset(2); - Verilated::commandArgs(argc, argv); + Verilated::commandArgs(verilated_argc, verilated_argv); TEST_HARNESS *tile = new TEST_HARNESS; #if VM_TRACE @@ -374,5 +389,6 @@ done_processing: if (tsi) delete tsi; if (jtag) delete jtag; if (tile) delete tile; + if (verilated_argv) delete[] verilated_argv; return ret; }