update 'Adding an Accelerator' for API changes

This commit is contained in:
Howard Mao 2019-09-05 18:05:15 -07:00
parent 34612e559c
commit b748dcf14e
1 changed files with 29 additions and 22 deletions

View File

@ -123,16 +123,15 @@ For a simple memory-mapped peripheral, this just involves connecting the periphe
.. code-block:: scala .. code-block:: scala
trait HasPeripheryPWM extends HasSystemNetworks { trait HasPeripheryPWM { this: BaseSubsystem =>
implicit val p: Parameters implicit val p: Parameters
private val address = 0x2000 private val address = 0x2000
private val portName = "pwm"
val pwm = LazyModule(new PWMTL( val pwm = LazyModule(new PWMTL(PWMParams(address, pbus.beatBytes)))
PWMParams(address, peripheryBusConfig.beatBytes))(p))
pwm.node := TLFragmenter( pbus.toVariableWidthSlave(Some(portName)) { pwm.node }
peripheryBusConfig.beatBytes, cacheBlockBytes)(peripheryBus.node)
} }
@ -146,7 +145,7 @@ We then connect the ``PWMTL``'s pwmout to the pwmout we declared.
.. code-block:: scala .. code-block:: scala
trait HasPeripheryPWMModuleImp extends LazyMultiIOModuleImp { trait HasPeripheryPWMModuleImp extends LazyModuleImp {
implicit val p: Parameters implicit val p: Parameters
val outer: HasPeripheryPWM val outer: HasPeripheryPWM
@ -160,33 +159,39 @@ This code is from ``generators/example/src/main/scala/Top.scala``.
.. code-block:: scala .. code-block:: scala
class ExampleTopWithPWM(q: Parameters) extends ExampleTop(q) class TopWithPWM(implicit p: Parameters) extends Top(p)
with PeripheryPWM { with HasPeripheryPWM {
override lazy val module = Module( override lazy val module = Module(new TopWithPWMModule(this))
new ExampleTopWithPWMModule(p, this))
} }
class ExampleTopWithPWMModule(l: ExampleTopWithPWM) class TopWithPWMModule(l: TopWithPWM) extends TopModule(l)
extends ExampleTopModule(l) with HasPeripheryPWMModuleImp with HasPeripheryPWMModuleImp
Just as we need separate traits for ``LazyModule`` and module implementation, we need two classes to build the system. Just as we need separate traits for ``LazyModule`` and module implementation, we need two classes to build the system.
The ``ExampleTop`` classes already have the basic peripherals included for us, so we will just extend those. The ``Top`` classes already have the basic peripherals included for us, so we will just extend those.
The ``ExampleTop`` class includes the pre-elaboration code and also a ``lazy val`` to produce the module implementation (hence ``LazyModule``). The ``Top`` class includes the pre-elaboration code and also a ``lazy val`` to produce the module implementation (hence ``LazyModule``).
The ``ExampleTopModule`` class is the actual RTL that gets synthesized. The ``TopModule`` class is the actual RTL that gets synthesized.
Finally, we need to add a configuration class in ``generators/example/src/main/scala/Configs.scala`` that tells the ``TestHarness`` to instantiate ``ExampleTopWithPWM`` instead of the default ``ExampleTop``. Next, we need to add a configuration mixin in ``generators/example/src/main/scala/ConfigMixins.scala`` that tells the ``TestHarness`` to instantiate ``TopWithPWM`` instead of the default ``Top``.
.. code-block:: scala .. code-block:: scala
class WithPWM extends Config((site, here, up) => { class WithPWMTop extends Config((site, here, up) => {
case BuildTop => (p: Parameters) => case BuildTop => (p: Parameters) =>
Module(LazyModule(new ExampleTopWithPWM()(p)).module) Module(LazyModule(new TopWithPWM()(p)).module)
}) })
class PWMConfig extends Config(new WithPWM ++ new BaseExampleConfig) And finally, we create a configuration class in ``generators/example/src/main/scala/RocketConfigs.scala`` that uses this mixin.
.. code-block:: scala
class PWMRocketConfig extends Config(
new WithPWMTop ++
new WithBootROM ++
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
new freechips.rocketchip.system.BaseConfig)
Now we can test that the PWM is working. The test program is in ``tests/pwm.c``. Now we can test that the PWM is working. The test program is in ``tests/pwm.c``.
@ -293,7 +298,9 @@ For instance, if we wanted to add the previously defined accelerator and route c
}) })
class CustomAcceleratorConfig extends Config( class CustomAcceleratorConfig extends Config(
new WithCustomAccelerator ++ new DefaultExampleConfig) new WithCustomAccelerator ++ new RocketConfig)
To add RoCC instructions in your program, use the RoCC C macros provided in ``tests/rocc.h``. You can find examples in the files ``tests/accum.c`` and ``charcount.c``.
Adding a DMA port Adding a DMA port
------------------- -------------------
@ -324,7 +331,7 @@ To add a device like that, you would do the following.
val dma = LazyModule(new DMADevice) val dma = LazyModule(new DMADevice)
fsb.node := dma.node fbus.fromPort(Some(portName))() := dma.node
} }
trait HasPeripheryDMAModuleImp extends LazyMultiIOModuleImp { trait HasPeripheryDMAModuleImp extends LazyMultiIOModuleImp {
@ -334,6 +341,6 @@ To add a device like that, you would do the following.
The ``ExtBundle`` contains the signals we connect off-chip that we get data from. The ``ExtBundle`` contains the signals we connect off-chip that we get data from.
The DMADevice also has a Tilelink client port that we connect into the L1-L2 crossbar through the front-side buffer (fsb). The DMADevice also has a Tilelink client port that we connect into the L1-L2 crossbar through the frontend bus (fbus).
The sourceId variable given in the ``TLClientNode`` instantiation determines the range of ids that can be used in acquire messages from this device. The sourceId variable given in the ``TLClientNode`` instantiation determines the range of ids that can be used in acquire messages from this device.
Since we specified [0, 1) as our range, only the ID 0 can be used. Since we specified [0, 1) as our range, only the ID 0 can be used.