This is mess clean it up
This commit is contained in:
@@ -1,9 +1,11 @@
|
||||
// See LICENSE for license details.
|
||||
|
||||
package barstools.tapeout.transforms.pads
|
||||
|
||||
import chisel3._
|
||||
import barstools.tapeout.transforms.clkgen._
|
||||
import chisel3.experimental._
|
||||
import firrtl.transforms.DedupModules
|
||||
import firrtl.Transform
|
||||
import firrtl.annotations.Annotation
|
||||
|
||||
// TODO: Move out of pads
|
||||
|
||||
@@ -20,29 +22,12 @@ abstract class TopModule(
|
||||
coreHeight: Int = 0,
|
||||
usePads: Boolean = true,
|
||||
override_clock: Option[Clock] = None,
|
||||
override_reset: Option[Bool] = None) extends Module with IsClkModule {
|
||||
override_reset: Option[Bool] = None) extends Module {
|
||||
|
||||
override_clock.foreach(clock := _)
|
||||
override_reset.foreach(reset := _)
|
||||
|
||||
override def annotateClkPort(p: Element, anno: ClkPortAnnotation): Unit = {
|
||||
DataMirror.directionOf(p) match {
|
||||
case chisel3.core.ActualDirection.Input =>
|
||||
require(anno.tag.nonEmpty, "Top Module input clks must be clk sinks")
|
||||
require(anno.tag.get.src.nonEmpty,
|
||||
"Top module input clks must have clk period, etc. specified")
|
||||
case _ =>
|
||||
throw new Exception("Clk port direction must be specified!")
|
||||
}
|
||||
p match {
|
||||
case _: chisel3.core.Clock =>
|
||||
case _ => throw new Exception("Clock port must be of type Clock")
|
||||
}
|
||||
annotate(TargetClkPortAnnoC(p, anno))
|
||||
}
|
||||
|
||||
override def annotateDerivedClks(m: Module, anno: ClkModAnnotation): Unit =
|
||||
throw new Exception("Top module cannot be pure clock module!")
|
||||
private val mySelf = this
|
||||
|
||||
// Annotate module as top module (that requires pad transform)
|
||||
// Specify the yaml file that indicates how pads are templated,
|
||||
@@ -55,7 +40,38 @@ abstract class TopModule(
|
||||
coreHeight = coreHeight,
|
||||
supplyAnnos = supplyAnnos
|
||||
)
|
||||
annotate(TargetModulePadAnnoC(this, modulePadAnnotation))
|
||||
//TODO: PORT-1.4: Remove commented code
|
||||
// annotate(TargetModulePadAnnoC(this, modulePadAnnotation))
|
||||
annotate(new ChiselAnnotation with RunFirrtlTransform {
|
||||
override def toFirrtl: Annotation = {
|
||||
TargetModulePadAnnoF(mySelf.toNamed, modulePadAnnotation)
|
||||
}
|
||||
def transformClass: Class[_ <: Transform] = classOf[AddIOPadsTransform]
|
||||
})
|
||||
}
|
||||
|
||||
private def extractElementNames(signal: Data): Seq[String] = {
|
||||
val names = signal match {
|
||||
case elt: Record =>
|
||||
elt.elements.map { case (key, value) => extractElementNames(value).map(x => key + "_" + x) }.toSeq.flatten
|
||||
case elt: Vec[_] =>
|
||||
elt.zipWithIndex.map { case (elt, i) => extractElementNames(elt).map(x => i + "_" + x) }.toSeq.flatten
|
||||
case elt: Element => Seq("")
|
||||
case elt => throw new Exception(s"Cannot extractElementNames for type ${elt.getClass}")
|
||||
}
|
||||
names.map(s => s.stripSuffix("_"))
|
||||
}
|
||||
|
||||
// TODO: Replace!
|
||||
def extractElements(signal: Data): Seq[Element] = {
|
||||
signal match {
|
||||
case elt: Record =>
|
||||
elt.elements.map { case (key, value) => extractElements(value) }.toSeq.flatten
|
||||
case elt: Vec[_] =>
|
||||
elt.map { elt => extractElements(elt) }.toSeq.flatten
|
||||
case elt: Element => Seq(elt)
|
||||
case elt => throw new Exception(s"Cannot extractElements for type ${elt.getClass}")
|
||||
}
|
||||
}
|
||||
|
||||
// Annotate IO with side + pad name
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
// See LICENSE for license details.
|
||||
|
||||
package barstools.tapeout.transforms.pads
|
||||
|
||||
import firrtl.annotations._
|
||||
import chisel3.experimental._
|
||||
import chisel3._
|
||||
import barstools.tapeout.transforms._
|
||||
import firrtl._
|
||||
|
||||
import net.jcazevedo.moultingyaml._
|
||||
|
||||
@@ -23,26 +23,32 @@ abstract class FirrtlPadTransformAnnotation {
|
||||
abstract class IOAnnotation {
|
||||
def serialize: String
|
||||
}
|
||||
|
||||
case class IOPadAnnotation(padSide: String, padName: String) extends IOAnnotation {
|
||||
import PadAnnotationsYaml._
|
||||
def serialize: String = this.toYaml.prettyPrint
|
||||
def getPadSide: PadSide = HasPadAnnotation.getSide(padSide)
|
||||
}
|
||||
|
||||
case class NoIOPadAnnotation(noPad: String = "") extends IOAnnotation {
|
||||
import PadAnnotationsYaml._
|
||||
def serialize: String = this.toYaml.prettyPrint
|
||||
def field = "noPad:"
|
||||
def field: String = "noPad:"
|
||||
}
|
||||
|
||||
// Firrtl version
|
||||
case class TargetIOPadAnnoF(target: ComponentName, anno: IOAnnotation) extends FirrtlPadTransformAnnotation with SingleTargetAnnotation[ComponentName] {
|
||||
case class TargetIOPadAnnoF(target: ComponentName, anno: IOAnnotation)
|
||||
extends FirrtlPadTransformAnnotation with SingleTargetAnnotation[ComponentName] {
|
||||
|
||||
def duplicate(n: ComponentName): TargetIOPadAnnoF = this.copy(target = n)
|
||||
def getAnno = Annotation(target, classOf[AddIOPadsTransform], anno.serialize)
|
||||
def targetName = target.name
|
||||
def targetName: String = target.name
|
||||
}
|
||||
|
||||
//TODO: PORT-1.4: Remove commented code
|
||||
// Chisel version
|
||||
case class TargetIOPadAnnoC(target: Element, anno: IOAnnotation) extends ChiselAnnotation {
|
||||
def toFirrtl = TargetIOPadAnnoF(target.toNamed, anno)
|
||||
}
|
||||
//case class TargetIOPadAnnoC(target: Element, anno: IOAnnotation) extends ChiselAnnotation {
|
||||
// def toFirrtl = TargetIOPadAnnoF(target.toNamed, anno)
|
||||
//}
|
||||
|
||||
// A bunch of supply pads (designated by name, # on each chip side) can be associated with the top module
|
||||
case class SupplyAnnotation(
|
||||
@@ -51,6 +57,7 @@ case class SupplyAnnotation(
|
||||
rightSide: Int = 0,
|
||||
topSide: Int = 0,
|
||||
bottomSide: Int = 0)
|
||||
|
||||
// The chip top should have a default pad side, a pad template file, and supply annotations
|
||||
case class ModulePadAnnotation(
|
||||
defaultPadSide: String = Top.serialize,
|
||||
@@ -63,17 +70,16 @@ case class ModulePadAnnotation(
|
||||
require(supplyPadNames.distinct.length == supplyPadNames.length, "Supply pads should only be specified once!")
|
||||
def getDefaultPadSide: PadSide = HasPadAnnotation.getSide(defaultPadSide)
|
||||
}
|
||||
|
||||
// Firrtl version
|
||||
case class TargetModulePadAnnoF(target: ModuleName, anno: ModulePadAnnotation) extends FirrtlPadTransformAnnotation with SingleTargetAnnotation[ModuleName] {
|
||||
case class TargetModulePadAnnoF(target: ModuleName, anno: ModulePadAnnotation)
|
||||
extends FirrtlPadTransformAnnotation with SingleTargetAnnotation[ModuleName] {
|
||||
|
||||
def duplicate(n: ModuleName): TargetModulePadAnnoF = this.copy(target = n)
|
||||
def getAnno = Annotation(target, classOf[AddIOPadsTransform], anno.serialize)
|
||||
def targetName = target.name
|
||||
}
|
||||
// Chisel version
|
||||
case class TargetModulePadAnnoC(target: Module, anno: ModulePadAnnotation) extends ChiselAnnotation {
|
||||
def toFirrtl = TargetModulePadAnnoF(target.toNamed, anno)
|
||||
def targetName: String = target.name
|
||||
}
|
||||
|
||||
|
||||
case class CollectedAnnos(
|
||||
componentAnnos: Seq[TargetIOPadAnnoF],
|
||||
moduleAnnos: TargetModulePadAnnoF) {
|
||||
@@ -95,16 +101,34 @@ object HasPadAnnotation {
|
||||
case _ => throw new Exception(s" $a not a valid pad side annotation!")
|
||||
}
|
||||
|
||||
//TODO: PORT-1.4: Remove commented code
|
||||
// def unapply(a: Annotation): Option[FirrtlPadTransformAnnotation] = a match {
|
||||
// case Annotation(f, t, s) if t == classOf[AddIOPadsTransform] => f match {
|
||||
// case m: ModuleName =>
|
||||
// Some(TargetModulePadAnnoF(m, s.parseYaml.convertTo[ModulePadAnnotation]))
|
||||
// case c: ComponentName if s.contains(NoIOPadAnnotation().field) =>
|
||||
// Some(TargetIOPadAnnoF(c, s.parseYaml.convertTo[NoIOPadAnnotation]))
|
||||
// case c: ComponentName =>
|
||||
// Some(TargetIOPadAnnoF(c, s.parseYaml.convertTo[IOPadAnnotation]))
|
||||
// case _ => throw new Exception("Annotation only valid on module or component")
|
||||
// }
|
||||
// case _ => None
|
||||
// }
|
||||
|
||||
//scalastyle:off cyclomatic.complexity
|
||||
def unapply(a: Annotation): Option[FirrtlPadTransformAnnotation] = a match {
|
||||
case Annotation(f, t, s) if t == classOf[AddIOPadsTransform] => f match {
|
||||
case m: ModuleName =>
|
||||
Some(TargetModulePadAnnoF(m, s.parseYaml.convertTo[ModulePadAnnotation]))
|
||||
case c: ComponentName if s.contains(NoIOPadAnnotation().field) =>
|
||||
Some(TargetIOPadAnnoF(c, s.parseYaml.convertTo[NoIOPadAnnotation]))
|
||||
case c: ComponentName =>
|
||||
Some(TargetIOPadAnnoF(c, s.parseYaml.convertTo[IOPadAnnotation]))
|
||||
case _ => throw new Exception("Annotation only valid on module or component")
|
||||
}
|
||||
case hasTransform: RunFirrtlTransform if hasTransform.transformClass == classOf[AddIOPadsTransform] =>
|
||||
hasTransform match {
|
||||
case hasTarget: SingleTargetAnnotation[_] =>
|
||||
hasTarget.target match {
|
||||
case m: ModuleName =>
|
||||
Some(TargetModulePadAnnoF(m, s.parseYaml.convertTo[ModulePadAnnotation]))
|
||||
hasTarget match {
|
||||
case _ => None
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
case _ => None
|
||||
}
|
||||
|
||||
@@ -113,8 +137,9 @@ object HasPadAnnotation {
|
||||
val padAnnos = annos.map(x => unapply(x)).flatten
|
||||
val targets = padAnnos.map(x => x.targetName)
|
||||
require(targets.distinct.length == targets.length, "Only 1 pad related annotation is allowed per component/module")
|
||||
if (padAnnos.length == 0) None
|
||||
else {
|
||||
if (padAnnos.length == 0) {
|
||||
None
|
||||
} else {
|
||||
val moduleAnnosTemp = padAnnos.filter {
|
||||
case TargetModulePadAnnoF(_, _) => true
|
||||
case _ => false
|
||||
|
||||
Reference in New Issue
Block a user