Skip to content

Commit

Permalink
Merge pull request #1399 from ucb-bar/iobinder-qol
Browse files Browse the repository at this point in the history
QoL improvement to IOBinders + custom ChipTop example
  • Loading branch information
jerryz123 authored Apr 5, 2023
2 parents 59b67c9 + 149c89d commit 4c085eb
Show file tree
Hide file tree
Showing 6 changed files with 112 additions and 2 deletions.
7 changes: 7 additions & 0 deletions docs/Advanced-Concepts/Top-Testharness.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,13 @@ The ``IOBinders`` are responsible for instantiating the IO cells for ``ChipTop``
The ``HarnessBinders`` are responsible for instantiating test harness collateral that connects to the ``ChipTop`` ports.
Most types of devices and testing collateral can be instantiated using custom ``IOBinders`` and ``HarnessBinders``.

Custom ChipTops
^^^^^^^^^^^^^^^^^^^^^^^^^

The default standard ``ChipTop`` provides a mimimal, barebones template for ``IOBinders`` to generate IOCells around ``DigitalTop`` traits.
For tapeouts, integrating Analog IP, or other non-standard use cases, Chipyard supports specifying a custom ``ChipTop`` using the ``BuildTop`` key.
An example of a custom ChipTop which uses non-standard IOCells is provided in `generators/chipyard/src/main/scala/example/CustomChipTop.scala <https://github.com/ucb-bar/chipyard/blob/main/generators/chipyard/src/main/scala/example/CustomChipTop.scala>`__


System/DigitalTop
-------------------------
Expand Down
33 changes: 31 additions & 2 deletions generators/chipyard/src/main/scala/IOBinders.scala
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,12 @@ case object IOBinders extends Field[Map[String, Seq[IOBinderFunction]]](
Map[String, Seq[IOBinderFunction]]().withDefaultValue(Nil)
)

case object DontTouchIOBindersPorts extends Field[Boolean](true)

class WithDontTouchIOBinders(b: Boolean = true) extends Config((site, here, up) => {
case DontTouchIOBindersPorts => b
})

abstract trait HasIOBinders { this: LazyModule =>
val lazySystem: LazyModule
private val iobinders = p(IOBinders)
Expand All @@ -67,10 +73,33 @@ abstract trait HasIOBinders { this: LazyModule =>
})

// A publicly accessible list of IO cells (useful for a floorplanning tool, for example)
lazy val iocells = (lzyFlattened.values ++ impFlattened.values).unzip._2.flatten.toBuffer
val iocells = InModuleBody { (lzyFlattened.values ++ impFlattened.values).unzip._2.flatten.toBuffer }

// A mapping between stringified DigitalSystem traits and their corresponding ChipTop ports
lazy val portMap = iobinders.keys.map(k => k -> (lzyFlattened(k)._1 ++ impFlattened(k)._1)).toMap
val portMap = InModuleBody { iobinders.keys.map(k => k -> (lzyFlattened(k)._1 ++ impFlattened(k)._1)).toMap }

// A mapping between stringified DigitalSystem traits and their corresponding ChipTop iocells
val iocellMap = InModuleBody { iobinders.keys.map(k => k -> (lzyFlattened(k)._2 ++ impFlattened(k)._2)).toMap }

InModuleBody {
if (p(DontTouchIOBindersPorts)) {
portMap.values.foreach(_.foreach(dontTouch(_)))
}

println("IOCells generated by IOBinders:")
for ((k, v) <- iocellMap) {
if (!v.isEmpty) {
val cells = v.map(_.getClass.getSimpleName).groupBy(identity).mapValues(_.size)

println(s" IOBinder for $k generated:")
for ((t, c) <- cells) { println(s" $c X $t") }
}
}
println()
val totals = iocells.map(_.getClass.getSimpleName).groupBy(identity).mapValues(_.size)
println(s" Total generated ${iocells.size} IOCells:")
for ((t, c) <- totals) { println(s" $c X $t") }
}
}

// Note: The parameters instance is accessible only through LazyModule
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import freechips.rocketchip.diplomacy.{AsynchronousCrossing}

// DOC include start: FFTRocketConfig
class FFTRocketConfig extends Config(
new chipyard.iobinders.WithDontTouchIOBinders(false) ++ // TODO: hack around dontTouch not working in SFC
new fftgenerator.WithFFTGenerator(numPoints=8, width=16, decPt=8) ++ // add 8-point mmio fft at the default addr (0x2400) with 16bit fixed-point numbers.
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
new chipyard.config.AbstractConfig)
Expand Down Expand Up @@ -58,6 +59,7 @@ class LargeNVDLARocketConfig extends Config(
new chipyard.config.AbstractConfig)

class ManyMMIOAcceleratorRocketConfig extends Config(
new chipyard.iobinders.WithDontTouchIOBinders(false) ++ // TODO: hack around dontTouch not working in SFC
new fftgenerator.WithFFTGenerator(numPoints=8, width=16, decPt=8) ++ // add 8-point mmio fft at the default addr (0x2400) with 16bit fixed-point numbers.
new nvidia.blocks.dla.WithNVDLA("small") ++ // add a small NVDLA
new chipyard.example.WithStreamingPassthrough ++ // use top with tilelink-controlled streaming passthrough
Expand Down
7 changes: 7 additions & 0 deletions generators/chipyard/src/main/scala/config/RocketConfigs.scala
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ class RocketConfig extends Config(
new chipyard.config.AbstractConfig)

class TinyRocketConfig extends Config(
new chipyard.iobinders.WithDontTouchIOBinders(false) ++ // TODO FIX: Don't dontTouch the ports
new chipyard.config.WithTLSerialLocation(
freechips.rocketchip.subsystem.FBUS,
freechips.rocketchip.subsystem.PBUS) ++ // attach TL serial adapter to f/p busses
Expand Down Expand Up @@ -126,3 +127,9 @@ class MulticlockAXIOverSerialConfig extends Config(
new freechips.rocketchip.subsystem.WithNBigCores(2) ++
new chipyard.config.AbstractConfig)
// DOC include end: MulticlockAXIOverSerialConfig

class CustomIOChipTopRocketConfig extends Config(
new chipyard.example.WithCustomChipTop ++
new chipyard.example.WithCustomIOCells ++
new freechips.rocketchip.subsystem.WithNBigCores(1) ++ // single rocket-core
new chipyard.config.AbstractConfig)
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ class TutorialSha3BlackBoxConfig extends Config(

// Tutorial Phase 5: Map a multicore heterogeneous SoC with multiple cores and memory-mapped accelerators
class TutorialNoCConfig extends Config(
new chipyard.iobinders.WithDontTouchIOBinders(false) ++
// Try changing the dimensions of the Mesh topology
new constellation.soc.WithGlobalNoC(constellation.soc.GlobalNoCParams(
NoCParams(
Expand Down
64 changes: 64 additions & 0 deletions generators/chipyard/src/main/scala/example/CustomChipTop.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package chipyard.example

import chisel3._
import chipyard.iobinders._

import freechips.rocketchip.config._
import freechips.rocketchip.diplomacy.{InModuleBody}
import barstools.iocell.chisel._
import chipyard._

// A "custom" IOCell with additional I/O
// The IO don't do anything here in this example
class CustomDigitalInIOCellBundle extends DigitalInIOCellBundle {
val custom_out = Output(Bool())
val custom_in = Input(Bool())
}

// Using a custom digital in iocell instead of the default one
class CustomDigitalInIOCell extends RawModule with DigitalInIOCell {
val io = IO(new CustomDigitalInIOCellBundle)
io.i := io.pad
io.custom_out := io.pad
}

case class CustomIOCellParams() extends IOCellTypeParams {
def analog() = Module(new GenericAnalogIOCell)
def gpio() = Module(new GenericDigitalGPIOCell)
def input() = Module(new CustomDigitalInIOCell)
def output() = Module(new GenericDigitalOutIOCell)
}

class CustomChipTop(implicit p: Parameters) extends ChipTop {
// making the module name ChipTop instead of CustomChipTop means
// we don't have to set the TOP make variable to CustomChipTop
override lazy val desiredName = "ChipTop"

// InModuleBody blocks are executed within the LazyModuleImp of this block
InModuleBody {
iocellMap.foreach { case (interface, cells) => {
cells.foreach { _ match {
case c: CustomDigitalInIOCell => {
c.io.custom_in := false.B
}
case c: GenericDigitalOutIOCell => {
// do nothing
}
case c => {
require(false, "Unsupported iocell type ${c.getClass}")
}
}}
}}

// demonstrate accessing the iocellMap directly
val serialTLIOCells = iocellMap("interface testchipip.CanHavePeripheryTLSerial")
}
}

class WithCustomIOCells extends Config((site, here, up) => {
case IOCellKey => CustomIOCellParams()
})

class WithCustomChipTop extends Config((site, here, up) => {
case BuildTop => (p: Parameters) => new CustomChipTop()(p)
})

0 comments on commit 4c085eb

Please sign in to comment.