Clean up passing ports from IOBinders to HarnessBinders
This commit is contained in:
@@ -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
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user