diff --git a/fpga/src/main/scala/arty/IOBinders.scala b/fpga/src/main/scala/arty/IOBinders.scala index c392926230..eb3185f9ae 100644 --- a/fpga/src/main/scala/arty/IOBinders.scala +++ b/fpga/src/main/scala/arty/IOBinders.scala @@ -18,6 +18,6 @@ class WithDebugResetPassthrough extends ComposeIOBinder({ val io_sjtag_reset: Bool = IO(Input(Bool())).suggestName("sjtag_reset") sjtag.reset := io_sjtag_reset - (Seq(DebugResetPort(io_ndreset), JTAGResetPort(io_sjtag_reset)), Nil) + (Seq(DebugResetPort(() => io_ndreset), JTAGResetPort(() => io_sjtag_reset)), Nil) } }) diff --git a/fpga/src/main/scala/vcu118/bringup/IOBinders.scala b/fpga/src/main/scala/vcu118/bringup/IOBinders.scala index 69dfbce969..155f264747 100644 --- a/fpga/src/main/scala/vcu118/bringup/IOBinders.scala +++ b/fpga/src/main/scala/vcu118/bringup/IOBinders.scala @@ -13,7 +13,7 @@ import testchipip.{HasPeripheryTSIHostWidget, TSIHostWidgetIO} import chipyard.iobinders.{OverrideIOBinder, Port, TLMemPort} -case class TSIHostWidgetPort(val io: TSIHostWidgetIO) +case class TSIHostWidgetPort(val getIO: () => TSIHostWidgetIO) extends Port[TSIHostWidgetIO] class WithTSITLIOPassthrough extends OverrideIOBinder({ @@ -25,6 +25,6 @@ class WithTSITLIOPassthrough extends OverrideIOBinder({ require(system.tsiSerial.size == 1) val io_tsi_serial_pins_temp = IO(DataMirror.internal.chiselTypeClone[TSIHostWidgetIO](system.tsiSerial.head)).suggestName("tsi_serial") io_tsi_serial_pins_temp <> system.tsiSerial.head - (Seq(TLMemPort(io_tsi_tl_mem_pins_temp), TSIHostWidgetPort(io_tsi_serial_pins_temp)), Nil) + (Seq(TLMemPort(() => io_tsi_tl_mem_pins_temp), TSIHostWidgetPort(() => io_tsi_serial_pins_temp)), Nil) } }) diff --git a/generators/chipyard/src/main/scala/ChipTop.scala b/generators/chipyard/src/main/scala/ChipTop.scala index 150221b6b9..2070966750 100644 --- a/generators/chipyard/src/main/scala/ChipTop.scala +++ b/generators/chipyard/src/main/scala/ChipTop.scala @@ -8,7 +8,7 @@ import freechips.rocketchip.prci.{ClockGroupIdentityNode, ClockSinkParameters, C import freechips.rocketchip.subsystem.{BaseSubsystem, SubsystemDriveAsyncClockGroupsKey} import org.chipsalliance.cde.config.{Parameters, Field} import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImp, LazyRawModuleImp, LazyModuleImpLike, BindingScope} -import freechips.rocketchip.util.{ResetCatchAndSync} +import freechips.rocketchip.util.{DontTouch} import chipyard.iobinders._ import barstools.iocell.chisel._ @@ -31,5 +31,5 @@ class ChipTop(implicit p: Parameters) extends LazyModule with BindingScope // of ChipTop (ex: ClockGroup) do not receive clock or reset. // However. anonymous children of ChipTop should not need an implicit Clock or Reset // anyways, they probably need to be explicitly clocked. - lazy val module: LazyModuleImpLike = new LazyRawModuleImp(this) { } + lazy val module: LazyModuleImpLike = new LazyRawModuleImp(this) with DontTouch { } } diff --git a/generators/chipyard/src/main/scala/clocking/ClockBinders.scala b/generators/chipyard/src/main/scala/clocking/ClockBinders.scala index 3ef8a61bdd..36d1fa2f96 100644 --- a/generators/chipyard/src/main/scala/clocking/ClockBinders.scala +++ b/generators/chipyard/src/main/scala/clocking/ClockBinders.scala @@ -75,11 +75,11 @@ class WithPLLSelectorDividerClockGenerator extends OverrideLazyIOBinder({ o.reset := reset_wire } - (Seq(ClockPort(clock_io, 100), ResetPort(reset_io)), clockIOCell ++ resetIOCell) + (Seq(ClockPort(() => clock_io, 100), ResetPort(() => reset_io)), clockIOCell ++ resetIOCell) } } }) - + // This passes all clocks through to the TestHarness class WithPassthroughClockGenerator extends OverrideLazyIOBinder({ (system: HasChipyardPRCI) => { @@ -113,9 +113,9 @@ class WithPassthroughClockGenerator extends OverrideLazyIOBinder({ val clock_io = IO(Input(Clock())).suggestName(s"clock_${m.name.get}") b.clock := clock_io b.reset := reset_io - ClockPort(clock_io, freq) + ClockPort(() => clock_io, freq) }.toSeq - ((clock_ios :+ ResetPort(reset_io)), Nil) + ((clock_ios :+ ResetPort(() => reset_io)), Nil) } } }) diff --git a/generators/chipyard/src/main/scala/config/MMIOAcceleratorConfigs.scala b/generators/chipyard/src/main/scala/config/MMIOAcceleratorConfigs.scala index 16e6b313cb..8d6f106346 100644 --- a/generators/chipyard/src/main/scala/config/MMIOAcceleratorConfigs.scala +++ b/generators/chipyard/src/main/scala/config/MMIOAcceleratorConfigs.scala @@ -9,7 +9,7 @@ import freechips.rocketchip.diplomacy.{AsynchronousCrossing} // DOC include start: FFTRocketConfig class FFTRocketConfig extends Config( - new chipyard.iobinders.WithDontTouchIOBinders(false) ++ // TODO: hack around dontTouch not working in SFC + new chipyard.harness.WithDontTouchChipTopPorts(false) ++ // TODO: hack around dontTouch not working in SFC new fftgenerator.WithFFTGenerator(numPoints=8, width=16, decPt=8) ++ // add 8-point mmio fft at the default addr (0x2400) with 16bit fixed-point numbers. new freechips.rocketchip.subsystem.WithNBigCores(1) ++ new chipyard.config.AbstractConfig) @@ -59,7 +59,7 @@ class LargeNVDLARocketConfig extends Config( new chipyard.config.AbstractConfig) class ManyMMIOAcceleratorRocketConfig extends Config( - new chipyard.iobinders.WithDontTouchIOBinders(false) ++ // TODO: hack around dontTouch not working in SFC + new chipyard.harness.WithDontTouchChipTopPorts(false) ++ // TODO: hack around dontTouch not working in SFC new fftgenerator.WithFFTGenerator(numPoints=8, width=16, decPt=8) ++ // add 8-point mmio fft at the default addr (0x2400) with 16bit fixed-point numbers. new chipyard.example.WithStreamingPassthrough ++ // use top with tilelink-controlled streaming passthrough new chipyard.example.WithStreamingFIR ++ // use top with tilelink-controlled streaming FIR diff --git a/generators/chipyard/src/main/scala/config/RocketConfigs.scala b/generators/chipyard/src/main/scala/config/RocketConfigs.scala index c45fb6f236..798b086d82 100644 --- a/generators/chipyard/src/main/scala/config/RocketConfigs.scala +++ b/generators/chipyard/src/main/scala/config/RocketConfigs.scala @@ -12,7 +12,7 @@ class RocketConfig extends Config( new chipyard.config.AbstractConfig) class TinyRocketConfig extends Config( - new chipyard.iobinders.WithDontTouchIOBinders(false) ++ // TODO FIX: Don't dontTouch the ports + new chipyard.harness.WithDontTouchChipTopPorts(false) ++ // TODO FIX: Don't dontTouch the ports new freechips.rocketchip.subsystem.WithIncoherentBusTopology ++ // use incoherent bus topology new freechips.rocketchip.subsystem.WithNBanks(0) ++ // remove L2$ new freechips.rocketchip.subsystem.WithNoMemPort ++ // remove backing memory @@ -97,6 +97,7 @@ class MulticlockRocketConfig extends Config( new chipyard.config.AbstractConfig) class CustomIOChipTopRocketConfig extends Config( + new chipyard.example.WithBrokenOutUARTIO ++ new chipyard.example.WithCustomChipTop ++ new chipyard.example.WithCustomIOCells ++ new freechips.rocketchip.subsystem.WithNBigCores(1) ++ // single rocket-core diff --git a/generators/chipyard/src/main/scala/config/TutorialConfigs.scala b/generators/chipyard/src/main/scala/config/TutorialConfigs.scala index daa082655d..edd9c438e7 100644 --- a/generators/chipyard/src/main/scala/config/TutorialConfigs.scala +++ b/generators/chipyard/src/main/scala/config/TutorialConfigs.scala @@ -77,7 +77,7 @@ class TutorialSha3BlackBoxConfig extends Config( // Tutorial Phase 5: Map a multicore heterogeneous SoC with multiple cores and memory-mapped accelerators class TutorialNoCConfig extends Config( - new chipyard.iobinders.WithDontTouchIOBinders(false) ++ + new chipyard.harness.WithDontTouchChipTopPorts(false) ++ // Try changing the dimensions of the Mesh topology new constellation.soc.WithGlobalNoC(constellation.soc.GlobalNoCParams( NoCParams( diff --git a/generators/chipyard/src/main/scala/example/CustomChipTop.scala b/generators/chipyard/src/main/scala/example/CustomChipTop.scala index f2ebfc3309..f710ccab62 100644 --- a/generators/chipyard/src/main/scala/example/CustomChipTop.scala +++ b/generators/chipyard/src/main/scala/example/CustomChipTop.scala @@ -5,9 +5,11 @@ import chipyard.iobinders._ import org.chipsalliance.cde.config._ import freechips.rocketchip.diplomacy.{InModuleBody} +import freechips.rocketchip.subsystem.{PBUS, HasTileLinkLocations} import barstools.iocell.chisel._ import chipyard._ import chipyard.harness.{BuildTop} +import sifive.blocks.devices.uart._ // A "custom" IOCell with additional I/O // The IO don't do anything here in this example @@ -63,3 +65,21 @@ class WithCustomIOCells extends Config((site, here, up) => { class WithCustomChipTop extends Config((site, here, up) => { case BuildTop => (p: Parameters) => new CustomChipTop()(p) }) + +class WithBrokenOutUARTIO extends OverrideIOBinder({ + (system: HasPeripheryUARTModuleImp) => { + val uart_txd = IO(Output(Bool())) + val uart_rxd = IO(Input(Bool())) + system.uart(0).rxd := uart_rxd + uart_txd := system.uart(0).txd + val where = PBUS // TODO fix + val bus = system.outer.asInstanceOf[HasTileLinkLocations].locateTLBusWrapper(where) + val freqMHz = bus.dtsFrequency.get / 1000000 + (Seq(UARTPort(() => { + val uart_wire = Wire(new UARTPortIO(system.uart(0).c)) + uart_wire.txd := uart_txd + uart_rxd := uart_wire.rxd + uart_wire + }, 0, freqMHz.toInt)), Nil) + } +}) diff --git a/generators/chipyard/src/main/scala/example/FlatChipTop.scala b/generators/chipyard/src/main/scala/example/FlatChipTop.scala index 165f918657..b51a66cda5 100644 --- a/generators/chipyard/src/main/scala/example/FlatChipTop.scala +++ b/generators/chipyard/src/main/scala/example/FlatChipTop.scala @@ -86,8 +86,8 @@ class FlatChipTop(implicit p: Parameters) extends LazyModule with HasChipyardPor o.reset := reset_wire } - ports = ports :+ ClockPort(clock_pad, 100.0) - ports = ports :+ ResetPort(reset_pad) + ports = ports :+ ClockPort(() => clock_pad, 100.0) + ports = ports :+ ResetPort(() => reset_pad) // For a real chip you should replace this ClockSourceAtFreqFromPlusArg // with a blackbox of whatever PLL is being integrated @@ -104,13 +104,13 @@ class FlatChipTop(implicit p: Parameters) extends LazyModule with HasChipyardPor // Custom Boot //========================= val (custom_boot_pad, customBootIOCell) = IOCell.generateIOFromSignal(system.custom_boot_pin.get.getWrappedValue, "custom_boot", p(IOCellKey)) - ports = ports :+ CustomBootPort(custom_boot_pad) + ports = ports :+ CustomBootPort(() => custom_boot_pad) //========================= // Serialized TileLink //========================= val (serial_tl_pad, serialTLIOCells) = IOCell.generateIOFromSignal(system.serial_tl.get.getWrappedValue, "serial_tl", p(IOCellKey)) - ports = ports :+ SerialTLPort(serial_tl_pad, p(SerialTLKey).get, system.serdesser.get, 0) + ports = ports :+ SerialTLPort(() => serial_tl_pad, p(SerialTLKey).get, system.serdesser.get, 0) //========================= // JTAG/Debug @@ -149,7 +149,7 @@ class FlatChipTop(implicit p: Parameters) extends LazyModule with HasChipyardPor IOCell.generateIOFromSignal(jtag_wire, "jtag", p(IOCellKey), abstractResetAsAsync = true) }.get - ports = ports :+ JTAGPort(jtag_pad) + ports = ports :+ JTAGPort(() => jtag_pad) //========================== // UART @@ -159,7 +159,7 @@ class FlatChipTop(implicit p: Parameters) extends LazyModule with HasChipyardPor val where = PBUS // TODO fix val bus = system.asInstanceOf[HasTileLinkLocations].locateTLBusWrapper(where) val freqMHz = bus.dtsFrequency.get / 1000000 - ports = ports :+ UARTPort(uart_pad, 0, freqMHz.toInt) + ports = ports :+ UARTPort(() => uart_pad, 0, freqMHz.toInt) //========================== // External interrupts (tie off) diff --git a/generators/chipyard/src/main/scala/harness/HasHarnessInstantiators.scala b/generators/chipyard/src/main/scala/harness/HasHarnessInstantiators.scala index 9052bc7719..06e039bde0 100644 --- a/generators/chipyard/src/main/scala/harness/HasHarnessInstantiators.scala +++ b/generators/chipyard/src/main/scala/harness/HasHarnessInstantiators.scala @@ -5,7 +5,7 @@ import chisel3._ import scala.collection.mutable.{ArrayBuffer, LinkedHashMap} import freechips.rocketchip.diplomacy.{LazyModule} import org.chipsalliance.cde.config.{Field, Parameters, Config} -import freechips.rocketchip.util.{ResetCatchAndSync} +import freechips.rocketchip.util.{ResetCatchAndSync, DontTouch} import freechips.rocketchip.prci.{ClockBundle, ClockBundleParameters, ClockSinkParameters, ClockParameters} import chipyard.stage.phases.TargetDirKey @@ -24,6 +24,7 @@ case object BuildTop extends Field[Parameters => LazyModule]((p: Parameters) => case object HarnessClockInstantiatorKey extends Field[() => HarnessClockInstantiator]() case object HarnessBinderClockFrequencyKey extends Field[Double](100.0) // MHz case object MultiChipIdx extends Field[Int](0) +case object DontTouchChipTopPorts extends Field[Boolean](true) class WithMultiChip(id: Int, p: Parameters) extends Config((site, here, up) => { case MultiChipParameters(`id`) => p @@ -39,6 +40,10 @@ class WithHarnessBinderClockFreqMHz(freqMHz: Double) extends Config((site, here, case HarnessBinderClockFrequencyKey => freqMHz }) +class WithDontTouchChipTopPorts(b: Boolean = true) extends Config((site, here, up) => { + case DontTouchChipTopPorts => b +}) + // A TestHarness mixing this in will // - use the HarnessClockInstantiator clock provide trait HasHarnessInstantiators { @@ -83,12 +88,18 @@ trait HasHarnessInstantiators { withClockAndReset (harnessBinderClock, harnessBinderReset) { lazyDuts.zipWithIndex.foreach { - case (d: HasChipyardPorts, i: Int) => ApplyHarnessBinders(this, d.ports)(chipParameters(i)) + case (d: HasChipyardPorts, i: Int) => { + ApplyHarnessBinders(this, d.ports)(chipParameters(i)) + } case _ => } ApplyMultiHarnessBinders(this, lazyDuts) } + duts.map(_ match { + case d: DontTouch => d.dontTouchPorts() + }) + val harnessBinderClk = harnessClockInstantiator.requestClockMHz("harnessbinder_clock", getHarnessBinderClockFreqMHz) println(s"Harness binder clock is $harnessBinderClockFreq") harnessBinderClock := harnessBinderClk diff --git a/generators/chipyard/src/main/scala/iobinders/IOBinders.scala b/generators/chipyard/src/main/scala/iobinders/IOBinders.scala index 4b5ac1c67d..c039154acb 100644 --- a/generators/chipyard/src/main/scala/iobinders/IOBinders.scala +++ b/generators/chipyard/src/main/scala/iobinders/IOBinders.scala @@ -51,12 +51,6 @@ case object IOBinders extends Field[Map[String, Seq[IOBinderFunction]]]( Map[String, Seq[IOBinderFunction]]().withDefaultValue(Nil) ) -case object DontTouchIOBindersPorts extends Field[Boolean](true) - -class WithDontTouchIOBinders(b: Boolean = true) extends Config((site, here, up) => { - case DontTouchIOBindersPorts => b -}) - abstract trait HasIOBinders extends HasChipyardPorts { this: LazyModule => val lazySystem: LazyModule private val iobinders = p(IOBinders) @@ -84,10 +78,6 @@ abstract trait HasIOBinders extends HasChipyardPorts { this: LazyModule => def ports = portMap.getWrappedValue.values.flatten.toSeq InModuleBody { - if (p(DontTouchIOBindersPorts)) { - portMap.values.flatten.foreach { case (port: Port[Data]) => dontTouch(port.io) } - } - println("IOCells generated by IOBinders:") for ((k, v) <- iocellMap) { if (!v.isEmpty) { @@ -174,7 +164,7 @@ class WithGPIOCells extends OverrideIOBinder({ iocell.io.ie := pin.o.ie pin.i.ival := iocell.io.i iocell.io.pad <> g - (GPIOPort(g, i, j), iocell) + (GPIOPort(() => g, i, j), iocell) }).unzip }).unzip (ports2d.flatten, cells2d.flatten) @@ -186,7 +176,7 @@ class WithGPIOPunchthrough extends OverrideIOBinder({ val ports = system.gpio.zipWithIndex.map { case (gpio, i) => val io_gpio = IO(gpio.cloneType).suggestName(s"gpio_$i") io_gpio <> gpio - GPIOPinsPort(io_gpio, i) + GPIOPinsPort(() => io_gpio, i) } (ports, Nil) } @@ -197,7 +187,7 @@ class WithI2CPunchthrough extends OverrideIOBinder({ val ports = system.i2c.zipWithIndex.map { case (i2c, i) => val io_i2c = IO(i2c.cloneType).suggestName(s"i2c_$i") io_i2c <> i2c - I2CPort(i2c) + I2CPort(() => i2c) } (ports, Nil) } @@ -211,7 +201,7 @@ class WithUARTIOCells extends OverrideIOBinder({ val where = PBUS // TODO fix val bus = system.outer.asInstanceOf[HasTileLinkLocations].locateTLBusWrapper(where) val freqMHz = bus.dtsFrequency.get / 1000000 - (UARTPort(port, i, freqMHz.toInt), ios) + (UARTPort(() => port, i, freqMHz.toInt), ios) }).unzip (ports, cells2d.flatten) } @@ -229,7 +219,7 @@ class WithSPIIOPunchthrough extends OverrideLazyIOBinder({ val ports = spi.zipWithIndex.map({ case (s, i) => val io_spi = IO(s.cloneType).suggestName(s"spi_$i") io_spi <> s - SPIPort(io_spi) + SPIPort(() => io_spi) }) (ports, Nil) } @@ -259,7 +249,7 @@ class WithSPIFlashIOCells extends OverrideIOBinder({ iocell } - (SPIFlashPort(port, system.p(PeripherySPIFlashKey)(i), i), dqIOs ++ csIOs ++ sckIOs) + (SPIFlashPort(() => port, system.p(PeripherySPIFlashKey)(i), i), dqIOs ++ csIOs ++ sckIOs) }).unzip (ports, cells2d.flatten) } @@ -269,7 +259,7 @@ class WithExtInterruptIOCells extends OverrideIOBinder({ (system: HasExtInterruptsModuleImp) => { if (system.outer.nExtInterrupts > 0) { val (port: UInt, cells) = IOCell.generateIOFromSignal(system.interrupts, "ext_interrupts", system.p(IOCellKey), abstractResetAsAsync = true) - (Seq(ExtIntPort(port)), cells) + (Seq(ExtIntPort(() => port)), cells) } else { system.interrupts := DontCare // why do I have to drive this 0-wide wire??? (Nil, Nil) @@ -320,7 +310,7 @@ class WithDebugIOCells extends OverrideLazyIOBinder({ // Add IOCells for the DMI/JTAG/APB ports val dmiTuple = debug.clockeddmi.map { d => val (port, cells) = IOCell.generateIOFromSignal(d, "dmi", p(IOCellKey), abstractResetAsAsync = true) - (DMIPort(port), cells) + (DMIPort(() => port), cells) } val jtagTuple = debug.systemjtag.map { j => @@ -330,7 +320,7 @@ class WithDebugIOCells extends OverrideLazyIOBinder({ j.jtag.TDI := jtag_wire.TDI jtag_wire.TDO := j.jtag.TDO.data val (port, cells) = IOCell.generateIOFromSignal(jtag_wire, "jtag", p(IOCellKey), abstractResetAsAsync = true) - (JTAGPort(port), cells) + (JTAGPort(() => port), cells) } require(!debug.apb.isDefined) @@ -347,7 +337,7 @@ class WithSerialTLIOCells extends OverrideIOBinder({ val (ports, cells) = system.serial_tl.zipWithIndex.map({ case (s, id) => val sys = system.asInstanceOf[BaseSubsystem] val (port, cells) = IOCell.generateIOFromSignal(s.getWrappedValue, "serial_tl", sys.p(IOCellKey), abstractResetAsAsync = true) - (SerialTLPort(port, sys.p(SerialTLKey).get, system.serdesser.get, id), cells) + (SerialTLPort(() => port, sys.p(SerialTLKey).get, system.serdesser.get, id), cells) }).unzip (ports.toSeq, cells.flatten.toSeq) } @@ -359,7 +349,7 @@ class WithSerialTLPunchthrough extends OverrideIOBinder({ val sys = system.asInstanceOf[BaseSubsystem] val port = IO(s.getWrappedValue.cloneType) port <> s.getWrappedValue - (SerialTLPort(port, sys.p(SerialTLKey).get, system.serdesser.get, id), Nil) + (SerialTLPort(() => port, sys.p(SerialTLKey).get, system.serdesser.get, id), Nil) }).unzip (ports.toSeq, cells.flatten.toSeq) } @@ -377,7 +367,7 @@ class WithAXI4MemPunchthrough extends OverrideLazyIOBinder({ val port = IO(new ClockedIO(DataMirror.internal.chiselTypeClone[AXI4Bundle](m))).suggestName(s"axi4_mem_${i}") port.bits <> m port.clock := clockBundle.clock - AXI4MemPort(port, p(ExtMem).get, system.memAXI4Node.edges.in(i), p(MemoryBusKey).dtsFrequency.get.toInt) + AXI4MemPort(() => port, p(ExtMem).get, system.memAXI4Node.edges.in(i), p(MemoryBusKey).dtsFrequency.get.toInt) }).toSeq (ports, Nil) } @@ -396,7 +386,7 @@ class WithAXI4MMIOPunchthrough extends OverrideLazyIOBinder({ val port = IO(new ClockedIO(DataMirror.internal.chiselTypeClone[AXI4Bundle](m))).suggestName(s"axi4_mmio_${i}") port.bits <> m port.clock := clockBundle.clock - AXI4MMIOPort(port, p(ExtBus).get, system.mmioAXI4Node.edges.in(i)) + AXI4MMIOPort(() => port, p(ExtBus).get, system.mmioAXI4Node.edges.in(i)) }).toSeq (ports, Nil) } @@ -415,7 +405,7 @@ class WithL2FBusAXI4Punchthrough extends OverrideLazyIOBinder({ val port = IO(new ClockedIO(Flipped(DataMirror.internal.chiselTypeClone[AXI4Bundle](m)))).suggestName(s"axi4_fbus_${i}") m <> port.bits port.clock := clockBundle.clock - AXI4InPort(port, p(ExtIn).get) + AXI4InPort(() => port, p(ExtIn).get) }).toSeq (ports, Nil) } @@ -429,7 +419,7 @@ class WithBlockDeviceIOPunchthrough extends OverrideIOBinder({ val bdParams = p(BlockDeviceKey).get val port = IO(new ClockedIO(new BlockDeviceIO(bdParams))).suggestName("blockdev") port <> bdev - BlockDevicePort(port, bdParams) + BlockDevicePort(() => port, bdParams) }).toSeq (ports, Nil) } @@ -441,7 +431,7 @@ class WithNICIOPunchthrough extends OverrideIOBinder({ val p = GetSystemParameters(system) val port = IO(new ClockedIO(new NICIOvonly)).suggestName("nic") port <> n - NICPort(port, p(NICKey).get) + NICPort(() => port, p(NICKey).get) }).toSeq (ports, Nil) } @@ -451,7 +441,7 @@ class WithTraceGenSuccessPunchthrough extends OverrideIOBinder({ (system: TraceGenSystemModuleImp) => { val success: Bool = IO(Output(Bool())).suggestName("success") success := system.success - (Seq(SuccessPort(success)), Nil) + (Seq(SuccessPort(() => success)), Nil) } }) @@ -474,7 +464,7 @@ class WithTraceIOPunchthrough extends OverrideIOBinder({ bootrom = chipyardSystem.bootROM.map(_.module.contents.toArray.mkString(" ")).getOrElse(""), has_dtm = p(ExportDebug).protocols.contains(DMI) // assume that exposing clockeddmi means we will connect SimDTM ) - TracePort(trace, cfg) + TracePort(() => trace, cfg) } (ports.toSeq, Nil) } @@ -484,7 +474,7 @@ class WithCustomBootPin extends OverrideIOBinder({ (system: CanHavePeripheryCustomBootPin) => system.custom_boot_pin.map({ p => val sys = system.asInstanceOf[BaseSubsystem] val (port, cells) = IOCell.generateIOFromSignal(p.getWrappedValue, "custom_boot", sys.p(IOCellKey), abstractResetAsAsync = true) - (Seq(CustomBootPort(port)), cells) + (Seq(CustomBootPort(() => port)), cells) }).getOrElse((Nil, Nil)) }) @@ -493,7 +483,7 @@ class WithUARTTSIPunchthrough extends OverrideIOBinder({ val sys = system.asInstanceOf[BaseSubsystem] val uart_tsi = IO(new UARTTSIIO(p.uartParams)) uart_tsi <> p - (Seq(UARTTSIPort(uart_tsi)), Nil) + (Seq(UARTTSIPort(() => uart_tsi)), Nil) }).getOrElse((Nil, Nil)) }) @@ -501,7 +491,7 @@ class WithTLMemPunchthrough extends OverrideIOBinder({ (system: CanHaveMasterTLMemPort) => { val io_tl_mem_pins_temp = IO(DataMirror.internal.chiselTypeClone[HeterogeneousBag[TLBundle]](system.mem_tl)).suggestName("tl_slave") io_tl_mem_pins_temp <> system.mem_tl - (Seq(TLMemPort(io_tl_mem_pins_temp)), Nil) + (Seq(TLMemPort(() => io_tl_mem_pins_temp)), Nil) } }) diff --git a/generators/chipyard/src/main/scala/iobinders/Ports.scala b/generators/chipyard/src/main/scala/iobinders/Ports.scala index 391d3baf4f..c5c9f19eb8 100644 --- a/generators/chipyard/src/main/scala/iobinders/Ports.scala +++ b/generators/chipyard/src/main/scala/iobinders/Ports.scala @@ -16,7 +16,9 @@ import freechips.rocketchip.util.{HeterogeneousBag} import freechips.rocketchip.tilelink.{TLBundle} trait Port[T <: Data] { - val io: T + val getIO: () => T + // port.io should only be called in the TestHarness context + lazy val io = getIO() } trait HasChipyardPorts { @@ -24,75 +26,75 @@ trait HasChipyardPorts { } // These case classes are generated by IOBinders, and interpreted by HarnessBinders -case class GPIOPort (val io: Analog, val gpioId: Int, val pinId: Int) +case class GPIOPort (val getIO: () => Analog, val gpioId: Int, val pinId: Int) extends Port[Analog] -case class GPIOPinsPort (val io: GPIOPortIO, val gpioId: Int) +case class GPIOPinsPort (val getIO: () => GPIOPortIO, val gpioId: Int) extends Port[GPIOPortIO] -case class I2CPort (val io: sifive.blocks.devices.i2c.I2CPort) +case class I2CPort (val getIO: () => sifive.blocks.devices.i2c.I2CPort) extends Port[sifive.blocks.devices.i2c.I2CPort] -case class UARTPort (val io: UARTPortIO, val uartNo: Int, val freqMHz: Int) +case class UARTPort (val getIO: () => UARTPortIO, val uartNo: Int, val freqMHz: Int) extends Port[UARTPortIO] -case class SPIFlashPort (val io: SPIChipIO, val params: SPIFlashParams, val spiId: Int) +case class SPIFlashPort (val getIO: () => SPIChipIO, val params: SPIFlashParams, val spiId: Int) extends Port[SPIChipIO] -case class SPIPort (val io: SPIPortIO) +case class SPIPort (val getIO: () => SPIPortIO) extends Port[SPIPortIO] -case class BlockDevicePort (val io: ClockedIO[BlockDeviceIO], val params: BlockDeviceConfig) +case class BlockDevicePort (val getIO: () => ClockedIO[BlockDeviceIO], val params: BlockDeviceConfig) extends Port[ClockedIO[BlockDeviceIO]] -case class NICPort (val io: ClockedIO[NICIOvonly], val params: NICConfig) +case class NICPort (val getIO: () => ClockedIO[NICIOvonly], val params: NICConfig) extends Port[ClockedIO[NICIOvonly]] -case class AXI4MemPort (val io: ClockedIO[AXI4Bundle], val params: MemoryPortParams, val edge: AXI4EdgeParameters, val clockFreqMHz: Int) +case class AXI4MemPort (val getIO: () => ClockedIO[AXI4Bundle], val params: MemoryPortParams, val edge: AXI4EdgeParameters, val clockFreqMHz: Int) extends Port[ClockedIO[AXI4Bundle]] -case class AXI4MMIOPort (val io: ClockedIO[AXI4Bundle], val params: MasterPortParams, val edge: AXI4EdgeParameters) +case class AXI4MMIOPort (val getIO: () => ClockedIO[AXI4Bundle], val params: MasterPortParams, val edge: AXI4EdgeParameters) extends Port[ClockedIO[AXI4Bundle]] -case class AXI4InPort (val io: ClockedIO[AXI4Bundle], val params: SlavePortParams) +case class AXI4InPort (val getIO: () => ClockedIO[AXI4Bundle], val params: SlavePortParams) extends Port[ClockedIO[AXI4Bundle]] -case class ExtIntPort (val io: UInt) +case class ExtIntPort (val getIO: () => UInt) extends Port[UInt] -case class DMIPort (val io: ClockedDMIIO) +case class DMIPort (val getIO: () => ClockedDMIIO) extends Port[ClockedDMIIO] -case class JTAGPort (val io: JTAGChipIO) +case class JTAGPort (val getIO: () => JTAGChipIO) extends Port[JTAGChipIO] -case class SerialTLPort (val io: ClockedIO[SerialIO], val params: SerialTLParams, val serdesser: TLSerdesser, val portId: Int) +case class SerialTLPort (val getIO: () => ClockedIO[SerialIO], val params: SerialTLParams, val serdesser: TLSerdesser, val portId: Int) extends Port[ClockedIO[SerialIO]] -case class UARTTSIPort (val io: UARTTSIIO) +case class UARTTSIPort (val getIO: () => UARTTSIIO) extends Port[UARTTSIIO] -case class SuccessPort (val io: Bool) +case class SuccessPort (val getIO: () => Bool) extends Port[Bool] -case class TracePort (val io: TraceOutputTop, val cosimCfg: SpikeCosimConfig) +case class TracePort (val getIO: () => TraceOutputTop, val cosimCfg: SpikeCosimConfig) extends Port[TraceOutputTop] -case class CustomBootPort (val io: Bool) +case class CustomBootPort (val getIO: () => Bool) extends Port[Bool] -case class ClockPort (val io: Clock, val freqMHz: Double) +case class ClockPort (val getIO: () => Clock, val freqMHz: Double) extends Port[Clock] -case class ResetPort (val io: AsyncReset) +case class ResetPort (val getIO: () => AsyncReset) extends Port[Reset] -case class DebugResetPort (val io: Reset) +case class DebugResetPort (val getIO: () => Reset) extends Port[Reset] -case class JTAGResetPort (val io: Reset) +case class JTAGResetPort (val getIO: () => Reset) extends Port[Reset] -case class TLMemPort (val io: HeterogeneousBag[TLBundle]) +case class TLMemPort (val getIO: () => HeterogeneousBag[TLBundle]) extends Port[HeterogeneousBag[TLBundle]]