Search code examples
rocket-chip

Adding a MMIO peripheral to a small rocket core


I have successfully added and simulated my MMIO perihperal coupled to a normal sized rocket core before. But now I want to try to add it to a small core (so called TinyCore), and this is the part where I am having problems. Also, just in case it is relevant, the conexions with my peripheral are all trough FIFOs.

First, the error I am getting when trying to generate the design:

[error] java.lang.IllegalArgumentException: requirement failed: Ports cannot overlap: AddressSet(0x80000000, 0x3fff) AddressSet(0x80000000, 0xfffffff)

I imagine this comes from the fact that the small rocket config has a different memory map, which I don't know, and I am trying to add the peripheral to an address that doesn't exist in this configuration.

Here it is the configuration I am using:

class myTinyRocketConfig2 extends Config(
  new freechips.rocketchip.subsystem.WithInclusiveCache(nBanks=1, nWays=4, capacityKB=128) ++
  new freechips.rocketchip.subsystem.With1TinyCore ++             // single tiny rocket-core
  new chipyard.config.AbstractConfig)

And this is how I added the peripheral, it shows the address and some other parameters:

class TLTxWriteQueue
(
  depth: Int = 4,
  csrAddress: AddressSet = AddressSet(0x2000, 0xff),
  beatBytes: Int = 4,
)(implicit p: Parameters) extends TxWriteQueue(depth) with TLHasCSR {
  val devname = "tlQueueIn"
  val devcompat = Seq("ucb-art", "dsptools")
  val device = new SimpleDevice(devname, devcompat) {
    override def describe(resources: ResourceBindings): Description = {
      val Description(name, mapping) = super.describe(resources)
      Description(name, mapping)
    }
  }
  // make diplomatic TL node for regmap
  override val mem = Some(TLRegisterNode(address = Seq(csrAddress), device = device, beatBytes = beatBytes))
}

I apologize in advance for any stupid mistake, as I am a beginner trying to go trough with his first project. Thanks


Solution

  • The the Rocket TinyCore uses a default scratchpad instead of a backing memory. This scratchpad 0x80000000 to 0x80003fff is overlapping with the memport's address range.

    You'll have to remove the memport. This is what chipyard's TinyRocketConfig does. This config should generate a design (just without an L2 Cache or backing memory).

    class TinyRocketConfig extends Config(
      new chipyard.config.WithTLSerialLocation(
        freechips.rocketchip.subsystem.FBUS,
        freechips.rocketchip.subsystem.PBUS) ++                       // attach TL serial adapter to f/p busses
      new chipyard.WithMulticlockIncoherentBusTopology ++             // use incoherent bus topology
      new freechips.rocketchip.subsystem.WithNBanks(0) ++             // remove L2$
      new freechips.rocketchip.subsystem.WithNoMemPort ++             // remove backing memory
      new freechips.rocketchip.subsystem.With1TinyCore ++             // single tiny rocket-core
      new chipyard.config.AbstractConfig)
    

    If you wanted to include an InclusiveCache in your design, you can try using a modified version of chipyard's TinyRocketConfig. Though currently, it doesn't seem like you're addressing the entire L2 Cache, and I think it's microarchitecturally unused with TinyCore. If you simply need a larger scratchpad, you can modify the scratchpad to contain more sets:

    class WithModifiedScratchPad extends Config((site, here, up) => {
      case RocketTilesKey => up(RocketTilesKey, site) map { r =>
        // each set is currently 64 bytes
        r.copy(dcache = r.dcache.map(_.copy(nSets = 2048 /*128KiB scratchpad*/))) }
    })