@@ -40,12 +40,12 @@ Top-level traits specify that the ``DigitalTop`` has been parameterized to read
|
|||||||
|
|
||||||
Top-level traits should be defined and documented in subprojects, alongside their corresponding keys. The traits should then be added to the ``DigitalTop`` being used by Chipyard.
|
Top-level traits should be defined and documented in subprojects, alongside their corresponding keys. The traits should then be added to the ``DigitalTop`` being used by Chipyard.
|
||||||
|
|
||||||
Below we see the traits for the GCD example. The Lazy trait connects the GCD module to the Diplomacy graph, while the Implementation trait causes the ``DigitalTop`` to instantiate an additional port and concretely connect it to the GCD module.
|
Below we see the traits for the GCD example. The Lazy trait connects the GCD module to the Diplomacy graph.
|
||||||
|
|
||||||
.. literalinclude:: ../../generators/chipyard/src/main/scala/example/GCD.scala
|
.. literalinclude:: ../../generators/chipyard/src/main/scala/example/GCD.scala
|
||||||
:language: scala
|
:language: scala
|
||||||
:start-after: DOC include start: GCD lazy trait
|
:start-after: DOC include start: GCD lazy trait
|
||||||
:end-before: DOC include end: GCD imp trait
|
:end-before: DOC include end: GCD lazy trait
|
||||||
|
|
||||||
These traits are added to the default ``DigitalTop`` in Chipyard.
|
These traits are added to the default ``DigitalTop`` in Chipyard.
|
||||||
|
|
||||||
|
|||||||
@@ -79,13 +79,7 @@ Register routers have a TileLink node simply named "node", which we can hook up
|
|||||||
This will automatically add address map and device tree entries for the peripheral.
|
This will automatically add address map and device tree entries for the peripheral.
|
||||||
Also observe how we have to place additional AXI4 buffers and converters for the AXI4 version of this peripheral.
|
Also observe how we have to place additional AXI4 buffers and converters for the AXI4 version of this peripheral.
|
||||||
|
|
||||||
For peripherals which instantiate a concrete module, or which need to be connected to concrete IOs or wires, a matching concrete trait is necessary. We will make our GCD example output a ``gcd_busy`` signal as a top-level port to demonstrate. In the concrete module implementation trait, we instantiate the top level IO (a concrete object) and wire it to the IO of our lazy module.
|
Peripherals which expose I/O can use `InModuleBody` to punch their I/O to the `DigitalTop` module.
|
||||||
|
|
||||||
|
|
||||||
.. literalinclude:: ../../generators/chipyard/src/main/scala/example/GCD.scala
|
|
||||||
:language: scala
|
|
||||||
:start-after: DOC include start: GCD imp trait
|
|
||||||
:end-before: DOC include end: GCD imp trait
|
|
||||||
|
|
||||||
Constructing the DigitalTop and Config
|
Constructing the DigitalTop and Config
|
||||||
--------------------------------------
|
--------------------------------------
|
||||||
|
|||||||
@@ -48,6 +48,5 @@ class DigitalTopModule[+L <: DigitalTop](l: L) extends ChipyardSystemModule(l)
|
|||||||
with sifive.blocks.devices.gpio.HasPeripheryGPIOModuleImp
|
with sifive.blocks.devices.gpio.HasPeripheryGPIOModuleImp
|
||||||
with sifive.blocks.devices.spi.HasPeripherySPIFlashModuleImp
|
with sifive.blocks.devices.spi.HasPeripherySPIFlashModuleImp
|
||||||
with sifive.blocks.devices.spi.HasPeripherySPIModuleImp
|
with sifive.blocks.devices.spi.HasPeripherySPIModuleImp
|
||||||
with chipyard.example.CanHavePeripheryGCDModuleImp
|
|
||||||
with freechips.rocketchip.util.DontTouch
|
with freechips.rocketchip.util.DontTouch
|
||||||
// DOC include end: DigitalTop
|
// DOC include end: DigitalTop
|
||||||
|
|||||||
@@ -161,10 +161,10 @@ trait CanHavePeripheryGCD { this: BaseSubsystem =>
|
|||||||
private val portName = "gcd"
|
private val portName = "gcd"
|
||||||
|
|
||||||
// Only build if we are using the TL (nonAXI4) version
|
// Only build if we are using the TL (nonAXI4) version
|
||||||
val gcd = p(GCDKey) match {
|
val gcd_busy = p(GCDKey) match {
|
||||||
case Some(params) => {
|
case Some(params) => {
|
||||||
if (params.useAXI4) {
|
val gcd = if (params.useAXI4) {
|
||||||
val gcd = LazyModule(new GCDAXI4(params, pbus.beatBytes)(p))
|
val gcd = pbus { LazyModule(new GCDAXI4(params, pbus.beatBytes)(p)) }
|
||||||
pbus.coupleTo(portName) {
|
pbus.coupleTo(portName) {
|
||||||
gcd.node :=
|
gcd.node :=
|
||||||
AXI4Buffer () :=
|
AXI4Buffer () :=
|
||||||
@@ -172,34 +172,29 @@ trait CanHavePeripheryGCD { this: BaseSubsystem =>
|
|||||||
// toVariableWidthSlave doesn't use holdFirstDeny, which TLToAXI4() needsx
|
// toVariableWidthSlave doesn't use holdFirstDeny, which TLToAXI4() needsx
|
||||||
TLFragmenter(pbus.beatBytes, pbus.blockBytes, holdFirstDeny = true) := _
|
TLFragmenter(pbus.beatBytes, pbus.blockBytes, holdFirstDeny = true) := _
|
||||||
}
|
}
|
||||||
Some(gcd)
|
gcd
|
||||||
} else {
|
} else {
|
||||||
val gcd = LazyModule(new GCDTL(params, pbus.beatBytes)(p))
|
val gcd = pbus { LazyModule(new GCDTL(params, pbus.beatBytes)(p)) }
|
||||||
pbus.coupleTo(portName) { gcd.node := TLFragmenter(pbus.beatBytes, pbus.blockBytes) := _ }
|
pbus.coupleTo(portName) { gcd.node := TLFragmenter(pbus.beatBytes, pbus.blockBytes) := _ }
|
||||||
Some(gcd)
|
gcd
|
||||||
}
|
}
|
||||||
|
val pbus_io = pbus { InModuleBody {
|
||||||
|
val busy = IO(Output(Bool()))
|
||||||
|
busy := gcd.module.io.gcd_busy
|
||||||
|
busy
|
||||||
|
}}
|
||||||
|
val gcd_busy = InModuleBody {
|
||||||
|
val busy = IO(Output(Bool())).suggestName("gcd_busy")
|
||||||
|
busy := pbus_io
|
||||||
|
busy
|
||||||
|
}
|
||||||
|
Some(gcd_busy)
|
||||||
}
|
}
|
||||||
case None => None
|
case None => None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// DOC include end: GCD lazy trait
|
// DOC include end: GCD lazy trait
|
||||||
|
|
||||||
// DOC include start: GCD imp trait
|
|
||||||
trait CanHavePeripheryGCDModuleImp extends LazyRawModuleImp {
|
|
||||||
val outer: CanHavePeripheryGCD
|
|
||||||
val gcd_busy = outer.gcd match {
|
|
||||||
case Some(gcd) => {
|
|
||||||
val busy = IO(Output(Bool()))
|
|
||||||
busy := gcd.module.io.gcd_busy
|
|
||||||
Some(busy)
|
|
||||||
}
|
|
||||||
case None => None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// DOC include end: GCD imp trait
|
|
||||||
|
|
||||||
|
|
||||||
// DOC include start: GCD config fragment
|
// DOC include start: GCD config fragment
|
||||||
class WithGCD(useAXI4: Boolean = false, useBlackBox: Boolean = false) extends Config((site, here, up) => {
|
class WithGCD(useAXI4: Boolean = false, useBlackBox: Boolean = false) extends Config((site, here, up) => {
|
||||||
case GCDKey => Some(GCDParams(useAXI4 = useAXI4, useBlackBox = useBlackBox))
|
case GCDKey => Some(GCDParams(useAXI4 = useAXI4, useBlackBox = useBlackBox))
|
||||||
|
|||||||
Reference in New Issue
Block a user