merge the different ExampleTop subclasses into the example package

This commit is contained in:
Howard Mao
2017-06-26 16:29:04 -07:00
parent 31f5fc98e4
commit f766dcc550
11 changed files with 89 additions and 148 deletions

View File

@@ -83,21 +83,16 @@ By passing the +blkdev argument on the simulator command line, you can allow
the RTL simulation to read and write from a file. Take a look at tests/blkdev.c the RTL simulation to read and write from a file. Take a look at tests/blkdev.c
for an example of how Rocket can program the block device controller. for an example of how Rocket can program the block device controller.
## Creating your own project ## Adding an MMIO peripheral
To create your own project, you should create your own scala package. You can RocketChip to create your own memory-mapped IO device and add it into
Let's use the PWM package as an example. First you create a directory the SoC design. The easiest way to create a TileLink peripheral is to use the
under src/main/scala that has the same name as your package. TLRegisterRouter, which abstracts away the details of handling the TileLink
protocol and provides a convenient interface for specifying memory-mapped
mkdir src/main/scala/pwm registers. To create a RegisterRouter-based peripheral, you will need to
specify a parameter case class for the configuration settings, a bundle trait
Now let's add a peripheral device to the new SoC. The easiest way to create a with the extra top-level ports, and a module implementation containing the
TileLink peripheral is to use the TLRegisterRouter, which abstracts away the actual RTL.
details of handling the TileLink protocol and provides a convenient interface
for specifying memory-mapped registers. To create a RegisterRouter-based
peripheral, you will need to specify a parameter case class for the
configuration settings, a bundle trait with the extra top-level ports, and
a module implementation containing the actual RTL.
case class PWMParams(address: BigInt, beatBytes: Int) case class PWMParams(address: BigInt, beatBytes: Int)
@@ -142,7 +137,7 @@ module trait.
new TLRegBundle(c, _) with PWMTLBundle)( new TLRegBundle(c, _) with PWMTLBundle)(
new TLRegModule(c, _, _) with PWMTLModule) new TLRegModule(c, _, _) with PWMTLModule)
The full module code with comments can be found in src/main/scala/pwm/PWM.scala. The full module code with comments can be found in src/main/scala/example/PWM.scala.
After creating the module, we need to hook it up to our SoC. Rocketchip After creating the module, we need to hook it up to our SoC. Rocketchip
accomplishes this using the [cake pattern](http://www.cakesolutions.net/teamblogs/2011/12/19/cake-pattern-in-depth). accomplishes this using the [cake pattern](http://www.cakesolutions.net/teamblogs/2011/12/19/cake-pattern-in-depth).
@@ -186,7 +181,7 @@ functionality. We then connect the PWMTL's pwmout to the pwmout we declared.
} }
Now we want to mix our traits into the system as a whole. This code is from Now we want to mix our traits into the system as a whole. This code is from
src/main/scala/pwm/Top.scala. src/main/scala/example/Top.scala.
class ExampleTopWithPWM(q: Parameters) extends ExampleTop(q) class ExampleTopWithPWM(q: Parameters) extends ExampleTop(q)
with PeripheryPWM { with PeripheryPWM {
@@ -198,38 +193,23 @@ src/main/scala/pwm/Top.scala.
extends ExampleTopModule(l) with HasPeripheryPWMModuleImp extends ExampleTopModule(l) with HasPeripheryPWMModuleImp
Just as we need separate traits for LazyModule and module implementation, we Just as we need separate traits for LazyModule and module implementation, we
need two classes to build the system. The ExampleTop classes from the example need two classes to build the system. The ExampleTop classes already have the
package already have the basic peripherals included for us, so we will just basic peripherals included for us, so we will just extend those.
extend those.
The ExampleTop class includes the pre-elaboration code and also a lazy val to The ExampleTop class includes the pre-elaboration code and also a lazy val to
produce the module implementation (hence LazyModule). The ExampleTopModule produce the module implementation (hence LazyModule). The ExampleTopModule
class is the actual RTL that gets synthesized. class is the actual RTL that gets synthesized.
Now we have the RTL for the chip, but we need a test harness to simulate it. Finally, we need to add a configuration class in
src/main/scala/example/Configs.scala that tells the TestHarness to instantiate
ExampleTopWithPWM instead of the default ExampleTop.
class TestHarness(q: Parameters) extends example.TestHarness()(q) { class WithPWM extends Config((site, here, up) => {
override def buildTop(p: Parameters) = case BuildTop => (p: Parameters) =>
LazyModule(new ExampleTopWithPWM(p)) Module(LazyModule(new ExampleTopWithPWM()(p)).module)
} })
We just extend the TestHarness from the example package, which already has class PWMConfig extends Config(new WithPWM ++ new BaseExampleConfig)
the extra RTL to simulate the memory system and tethered serial port.
It provides us the hook function `buildTop` which we can override to build
our ExampleTopWithPWM instead of the regular ExampleTop.
We also need to create a Generator object, which gets called as the entry
point for elaboration.
object Generator extends GeneratorApp {
generateFirrtl
}
Finally, we need to add a configuration class in src/main/scala/pwm/Configs.scala.
This defines all the settings in the Parameters object. We aren't adding any
new parameters, so we can just extend the default configuration.
class PWMTLConfig extends Config(new example.DefaultExampleConfig)
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
@@ -265,8 +245,8 @@ Compiling this program with make produces a `pwm.riscv` executable.
Now with all of that done, we can go ahead and run our simulation. Now with all of that done, we can go ahead and run our simulation.
cd verisim cd verisim
make PROJECT=pwm CONFIG=PWMTLConfig make PROJECT=pwm CONFIG=PWMConfig
./simulator-pwm-PWMTLConfig ../tests/pwm.riscv ./simulator-pwm-PWMConfig ../tests/pwm.riscv
## Adding a DMA port ## Adding a DMA port

View File

@@ -1,21 +0,0 @@
package blkdev
import config.{Parameters, Config}
import example.DefaultExampleConfig
import testchipip.{WithBlockDevice, WithNBlockDeviceTrackers}
class WithSimBlockDevice extends Config((site, here, up) => {
case UseSimBlockDevice => true
})
class WithBlockDeviceModel extends Config((site, here, up) => {
case UseSimBlockDevice => false
})
class BlockDeviceConfig extends Config(
new WithSimBlockDevice ++
new WithBlockDevice ++
new DefaultExampleConfig)
class WithTwoTrackers extends WithNBlockDeviceTrackers(2)
class WithFourTrackers extends WithNBlockDeviceTrackers(4)

View File

@@ -1,27 +0,0 @@
package blkdev
import diplomacy.LazyModule
import chisel3._
import config.{Parameters, Field}
import testchipip.GeneratorApp
import example._
case object UseSimBlockDevice extends Field[Boolean]
class TestHarness(implicit p: Parameters) extends Module {
val io = IO(new Bundle {
val success = Output(Bool())
})
val dut = Module(LazyModule(new ExampleTopWithBlockDevice).module)
dut.connectSimAXIMem()
if (p(UseSimBlockDevice))
dut.connectSimBlockDevice()
else
dut.connectBlockDeviceModel()
io.success := dut.connectSimSerial()
}
object Generator extends GeneratorApp {
generateFirrtl
}

View File

@@ -1,15 +0,0 @@
package blkdev
import chisel3._
import config.Parameters
import testchipip._
import example._
class ExampleTopWithBlockDevice(implicit p: Parameters) extends ExampleTop
with HasPeripheryBlockDevice {
override lazy val module = new ExampleTopWithBlockDeviceModule(this)
}
class ExampleTopWithBlockDeviceModule(l: ExampleTopWithBlockDevice)
extends ExampleTopModule(l)
with HasPeripheryBlockDeviceModuleImp

View File

@@ -1,14 +1,56 @@
package example package example
import chisel3._
import config.{Parameters, Config} import config.{Parameters, Config}
import testchipip.WithSerialAdapter import diplomacy.LazyModule
import coreplex.WithRoccExample import coreplex.WithRoccExample
import rocketchip.WithoutTLMonitors import rocketchip.WithoutTLMonitors
import testchipip._
class DefaultExampleConfig extends Config( class WithExampleTop extends Config((site, here, up) => {
case BuildTop => (p: Parameters) =>
Module(LazyModule(new ExampleTop()(p)).module)
})
class WithPWM extends Config((site, here, up) => {
case BuildTop => (p: Parameters) =>
Module(LazyModule(new ExampleTopWithPWM()(p)).module)
})
class WithBlockDeviceModel extends Config((site, here, up) => {
case BuildTop => (p: Parameters) => {
val top = Module(LazyModule(new ExampleTopWithBlockDevice()(p)).module)
top.connectBlockDeviceModel()
top
}
})
class WithSimBlockDevice extends Config((site, here, up) => {
case BuildTop => (p: Parameters) => {
val top = Module(LazyModule(new ExampleTopWithBlockDevice()(p)).module)
top.connectSimBlockDevice()
top
}
})
class BaseExampleConfig extends Config(
new WithoutTLMonitors ++ new WithoutTLMonitors ++
new WithSerialAdapter ++ new WithSerialAdapter ++
new rocketchip.DefaultConfig) new rocketchip.DefaultConfig)
class DefaultExampleConfig extends Config(
new WithExampleTop ++ new BaseExampleConfig)
class RoccExampleConfig extends Config( class RoccExampleConfig extends Config(
new WithRoccExample ++ new DefaultExampleConfig) new WithRoccExample ++ new DefaultExampleConfig)
class PWMConfig extends Config(new WithPWM ++ new BaseExampleConfig)
class SimBlockDeviceConfig extends Config(
new WithBlockDevice ++ new WithSimBlockDevice ++ new BaseExampleConfig)
class BlockDeviceModelConfig extends Config(
new WithBlockDevice ++ new WithBlockDeviceModel ++ new BaseExampleConfig)
class WithTwoTrackers extends WithNBlockDeviceTrackers(2)
class WithFourTrackers extends WithNBlockDeviceTrackers(4)

View File

@@ -1,4 +1,4 @@
package pwm package example
import chisel3._ import chisel3._
import chisel3.util._ import chisel3.util._

View File

@@ -4,16 +4,16 @@ import diplomacy.LazyModule
import rocketchip._ import rocketchip._
import testchipip._ import testchipip._
import chisel3._ import chisel3._
import config.Parameters import config.{Field, Parameters}
case object BuildTop extends Field[Parameters => ExampleTopModule[ExampleTop]]
class TestHarness(implicit val p: Parameters) extends Module { class TestHarness(implicit val p: Parameters) extends Module {
val io = IO(new Bundle { val io = IO(new Bundle {
val success = Output(Bool()) val success = Output(Bool())
}) })
def buildTop(p: Parameters): ExampleTop = LazyModule(new ExampleTop()(p)) val dut = p(BuildTop)(p)
val dut = Module(buildTop(p).module)
dut.connectSimAXIMem() dut.connectSimAXIMem()
io.success := dut.connectSimSerial() io.success := dut.connectSimSerial()
} }

View File

@@ -24,3 +24,20 @@ class ExampleTopModule[+L <: ExampleTop](l: L) extends BaseSystemModule(l)
with HasRocketPlexMasterModuleImp with HasRocketPlexMasterModuleImp
with HasNoDebugModuleImp with HasNoDebugModuleImp
with HasPeripherySerialModuleImp with HasPeripherySerialModuleImp
class ExampleTopWithPWM(implicit p: Parameters) extends ExampleTop
with HasPeripheryPWM {
override lazy val module = new ExampleTopWithPWMModule(this)
}
class ExampleTopWithPWMModule(l: ExampleTopWithPWM)
extends ExampleTopModule(l) with HasPeripheryPWMModuleImp
class ExampleTopWithBlockDevice(implicit p: Parameters) extends ExampleTop
with HasPeripheryBlockDevice {
override lazy val module = new ExampleTopWithBlockDeviceModule(this)
}
class ExampleTopWithBlockDeviceModule(l: ExampleTopWithBlockDevice)
extends ExampleTopModule(l)
with HasPeripheryBlockDeviceModuleImp

View File

@@ -1,8 +0,0 @@
package pwm
import config.{Parameters, Config}
import testchipip.WithSerialAdapter
import uncore.tilelink.ClientUncachedTileLinkIO
import chisel3._
class PWMConfig extends Config(new example.DefaultExampleConfig)

View File

@@ -1,14 +0,0 @@
package pwm
import config.Parameters
import diplomacy.LazyModule
import testchipip.GeneratorApp
class TestHarness(q: Parameters) extends example.TestHarness()(q) {
override def buildTop(p: Parameters) =
LazyModule(new ExampleTopWithPWM()(p))
}
object Generator extends GeneratorApp {
generateFirrtl
}

View File

@@ -1,13 +0,0 @@
package pwm
import chisel3._
import example._
import config.Parameters
class ExampleTopWithPWM(implicit p: Parameters) extends ExampleTop
with HasPeripheryPWM {
override lazy val module = new ExampleTopWithPWMModule(this)
}
class ExampleTopWithPWMModule(l: ExampleTopWithPWM)
extends ExampleTopModule(l) with HasPeripheryPWMModuleImp