Files
chipyard/tapeout/src/main/scala/transforms/pads/CreatePadBBs.scala
Angie Wang f1c437f830 Add Pads + other utilities (#7)
[stevo]: adds a bunch of pad frame commits, as well as beginning work on clocking annotations and constraints


* start add io pads pass

* save progress adding yaml pad info

* saving some semi-presentable work -- parses yaml for pad templates and associates templates with ports

* added black boxes to the module; still need to hook up

* added supply pad yaml example; added option to not include pad for an IO, blackboxed that cat + bit extraction functions

* rewrite createbbs and some other parts of the transform

* finally got blackboxhelper to work -- seems there was a typo in the firrtl pass (?) have not connected them up properly in the padframe

* finished first version of pad transform; need to add bells and whistles + special case stuff

* made a bunch of changes in firrtl to shorthand things

* done with padframe for signals

* started major refactoring; first of pad yaml stuff

* forgot to update verilogTemplate -> verilog

* rename ParsePadYaml -> ChipPadsYaml; moved some stuff

* separated out stuff that describes pads i.e. direction, type, side

* forgot to update import for yamlhelpers

* trying to make the process of creating annotations more structured

* saving annotation helpers but prob better to switch to yaml

* saving changes -- reworking annotations

* fixing some bugs; properly annotated ports with pads

* annotate supply pads

* lesson (re)learned. cleaned up constants

* finished adding supply pads to pad frame; still need to generate io file

* also committing updated transform; still without io file

* big typo was causing pad verilog files not to be generated

* verilator passes with transform; had to fix verilog bb typo

* added unused pads; added more thorough tests + did visual inspection of output; made some port types more explicit

* renamed files/classes to be clearer

* started creating pad io template

* update spec so that transform order matters

* get rid of logger

* went around in circles with blackboxhelper + way to annotate

* finished adding + testing pad.io creation

* starting clkgen pass -- made model for asynchronously reset clk divider + wrappers for programmatic bundling

* temporarily locating albert's utility functions here

* saving work on clk constraints

* redid input config passing -- pass in tech directory instead; seems like getting clk sink, src, and relationship works

* not done; need to pause to do tapeout-y things. the clk gen pass gets all the clks and their sources, but i need to build a proper graph to handle clks coming out of muxes
2017-03-05 18:50:56 -08:00

109 lines
4.4 KiB
Scala

package barstools.tapeout.transforms.pads
import firrtl.annotations._
import firrtl._
import firrtl.ir._
import firrtl.transforms._
object CreatePadBBs {
private [barstools] case class UsedPadInfo(
// The following are found with both supply + io pads
padInline: String, // Verilog txt
padName: String, // Pad module name
padType: PadType, // Pad type: supply, analog, digital
// The following only affects io pads (due to using parameterized modules for bit extraction / cat)
padArrayName: String, // Name of parameterized pad wrapper (that does bit extract/cat)
firrtlBBName: String, // Unique Firrtl name of each parameterized pad wrapper
portWidth: Int // Port width for analog/digital
)
def convertToUsedPad(p: PortIOPad): UsedPadInfo = {
UsedPadInfo(
padInline = p.createPadInline,
padName = p.getPadName,
padType = p.padType,
padArrayName = p.getPadArrayName,
firrtlBBName = p.firrtlBBName,
portWidth = p.portWidth)
}
def convertToUsedPad(p: TopSupplyPad): UsedPadInfo = {
UsedPadInfo(
padInline = p.createPadInline,
padName = p.getPadName,
padType = p.padType,
// Supply pads don't require bit extraction / cat so don't care
padArrayName = p.getPadName,
firrtlBBName = p.getPadName,
portWidth = 0)
}
def checkLegalPadName(namespace: Namespace, usedPads: Seq[UsedPadInfo]): Unit = {
usedPads foreach { x =>
if (namespace contains x.padName)
throw new Exception(s"Pad name ${x.padName} already used!")
if (namespace contains x.padArrayName)
throw new Exception(s"Pad array ${x.padArrayName} name already used!")
if (namespace contains x.firrtlBBName)
throw new Exception(s"Firrtl black box ${x.firrtlBBName} name already used!")
}
}
def apply(
c: Circuit,
ioPads: Seq[PortIOPad],
supplyPads: Seq[TopSupplyPad]): (Circuit, Seq[Annotation]) = {
// Add black boxes for both supply + (used) io pads
val usedPads = ioPads.filter(x => x.pad.nonEmpty).map(convertToUsedPad(_)) ++ supplyPads.map(convertToUsedPad(_))
checkLegalPadName(Namespace(c), usedPads)
// Note that we need to check for Firrtl name uniqueness here! (due to parameterization)
val uniqueExtMods = scala.collection.mutable.ArrayBuffer[UsedPadInfo]()
usedPads foreach { x =>
if (uniqueExtMods.find(_.firrtlBBName == x.firrtlBBName).isEmpty)
uniqueExtMods += x
}
// Collecting unique parameterized black boxes
// (for io, they're wrapped pads; for supply, they're pad modules directly)
val uniqueParameterizedBBs = scala.collection.mutable.ArrayBuffer[UsedPadInfo]()
uniqueExtMods foreach { x =>
if (uniqueParameterizedBBs.find(_.padArrayName == x.padArrayName).isEmpty)
uniqueParameterizedBBs += x
}
// Note: Firrtl is silly and doesn't implement true parameterization -- each module with
// parameterization that potentially affects # of IO needs to be uniquely identified
// (but only in Firrtl)
val bbs = uniqueExtMods.map(x => {
// Supply pads don't have ports
val ports = x.padType match {
case AnalogPad => Seq(Port(NoInfo, AnalogPad.ioName, Input, AnalogType(IntWidth(x.portWidth))))
case DigitalPad => Seq(
Port(NoInfo, DigitalPad.inName, Input, UIntType(IntWidth(x.portWidth))),
Port(NoInfo, DigitalPad.outName, Output, UIntType(IntWidth(x.portWidth)))
)
case SupplyPad => Seq.empty
case _ => throw new Exception("Port pad type invalid!")
}
// Supply black boxes are not parameterized
val params = x.padType match {
case AnalogPad | DigitalPad => Seq(IntParam(ioPads.head.widthParamName, x.portWidth))
case SupplyPad => Seq()
case _ => throw new Exception("Port pad type invalid!")
}
// Firrtl name is unique
ExtModule(NoInfo, x.firrtlBBName, ports, x.padArrayName, params)
} ).toSeq
// Add annotations to black boxes to inline Verilog from template
// Again, note the weirdness in parameterization -- just need to hook to one matching Firrtl instance
val annos = uniqueParameterizedBBs.map(x =>
BlackBoxSourceAnnotation(ModuleName(x.firrtlBBName, CircuitName(c.main)), x.padInline)
).toSeq
(c.copy(modules = c.modules ++ bbs), annos)
}
}