3.7. SiFive Generators

Chipyard includes several open-source generators developed and maintained by SiFive. These are currently organized within two submodules named sifive-blocks and sifive-cache.

3.7.1. Last-Level Cache Generator

sifive-cache includes last-level cache geneator. The Chipyard framework uses this last-level cache as an L2 cache. To use this L2 cache, you should add the freechips.rocketchip.subsystem.WithInclusiveCache mixin to your SoC configuration. To learn more about configuring this L2 cache, please refer to the Memory Hierarchy section.

3.7.2. Peripheral Devices

sifive-blocks includes multiple peripheral device generators, such as UART, SPI, PWM, JTAG, GPIO and more.

These peripheral devices usually affect the memory map of the SoC, and its top-level IO as well. To integrate one of these devices in your SoC, you will need to define a custom mixin with the approriate address for the device using the Rocket Chip parameter system. As an example, for a GPIO device you could add the following mixin to set the GPIO address to 0x10012000. This address is the start address for the GPIO configuration registers.

/**
 * Class to add in GPIO
 */
class WithGPIO extends Config((site, here, up) => {
  case PeripheryGPIOKey => List(
    GPIOParams(address = 0x10012000, width = 4, includeIOF = false))
})

Additionally, if the device requires top-level IOs, you will need to define a mixin to change the top-level configuration of your SoC. When adding a top-level IO, you should also be aware of whether it interacts with the test-harness. For example, a GPIO device would require a GPIO pin, and therefore we would write a mixin to augment the top level as follows:

/**
 * Class to specify a top level BOOM and/or Rocket system with GPIO
 */
class WithGPIOTop extends Config((site, here, up) => {
  case BuildTop => (clock: Clock, reset: Bool, p: Parameters) => {
    val top = Module(LazyModule(new TopWithGPIO()(p)).module)
    for (gpio <- top.gpio) {
      for (pin <- gpio.pins) {
        pin.i.ival := false.B
      }
    }
    top
  }
})

This example instantiates a top-level module with include GPIO ports (TopWithGPIO), and then ties-off the GPIO port inputs to 0 (false.B).

Finally, you add the relevant config mixin to the SoC config. For example:

class GPIORocketConfig extends Config(
  new WithGPIO ++                                          // add GPIOs to the peripherybus
  new WithGPIOTop ++                                       // use top with GPIOs
  new WithBootROM ++
  new freechips.rocketchip.subsystem.WithInclusiveCache ++
  new freechips.rocketchip.subsystem.WithNBigCores(1) ++
  new freechips.rocketchip.system.BaseConfig)

Some of the devices in sifive-blocks (such as GPIO) may already have pre-defined mixins within the Chipyard example project. You may be able to use these config mixins directly, but you should be aware of their addresses within the SoC address map.