Clean up passing ports from IOBinders to HarnessBinders

This commit is contained in:
Jerry Zhao
2020-09-08 21:52:50 -07:00
parent 11a9ad2428
commit 8f9574fd79
2 changed files with 114 additions and 164 deletions

View File

@@ -1,6 +1,7 @@
package chipyard.harness package chipyard.harness
import chisel3._ import chisel3._
import chisel3.experimental.{Analog}
import freechips.rocketchip.config.{Field, Config, Parameters} import freechips.rocketchip.config.{Field, Config, Parameters}
import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImpLike} import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImpLike}
@@ -19,6 +20,7 @@ import barstools.iocell.chisel._
import testchipip._ import testchipip._
import chipyard.HasHarnessSignalReferences import chipyard.HasHarnessSignalReferences
import chipyard.iobinders.ClockedIO
import tracegen.{TraceGenSystemModuleImp} import tracegen.{TraceGenSystemModuleImp}
import icenet.{CanHavePeripheryIceNICModuleImp, SimNetwork, NicLoopback, NICKey, NICIOvonly} import icenet.{CanHavePeripheryIceNICModuleImp, SimNetwork, NicLoopback, NICKey, NICIOvonly}
@@ -33,26 +35,29 @@ case object HarnessBinders extends Field[Map[String, (Any, HasHarnessSignalRefer
object ApplyHarnessBinders { object ApplyHarnessBinders {
def apply(th: HasHarnessSignalReferences, sys: LazyModule, map: Map[String, (Any, HasHarnessSignalReferences, Seq[Data]) => Seq[Any]], portMap: Map[String, Seq[Data]]) = { def apply(th: HasHarnessSignalReferences, sys: LazyModule, map: Map[String, (Any, HasHarnessSignalReferences, Seq[Data]) => Seq[Any]], portMap: Map[String, Seq[Data]]) = {
val pm = portMap.withDefaultValue(Nil) val pm = portMap.withDefaultValue(Nil)
map.map { case (s, f) => f(sys, th, pm(s)) ++ f(sys.module, th, pm(s)) } map.map { case (s, f) => f(sys, th, pm(s)) ++ f(sys.module, th, pm(s))
}
} }
} }
class OverrideHarnessBinder[T](fn: => (T, HasHarnessSignalReferences, Seq[Data]) => Seq[Any])(implicit tag: ClassTag[T]) extends Config((site, here, up) => { class OverrideHarnessBinder[T, S <: Data](fn: => (T, HasHarnessSignalReferences, Seq[S]) => Seq[Any])(implicit tag: ClassTag[T]) extends Config((site, here, up) => {
case HarnessBinders => up(HarnessBinders, site) + (tag.runtimeClass.toString -> case HarnessBinders => up(HarnessBinders, site) + (tag.runtimeClass.toString ->
((t: Any, th: HasHarnessSignalReferences, ports: Seq[Data]) => { ((t: Any, th: HasHarnessSignalReferences, ports: Seq[Data]) => {
val pts = ports.map(_.asInstanceOf[S])
t match { t match {
case system: T => fn(system, th, ports) case system: T => fn(system, th, pts)
case _ => Nil case _ => Nil
} }
}) })
) )
}) })
class ComposeHarnessBinder[T](fn: => (T, HasHarnessSignalReferences, Seq[Data]) => Seq[Any])(implicit tag: ClassTag[T]) extends Config((site, here, up) => { class ComposeHarnessBinder[T, S <: Data](fn: => (T, HasHarnessSignalReferences, Seq[S]) => Seq[Any])(implicit tag: ClassTag[T]) extends Config((site, here, up) => {
case HarnessBinders => up(HarnessBinders, site) + (tag.runtimeClass.toString -> case HarnessBinders => up(HarnessBinders, site) + (tag.runtimeClass.toString ->
((t: Any, th: HasHarnessSignalReferences, ports: Seq[Data]) => { ((t: Any, th: HasHarnessSignalReferences, ports: Seq[Data]) => {
val pts = ports.map(_.asInstanceOf[S])
t match { t match {
case system: T => up(HarnessBinders, site)(tag.runtimeClass.toString)(system, th, ports) ++ fn(system, th, ports) case system: T => up(HarnessBinders, site)(tag.runtimeClass.toString)(system, th, pts) ++ fn(system, th, pts)
case _ => Nil case _ => Nil
} }
}) })
@@ -60,109 +65,83 @@ class ComposeHarnessBinder[T](fn: => (T, HasHarnessSignalReferences, Seq[Data])
}) })
class WithGPIOTiedOff extends OverrideHarnessBinder({ class WithGPIOTiedOff extends OverrideHarnessBinder({
(system: HasPeripheryGPIOModuleImp, th: HasHarnessSignalReferences, ports: Seq[Data]) => { (system: HasPeripheryGPIOModuleImp, th: HasHarnessSignalReferences, ports: Seq[Analog]) => {
ports.map { case p: GPIOPortIO => p <> AnalogConst(0) } ports.foreach { _ <> AnalogConst(0) }
Nil Nil
} }
}) })
// DOC include start: WithUARTAdapter // DOC include start: WithUARTAdapter
class WithUARTAdapter extends OverrideHarnessBinder({ class WithUARTAdapter extends OverrideHarnessBinder({
(system: HasPeripheryUARTModuleImp, th: HasHarnessSignalReferences, ports: Seq[Data]) => { (system: HasPeripheryUARTModuleImp, th: HasHarnessSignalReferences, ports: Seq[UARTPortIO]) => {
UARTAdapter.connect(ports.map({case p: UARTPortIO => p}))(system.p) UARTAdapter.connect(ports)(system.p)
Nil Nil
} }
}) })
// DOC include end: WithUARTAdapter // DOC include end: WithUARTAdapter
class WithSimSPIFlashModel(rdOnly: Boolean = true) extends OverrideHarnessBinder({ class WithSimSPIFlashModel(rdOnly: Boolean = true) extends OverrideHarnessBinder({
(system: HasPeripherySPIFlashModuleImp, th: HasHarnessSignalReferences, ports: Seq[Data]) => { (system: HasPeripherySPIFlashModuleImp, th: HasHarnessSignalReferences, ports: Seq[SPIChipIO]) => {
SimSPIFlashModel.connect(ports.map({case p: SPIChipIO => p}), th.harnessReset, rdOnly)(system.p) SimSPIFlashModel.connect(ports, th.harnessReset, rdOnly)(system.p)
Nil Nil
} }
}) })
class WithSimBlockDevice extends OverrideHarnessBinder({ class WithSimBlockDevice extends OverrideHarnessBinder({
(system: CanHavePeripheryBlockDeviceModuleImp, th: HasHarnessSignalReferences, ports: Seq[Data]) => { (system: CanHavePeripheryBlockDeviceModuleImp, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[BlockDeviceIO]]) => {
val clock = WireInit(false.B.asClock) ports.map { p => SimBlockDevice.connect(p.clock, th.harnessReset.asBool, Some(p.bits))(system.p) }
ports.map {
case p: BlockDeviceIO => SimBlockDevice.connect(clock, th.harnessReset.asBool, Some(p))(system.p)
case c: Clock => clock := c
}
Nil Nil
} }
}) })
class WithBlockDeviceModel extends OverrideHarnessBinder({ class WithBlockDeviceModel extends OverrideHarnessBinder({
(system: CanHavePeripheryBlockDeviceModuleImp, th: HasHarnessSignalReferences, ports: Seq[Data]) => { (system: CanHavePeripheryBlockDeviceModuleImp, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[BlockDeviceIO]]) => {
val clock = WireInit(false.B.asClock) ports.map { p => withClockAndReset(p.clock, th.harnessReset) { BlockDeviceModel.connect(Some(p.bits))(system.p) } }
ports.map {
case p: BlockDeviceIO => withClockAndReset(clock, th.harnessReset) { BlockDeviceModel.connect(Some(p))(system.p) }
case c: Clock => clock := c
}
Nil Nil
} }
}) })
class WithLoopbackNIC extends OverrideHarnessBinder({ class WithLoopbackNIC extends OverrideHarnessBinder({
(system: CanHavePeripheryIceNICModuleImp, th: HasHarnessSignalReferences, ports: Seq[Data]) => { (system: CanHavePeripheryIceNICModuleImp, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[NICIOvonly]]) => {
val clock = WireInit(false.B.asClock) ports.map { p =>
ports.map { withClockAndReset(p.clock, th.harnessReset) {
case p: NICIOvonly => withClockAndReset(clock, th.harnessReset) { NicLoopback.connect(Some(p.bits), system.p(NICKey))
NicLoopback.connect(Some(p), system.p(NICKey))
} }
case c: Clock => clock := c
} }
Nil Nil
} }
}) })
class WithSimNetwork extends OverrideHarnessBinder({ class WithSimNetwork extends OverrideHarnessBinder({
(system: CanHavePeripheryIceNICModuleImp, th: HasHarnessSignalReferences, ports: Seq[Data]) => { (system: CanHavePeripheryIceNICModuleImp, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[NICIOvonly]]) => {
val clock = WireInit(false.B.asClock) ports.map { p => SimNetwork.connect(Some(p.bits), p.clock, th.harnessReset.asBool) }
ports.map {
case p: NICIOvonly => SimNetwork.connect(Some(p), clock, th.harnessReset.asBool)
case c: Clock => clock := c
}
Nil Nil
} }
}) })
class WithSimAXIMem extends OverrideHarnessBinder({ class WithSimAXIMem extends OverrideHarnessBinder({
(system: CanHaveMasterAXI4MemPort, th: HasHarnessSignalReferences, ports: Seq[Data]) => { (system: CanHaveMasterAXI4MemPort, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[AXI4Bundle]]) => {
val p: Parameters = chipyard.iobinders.GetSystemParameters(system) val p: Parameters = chipyard.iobinders.GetSystemParameters(system)
val clock = WireInit(false.B.asClock) (ports zip system.memAXI4Node.edges.in).map { case (port, edge) =>
ports.map {
case p: Clock => clock := p
case _ =>
}
val axi4_ports = ports.collect { case p: AXI4Bundle => p }
(axi4_ports zip system.memAXI4Node.edges.in).map { case (port: AXI4Bundle, edge) =>
val mem = LazyModule(new SimAXIMem(edge, size=p(ExtMem).get.master.size)(p)) val mem = LazyModule(new SimAXIMem(edge, size=p(ExtMem).get.master.size)(p))
withClockAndReset(clock, th.harnessReset) { withClockAndReset(port.clock, th.harnessReset) {
Module(mem.module).suggestName("mem") Module(mem.module).suggestName("mem")
} }
mem.io_axi4.head <> port mem.io_axi4.head <> port.bits
} }
Nil Nil
} }
}) })
class WithBlackBoxSimMem extends OverrideHarnessBinder({ class WithBlackBoxSimMem extends OverrideHarnessBinder({
(system: CanHaveMasterAXI4MemPort, th: HasHarnessSignalReferences, ports: Seq[Data]) => { (system: CanHaveMasterAXI4MemPort, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[AXI4Bundle]]) => {
val p: Parameters = chipyard.iobinders.GetSystemParameters(system) val p: Parameters = chipyard.iobinders.GetSystemParameters(system)
val clock = WireInit(false.B.asClock) (ports zip system.memAXI4Node.edges.in).map { case (port, edge) =>
ports.map {
case p: Clock => clock := p
case _ =>
}
val axi4_ports = ports.collect { case p: AXI4Bundle => p }
(axi4_ports zip system.memAXI4Node.edges.in).map { case (port: AXI4Bundle, edge) =>
val memSize = p(ExtMem).get.master.size val memSize = p(ExtMem).get.master.size
val lineSize = p(CacheBlockBytes) val lineSize = p(CacheBlockBytes)
val mem = Module(new SimDRAM(memSize, lineSize, edge.bundle)).suggestName("simdram") val mem = Module(new SimDRAM(memSize, lineSize, edge.bundle)).suggestName("simdram")
mem.io.axi <> port mem.io.axi <> port.bits
mem.io.clock := clock mem.io.clock := port.clock
mem.io.reset := th.harnessReset mem.io.reset := th.harnessReset
} }
Nil Nil
@@ -170,57 +149,44 @@ class WithBlackBoxSimMem extends OverrideHarnessBinder({
}) })
class WithSimAXIMMIO extends OverrideHarnessBinder({ class WithSimAXIMMIO extends OverrideHarnessBinder({
(system: CanHaveMasterAXI4MMIOPort, th: HasHarnessSignalReferences, ports: Seq[Data]) => { (system: CanHaveMasterAXI4MMIOPort, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[AXI4Bundle]]) => {
val p: Parameters = chipyard.iobinders.GetSystemParameters(system) val p: Parameters = chipyard.iobinders.GetSystemParameters(system)
val clock = WireInit(false.B.asClock) (ports zip system.mmioAXI4Node.edges.in).map { case (port, edge) =>
ports.map {
case p: Clock => clock := p
case _ =>
}
val axi4_ports = ports.collect { case p: AXI4Bundle => p }
(axi4_ports zip system.mmioAXI4Node.edges.in).map { case (port: AXI4Bundle, edge) =>
val mmio_mem = LazyModule(new SimAXIMem(edge, size = p(ExtBus).get.size)(p)) val mmio_mem = LazyModule(new SimAXIMem(edge, size = p(ExtBus).get.size)(p))
withClockAndReset(clock, th.harnessReset) { withClockAndReset(port.clock, th.harnessReset) {
Module(mmio_mem.module).suggestName("mmio_mem") Module(mmio_mem.module).suggestName("mmio_mem")
} }
mmio_mem.io_axi4.head <> port mmio_mem.io_axi4.head <> port.bits
} }
Nil Nil
} }
}) })
class WithTieOffInterrupts extends OverrideHarnessBinder({ class WithTieOffInterrupts extends OverrideHarnessBinder({
(system: HasExtInterruptsModuleImp, th: HasHarnessSignalReferences, ports: Seq[Data]) => { (system: HasExtInterruptsModuleImp, th: HasHarnessSignalReferences, ports: Seq[UInt]) => {
ports.map { case p: UInt => p := 0.U } ports.foreach { _ := 0.U }
Nil Nil
} }
}) })
class WithTieOffL2FBusAXI extends OverrideHarnessBinder({ class WithTieOffL2FBusAXI extends OverrideHarnessBinder({
(system: CanHaveSlaveAXI4Port, th: HasHarnessSignalReferences, ports: Seq[Data]) => { (system: CanHaveSlaveAXI4Port, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[AXI4Bundle]]) => {
ports.map { ports.foreach({ p => p := DontCare; p.bits.tieoff() })
case p: AXI4Bundle =>
p := DontCare
p.tieoff()
case c: Clock =>
}
Nil Nil
} }
}) })
class WithSimDebug extends OverrideHarnessBinder({ class WithSimDebug extends OverrideHarnessBinder({
(system: HasPeripheryDebugModuleImp, th: HasHarnessSignalReferences, ports: Seq[Data]) => { (system: HasPeripheryDebugModuleImp, th: HasHarnessSignalReferences, ports: Seq[Data]) => {
if (!ports.isEmpty) { ports.map {
val dtm_success = Wire(Bool()) case d: ClockedDMIIO =>
when (dtm_success) { th.success := true.B } val dtm_success = WireInit(false.B)
ports.map { when (dtm_success) { th.success := true.B }
case d: ClockedDMIIO => val dtm = Module(new SimDTM()(system.p)).connect(th.harnessClock, th.harnessReset.asBool, d, dtm_success)
val dtm = Module(new SimDTM()(system.p)).connect(th.harnessClock, th.harnessReset.asBool, d, dtm_success) case j: JTAGIO =>
case j: JTAGIO => val dtm_success = WireInit(false.B)
val jtag = Module(new SimJTAG(tickDelay=3)).connect(j, th.harnessClock, th.harnessReset.asBool, ~(th.harnessReset.asBool), dtm_success) when (dtm_success) { th.success := true.B }
case _ => val jtag = Module(new SimJTAG(tickDelay=3)).connect(j, th.harnessClock, th.harnessReset.asBool, ~(th.harnessReset.asBool), dtm_success)
require(false, "We only support DMI or JTAG simulated debug connections")
}
} }
Nil Nil
} }
@@ -229,63 +195,56 @@ class WithSimDebug extends OverrideHarnessBinder({
class WithTiedOffDebug extends OverrideHarnessBinder({ class WithTiedOffDebug extends OverrideHarnessBinder({
(system: HasPeripheryDebugModuleImp, th: HasHarnessSignalReferences, ports: Seq[Data]) => { (system: HasPeripheryDebugModuleImp, th: HasHarnessSignalReferences, ports: Seq[Data]) => {
ports.map { ports.map {
case j: JTAGIO =>
j.TCK := true.B.asClock
j.TMS := true.B
j.TDI := true.B
j.TRSTn.foreach { r => r := true.B }
case d: ClockedDMIIO => case d: ClockedDMIIO =>
d.dmi.req.valid := false.B d.dmi.req.valid := false.B
d.dmi.req.bits := DontCare d.dmi.req.bits := DontCare
d.dmi.resp.ready := true.B d.dmi.resp.ready := true.B
d.dmiClock := false.B.asClock d.dmiClock := false.B.asClock
d.dmiReset := true.B d.dmiReset := true.B
case j: JTAGIO =>
j.TCK := true.B.asClock
j.TMS := true.B
j.TDI := true.B
j.TRSTn.foreach { r => r := true.B }
case a: ClockedAPBBundle => case a: ClockedAPBBundle =>
a.tieoff() a.tieoff()
a.clock := false.B.asClock a.clock := false.B.asClock
a.reset := true.B.asAsyncReset a.reset := true.B.asAsyncReset
a.psel := false.B a.psel := false.B
a.penable := false.B a.penable := false.B
case _ => require(false)
} }
Nil Nil
} }
}) })
class WithTiedOffSerial extends OverrideHarnessBinder({ class WithTiedOffSerial extends OverrideHarnessBinder({
(system: CanHavePeripherySerial, th: HasHarnessSignalReferences, ports: Seq[Data]) => { (system: CanHavePeripherySerial, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[SerialIO]]) => {
ports.map { ports.map { p => SerialAdapter.tieoff(Some(p.bits)) }
case p: SerialIO => SerialAdapter.tieoff(Some(p))
case _ =>
}
Nil Nil
} }
}) })
class WithSimSerial extends OverrideHarnessBinder({ class WithSimSerial extends OverrideHarnessBinder({
(system: CanHavePeripherySerial, th: HasHarnessSignalReferences, ports: Seq[Data]) => { (system: CanHavePeripherySerial, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[SerialIO]]) => {
val serial_clock = WireInit(false.B.asClock) ports.map { p =>
ports.map { val ser_success = SerialAdapter.connectSimSerial(p.bits, p.clock, th.harnessReset)
case p: SerialIO => when (ser_success) { th.success := true.B }
val ser_success = SerialAdapter.connectSimSerial(p, serial_clock, th.harnessReset)
when (ser_success) { th.success := true.B }
case c: Clock =>
serial_clock := c
} }
Nil Nil
} }
}) })
class WithTraceGenSuccess extends OverrideHarnessBinder({ class WithTraceGenSuccess extends OverrideHarnessBinder({
(system: TraceGenSystemModuleImp, th: HasHarnessSignalReferences, ports: Seq[Data]) => { (system: TraceGenSystemModuleImp, th: HasHarnessSignalReferences, ports: Seq[Bool]) => {
ports.map { case p: Bool => when (p) { th.success := true.B } } ports.map { p => when (p) { th.success := true.B } }
Nil Nil
} }
}) })
class WithSimDromajoBridge extends ComposeHarnessBinder({ class WithSimDromajoBridge extends ComposeHarnessBinder({
(system: CanHaveTraceIOModuleImp, th: HasHarnessSignalReferences, ports: Seq[Data]) => { (system: CanHaveTraceIOModuleImp, th: HasHarnessSignalReferences, ports: Seq[TraceOutputTop]) => {
ports.map { case p: TraceOutputTop => p.traces.map(tileTrace => SimDromajoBridge(tileTrace)(system.p)) } ports.map { p => p.traces.map(tileTrace => SimDromajoBridge(tileTrace)(system.p)) }
Nil Nil
} }
}) })

View File

@@ -74,7 +74,7 @@ object GetSystemParameters {
// This macro overrides previous matches on some Top mixin. This is useful for // This macro overrides previous matches on some Top mixin. This is useful for
// binders which drive IO, since those typically cannot be composed // binders which drive IO, since those typically cannot be composed
class OverrideIOBinder[T](fn: => (T) => (Seq[Data], Seq[IOCell]))(implicit tag: ClassTag[T]) extends Config((site, here, up) => { class OverrideIOBinder[T, S <: Data](fn: => (T) => (Seq[S], Seq[IOCell]))(implicit tag: ClassTag[T]) extends Config((site, here, up) => {
case IOBinders => up(IOBinders, site) + (tag.runtimeClass.toString -> case IOBinders => up(IOBinders, site) + (tag.runtimeClass.toString ->
((t: Any) => { ((t: Any) => {
t match { t match {
@@ -87,7 +87,7 @@ class OverrideIOBinder[T](fn: => (T) => (Seq[Data], Seq[IOCell]))(implicit tag:
// This macro composes with previous matches on some Top mixin. This is useful for // This macro composes with previous matches on some Top mixin. This is useful for
// annotation-like binders, since those can typically be composed // annotation-like binders, since those can typically be composed
class ComposeIOBinder[T](fn: => (T) => (Seq[Data], Seq[IOCell]))(implicit tag: ClassTag[T]) extends Config((site, here, up) => { class ComposeIOBinder[T, S <: Data](fn: => (T) => (Seq[S], Seq[IOCell]))(implicit tag: ClassTag[T]) extends Config((site, here, up) => {
case IOBinders => up(IOBinders, site) + (tag.runtimeClass.toString -> case IOBinders => up(IOBinders, site) + (tag.runtimeClass.toString ->
((t: Any) => { ((t: Any) => {
t match { t match {
@@ -116,6 +116,11 @@ object BoreHelper {
case object IOCellKey extends Field[IOCellTypeParams](GenericIOCellParams()) case object IOCellKey extends Field[IOCellTypeParams](GenericIOCellParams())
class ClockedIO[T <: Data](gen: T) extends Bundle {
val clock = Output(Clock())
val bits = gen
override def cloneType: this.type = (new ClockedIO(DataMirror.internal.chiselTypeClone[T](gen))).asInstanceOf[this.type]
}
class WithGPIOCells extends OverrideIOBinder({ class WithGPIOCells extends OverrideIOBinder({
(system: HasPeripheryGPIOModuleImp) => { (system: HasPeripheryGPIOModuleImp) => {
@@ -131,14 +136,15 @@ class WithGPIOCells extends OverrideIOBinder({
(g, iocell) (g, iocell)
}).unzip }).unzip
}).unzip }).unzip
(ports2d.flatten, cells2d.flatten) val ports: Seq[Analog] = ports2d.flatten
(ports, cells2d.flatten)
} }
}) })
// DOC include start: WithUARTIOCells // DOC include start: WithUARTIOCells
class WithUARTIOCells extends OverrideIOBinder({ class WithUARTIOCells extends OverrideIOBinder({
(system: HasPeripheryUARTModuleImp) => { (system: HasPeripheryUARTModuleImp) => {
val (ports, cells2d) = system.uart.zipWithIndex.map({ case (u, i) => val (ports: Seq[UARTPortIO], cells2d) = system.uart.zipWithIndex.map({ case (u, i) =>
val (port, ios) = IOCell.generateIOFromSignal(u, Some(s"iocell_uart_${i}"), system.p(IOCellKey)) val (port, ios) = IOCell.generateIOFromSignal(u, Some(s"iocell_uart_${i}"), system.p(IOCellKey))
port.suggestName(s"uart_${i}") port.suggestName(s"uart_${i}")
(port, ios) (port, ios)
@@ -150,7 +156,7 @@ class WithUARTIOCells extends OverrideIOBinder({
class WithSPIIOCells extends OverrideIOBinder({ class WithSPIIOCells extends OverrideIOBinder({
(system: HasPeripherySPIFlashModuleImp) => { (system: HasPeripherySPIFlashModuleImp) => {
val (ports, cells2d) = system.qspi.zipWithIndex.map({ case (s, i) => val (ports: Seq[SPIChipIO], cells2d) = system.qspi.zipWithIndex.map({ case (s, i) =>
val port = IO(new SPIChipIO(s.c.csWidth)).suggestName(s"spi_${i}") val port = IO(new SPIChipIO(s.c.csWidth)).suggestName(s"spi_${i}")
val iocellBase = s"iocell_spi_${i}" val iocellBase = s"iocell_spi_${i}"
@@ -178,7 +184,7 @@ class WithSPIIOCells extends OverrideIOBinder({
class WithExtInterruptIOCells extends OverrideIOBinder({ class WithExtInterruptIOCells extends OverrideIOBinder({
(system: HasExtInterruptsModuleImp) => { (system: HasExtInterruptsModuleImp) => {
if (system.outer.nExtInterrupts > 0) { if (system.outer.nExtInterrupts > 0) {
val (port, cells) = IOCell.generateIOFromSignal(system.interrupts, Some("iocell_interrupts"), system.p(IOCellKey)) val (port: UInt, cells) = IOCell.generateIOFromSignal(system.interrupts, Some("iocell_interrupts"), system.p(IOCellKey))
port.suggestName("ext_interrupts") port.suggestName("ext_interrupts")
(Seq(port), cells) (Seq(port), cells)
} else { } else {
@@ -246,94 +252,79 @@ class WithDebugIOCells extends OverrideIOBinder({
class WithSerialIOCells extends OverrideIOBinder({ class WithSerialIOCells extends OverrideIOBinder({
(system: CanHavePeripherySerial) => system.serial.map({ s => (system: CanHavePeripherySerial) => system.serial.map({ s =>
val sys = system.asInstanceOf[BaseSubsystem] val sys = system.asInstanceOf[BaseSubsystem]
val (port, cells) = IOCell.generateIOFromSignal(s, Some("iocell_serial"), sys.p(IOCellKey)) val clocked_serial = Wire(new ClockedIO(DataMirror.internal.chiselTypeClone[SerialIO](s))).suggestName("serial_wire")
val serial_clock = Wire(Output(Clock())).suggestName("chiptop_serial_clock") clocked_serial.clock := BoreHelper("serial_clock", sys.fbus.module.clock)
serial_clock := false.B.asClock // necessary for BoringUtils to work properly clocked_serial.bits <> s
dontTouch(serial_clock) val (port, cells) = IOCell.generateIOFromSignal(clocked_serial, Some("serial"), sys.p(IOCellKey))
BoringUtils.bore(sys.fbus.module.clock, Seq(serial_clock))
val (serial_clock_io, serial_clock_cell) = IOCell.generateIOFromSignal(serial_clock, Some("serial_clock"), sys.p(IOCellKey))
serial_clock_io.suggestName("serial_clock")
port.suggestName("serial") port.suggestName("serial")
(Seq(port, serial_clock_io), cells ++ serial_clock_cell) (Seq(port), cells)
}).getOrElse((Nil, Nil)) }).getOrElse((Nil, Nil))
}) })
class WithAXI4MemPunchthrough extends OverrideIOBinder({ class WithAXI4MemPunchthrough extends OverrideIOBinder({
(system: CanHaveMasterAXI4MemPort) => { (system: CanHaveMasterAXI4MemPort) => {
val clock = if (!system.mem_axi4.isEmpty) { val ports: Seq[ClockedIO[AXI4Bundle]] = system.mem_axi4.zipWithIndex.map({ case (m, i) =>
Some(BoreHelper("axi4_mem_clock", system.asInstanceOf[BaseSubsystem].mbus.module.clock)) val p = IO(new ClockedIO(DataMirror.internal.chiselTypeClone[AXI4Bundle](m))).suggestName(s"axi4_mem_${i}")
} else { p.bits <> m
None p.clock := BoreHelper("axi4_mem_clock", system.asInstanceOf[BaseSubsystem].mbus.module.clock)
}
val ports = system.mem_axi4.zipWithIndex.map({ case (m, i) =>
val p = IO(DataMirror.internal.chiselTypeClone[AXI4Bundle](m)).suggestName(s"axi4_mem_${i}")
p <> m
p p
}) })
(ports ++ clock, Nil) (ports, Nil)
} }
}) })
class WithAXI4MMIOPunchthrough extends OverrideIOBinder({ class WithAXI4MMIOPunchthrough extends OverrideIOBinder({
(system: CanHaveMasterAXI4MMIOPort) => { (system: CanHaveMasterAXI4MMIOPort) => {
val clock = if (!system.mmio_axi4.isEmpty) { val ports: Seq[ClockedIO[AXI4Bundle]] = system.mmio_axi4.zipWithIndex.map({ case (m, i) =>
Some(BoreHelper("axi4_mmio_clock", system.asInstanceOf[BaseSubsystem].mbus.module.clock)) val p = IO(new ClockedIO(DataMirror.internal.chiselTypeClone[AXI4Bundle](m))).suggestName(s"axi4_mmio_${i}")
} else { p.bits <> m
None p.clock := BoreHelper("axi4_mmio_clock", system.asInstanceOf[BaseSubsystem].mbus.module.clock)
}
val ports = system.mmio_axi4.zipWithIndex.map({ case (m, i) =>
val p = IO(DataMirror.internal.chiselTypeClone[AXI4Bundle](m)).suggestName(s"axi4_mmio_${i}")
p <> m
p p
}) })
(ports ++ clock, Nil) (ports, Nil)
} }
}) })
class WithL2FBusAXI4Punchthrough extends OverrideIOBinder({ class WithL2FBusAXI4Punchthrough extends OverrideIOBinder({
(system: CanHaveSlaveAXI4Port) => { (system: CanHaveSlaveAXI4Port) => {
val clock = if (!system.l2_frontend_bus_axi4.isEmpty) { val ports: Seq[ClockedIO[AXI4Bundle]] = system.l2_frontend_bus_axi4.zipWithIndex.map({ case (m, i) =>
Some(BoreHelper("axi4_fbus_clock", system.asInstanceOf[BaseSubsystem].fbus.module.clock)) val p = IO(new ClockedIO(Flipped(DataMirror.internal.chiselTypeClone[AXI4Bundle](m)))).suggestName(s"axi4_fbus_${i}")
} else { m <> p.bits
None p.clock := BoreHelper("axi4_fbus_clock", system.asInstanceOf[BaseSubsystem].fbus.module.clock)
}
val ports = system.l2_frontend_bus_axi4.zipWithIndex.map({ case (m, i) =>
val p = IO(Flipped(DataMirror.internal.chiselTypeClone[AXI4Bundle](m))).suggestName(s"axi4_fbus_${i}")
m <> p
p p
}) })
(ports ++ clock, Nil) (ports, Nil)
} }
}) })
class WithBlockDeviceIOPunchthrough extends OverrideIOBinder({ class WithBlockDeviceIOPunchthrough extends OverrideIOBinder({
(system: CanHavePeripheryBlockDeviceModuleImp) => { (system: CanHavePeripheryBlockDeviceModuleImp) => {
val ports = system.bdev.map({ bdev => val ports: Seq[ClockedIO[BlockDeviceIO]] = system.bdev.map({ bdev =>
val p = IO(new BlockDeviceIO()(system.p)).suggestName("blockdev") val p = IO(new ClockedIO(new BlockDeviceIO()(system.p))).suggestName("blockdev")
val clock = BoreHelper("blkdev_clk", system.outer.controller.get.module.clock) p.clock := BoreHelper("blkdev_clk", system.outer.controller.get.module.clock)
p <> bdev p.bits <> bdev
Seq(p, clock) p
}).getOrElse(Nil) }).toSeq
(ports, Nil) (ports, Nil)
} }
}) })
class WithNICIOPunchthrough extends OverrideIOBinder({ class WithNICIOPunchthrough extends OverrideIOBinder({
(system: CanHavePeripheryIceNICModuleImp) => { (system: CanHavePeripheryIceNICModuleImp) => {
val port = system.net.map({ n => val ports: Seq[ClockedIO[NICIOvonly]] = system.net.map({ n =>
val p = IO(new NICIOvonly).suggestName("nic") val p = IO(new ClockedIO(new NICIOvonly)).suggestName("nic")
val clock = BoreHelper("nic_clk", system.outer.icenicOpt.get.module.clock) p.clock := BoreHelper("nic_clk", system.outer.icenicOpt.get.module.clock)
p <> n p.bits <> n
Seq(p, clock) p
}).getOrElse(Nil) }).toSeq
(port.toSeq, Nil) (ports, Nil)
} }
}) })
class WithTraceGenSuccessPunchthrough extends OverrideIOBinder({ class WithTraceGenSuccessPunchthrough extends OverrideIOBinder({
(system: TraceGenSystemModuleImp) => { (system: TraceGenSystemModuleImp) => {
val success = IO(Output(Bool())).suggestName("success") val success: Bool = IO(Output(Bool())).suggestName("success")
success := system.success success := system.success
(Seq(success), Nil) (Seq(success), Nil)
} }
@@ -341,7 +332,7 @@ class WithTraceGenSuccessPunchthrough extends OverrideIOBinder({
class WithTraceIOPunchthrough extends OverrideIOBinder({ class WithTraceIOPunchthrough extends OverrideIOBinder({
(system: CanHaveTraceIOModuleImp) => { (system: CanHaveTraceIOModuleImp) => {
val ports = system.traceIO.map { t => val ports: Option[TraceOutputTop] = system.traceIO.map { t =>
val trace = IO(DataMirror.internal.chiselTypeClone[TraceOutputTop](t)).suggestName("trace") val trace = IO(DataMirror.internal.chiselTypeClone[TraceOutputTop](t)).suggestName("trace")
trace <> t trace <> t
trace trace