Run RemoveValidIf pass for updated CIRCT
This commit is contained in:
@@ -1,71 +0,0 @@
|
||||
// See LICENSE for license details.
|
||||
|
||||
package barstools.tapeout.transforms
|
||||
|
||||
import firrtl.Mappers._
|
||||
import firrtl._
|
||||
import firrtl.annotations.{CircuitTarget, ModuleTarget, SingleTargetAnnotation}
|
||||
import firrtl.ir._
|
||||
import firrtl.stage.Forms
|
||||
import firrtl.stage.TransformManager.TransformDependency
|
||||
|
||||
case class KeepNameAnnotation(target: ModuleTarget) extends SingleTargetAnnotation[ModuleTarget] {
|
||||
def duplicate(n: ModuleTarget) = this.copy(n)
|
||||
}
|
||||
|
||||
case class ModuleNameSuffixAnnotation(target: CircuitTarget, suffix: String)
|
||||
extends SingleTargetAnnotation[CircuitTarget] {
|
||||
def duplicate(n: CircuitTarget) = this.copy(target = n)
|
||||
}
|
||||
|
||||
class AddSuffixToModuleNames extends Transform with DependencyAPIMigration {
|
||||
|
||||
override def prerequisites: Seq[TransformDependency] = Forms.LowForm
|
||||
override def optionalPrerequisites: Seq[TransformDependency] = Forms.LowFormOptimized
|
||||
override def optionalPrerequisiteOf: Seq[TransformDependency] = Forms.LowEmitters
|
||||
override def invalidates(a: Transform): Boolean = false
|
||||
|
||||
def determineRenamerandAnnos(state: CircuitState): (AnnotationSeq, (String) => String) = {
|
||||
// remove determine suffix annotation
|
||||
val newAnnos = state.annotations.filterNot(_.isInstanceOf[ModuleNameSuffixAnnotation])
|
||||
val suffixes = state.annotations.collect({ case ModuleNameSuffixAnnotation(_, suffix) => suffix })
|
||||
require(suffixes.length <= 1)
|
||||
val suffix = suffixes.headOption.getOrElse("")
|
||||
|
||||
// skip renaming ExtModules and top-level module
|
||||
val excludeSet = state.circuit.modules.flatMap {
|
||||
case e: ExtModule => Some(e.name)
|
||||
case m if (m.name == state.circuit.main) => Some(m.name)
|
||||
case _ => None
|
||||
}.toSet
|
||||
|
||||
val renamer = { (name: String) => if (excludeSet(name)) name else name + suffix }
|
||||
|
||||
(newAnnos, renamer)
|
||||
}
|
||||
|
||||
def renameInstanceModules(renamer: (String) => String)(stmt: Statement): Statement = {
|
||||
stmt match {
|
||||
case m: DefInstance => new DefInstance(m.info, m.name, renamer(m.module))
|
||||
case s => s.map(renameInstanceModules(renamer)) // if is statement, recurse
|
||||
}
|
||||
}
|
||||
|
||||
def run(state: CircuitState, renamer: (String) => String): (Circuit, RenameMap) = {
|
||||
val myRenames = RenameMap()
|
||||
val c = state.circuit
|
||||
val modulesx = c.modules.map {
|
||||
case m if (renamer(m.name) != m.name) =>
|
||||
myRenames.record(ModuleTarget(c.main, m.name), ModuleTarget(c.main, renamer(m.name)))
|
||||
m.map(renamer).map(renameInstanceModules(renamer))
|
||||
case m => m.map(renameInstanceModules(renamer))
|
||||
}
|
||||
(Circuit(c.info, modulesx, c.main), myRenames)
|
||||
}
|
||||
|
||||
def execute(state: CircuitState): CircuitState = {
|
||||
val (newAnnos, renamer) = determineRenamerandAnnos(state)
|
||||
val (ret, renames) = run(state, renamer)
|
||||
state.copy(circuit = ret, annotations = newAnnos, renames = Some(renames))
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
// See LICENSE for license details.
|
||||
|
||||
package barstools.tapeout.transforms
|
||||
|
||||
import firrtl._
|
||||
import firrtl.annotations.NoTargetAnnotation
|
||||
import firrtl.ir._
|
||||
import firrtl.options.Dependency
|
||||
import firrtl.passes.memlib.ReplSeqMem
|
||||
import firrtl.stage.Forms
|
||||
import firrtl.stage.TransformManager.TransformDependency
|
||||
|
||||
case class LinkExtModulesAnnotation(mustLink: Seq[ExtModule]) extends NoTargetAnnotation
|
||||
|
||||
class AvoidExtModuleCollisions extends Transform with DependencyAPIMigration {
|
||||
|
||||
override def prerequisites: Seq[TransformDependency] = Forms.HighForm
|
||||
override def optionalPrerequisites: Seq[TransformDependency] = Seq(Dependency[RemoveUnusedModules])
|
||||
override def optionalPrerequisiteOf: Seq[TransformDependency] = {
|
||||
Forms.HighEmitters :+ Dependency[ReplSeqMem]
|
||||
}
|
||||
override def invalidates(a: Transform): Boolean = false
|
||||
|
||||
def execute(state: CircuitState): CircuitState = {
|
||||
val mustLink = state.annotations.flatMap {
|
||||
case LinkExtModulesAnnotation(mustLink) => mustLink
|
||||
case _ => Nil
|
||||
}
|
||||
val newAnnos = state.annotations.filterNot(_.isInstanceOf[LinkExtModulesAnnotation])
|
||||
state.copy(circuit = state.circuit.copy(modules = state.circuit.modules ++ mustLink), annotations = newAnnos)
|
||||
}
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
// See LICENSE for license details.
|
||||
|
||||
package barstools.tapeout.transforms
|
||||
|
||||
import firrtl._
|
||||
import firrtl.annotations.{ModuleTarget, ReferenceTarget, SingleTargetAnnotation}
|
||||
import firrtl.ir._
|
||||
import firrtl.options.Dependency
|
||||
import firrtl.passes.memlib.ReplSeqMem
|
||||
import firrtl.stage.Forms
|
||||
import firrtl.stage.TransformManager.TransformDependency
|
||||
|
||||
case class ConvertToExtModAnnotation(target: ModuleTarget) extends SingleTargetAnnotation[ModuleTarget] {
|
||||
def duplicate(n: ModuleTarget) = this.copy(n)
|
||||
}
|
||||
|
||||
// Converts some modules to external modules, based on a given function. If
|
||||
// that function returns "true" then the module is converted into an ExtModule,
|
||||
// otherwise it's left alone.
|
||||
class ConvertToExtMod extends Transform with DependencyAPIMigration {
|
||||
|
||||
override def prerequisites: Seq[TransformDependency] = Forms.HighForm
|
||||
override def optionalPrerequisites: Seq[TransformDependency] = Seq.empty
|
||||
override def optionalPrerequisiteOf: Seq[TransformDependency] = {
|
||||
Forms.HighEmitters ++ Seq(Dependency[RemoveUnusedModules], Dependency[ReplSeqMem])
|
||||
}
|
||||
override def invalidates(a: Transform): Boolean = false
|
||||
|
||||
def run(state: CircuitState, makeExt: Set[String]): (Circuit, RenameMap) = {
|
||||
val renames = RenameMap()
|
||||
val c = state.circuit
|
||||
renames.setCircuit(c.main)
|
||||
val modulesx = c.modules.map {
|
||||
case m: ExtModule => m
|
||||
case m: Module =>
|
||||
val removing = collection.mutable.HashSet[String]()
|
||||
def findDeadNames(statement: Statement): Unit = {
|
||||
statement match {
|
||||
case hn: IsDeclaration => removing += hn.name
|
||||
case x => x.foreachStmt(findDeadNames)
|
||||
}
|
||||
}
|
||||
if (makeExt(m.name)) {
|
||||
m.foreachStmt(findDeadNames)
|
||||
removing.foreach { name =>
|
||||
renames.record(ReferenceTarget(c.main, m.name, Nil, name, Nil), Nil)
|
||||
}
|
||||
new ExtModule(m.info, m.name, m.ports, m.name, Seq.empty)
|
||||
} else {
|
||||
m
|
||||
}
|
||||
}
|
||||
(Circuit(c.info, modulesx, c.main), renames)
|
||||
}
|
||||
|
||||
def execute(state: CircuitState): CircuitState = {
|
||||
val makeExt = state.annotations.collect({ case ConvertToExtModAnnotation(tgt) => tgt.module }).toSet
|
||||
val newAnnos = state.annotations.filterNot(_.isInstanceOf[ConvertToExtModAnnotation])
|
||||
val (ret, renames) = run(state, makeExt)
|
||||
state.copy(circuit = ret, annotations = newAnnos, renames = Some(renames))
|
||||
}
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
// See LICENSE for license details.
|
||||
|
||||
package barstools.tapeout.transforms
|
||||
|
||||
import firrtl._
|
||||
import firrtl.ir._
|
||||
import firrtl.passes.Pass
|
||||
import firrtl.stage.Forms
|
||||
import firrtl.stage.TransformManager.TransformDependency
|
||||
|
||||
class EnumerateModulesPass(enumerate: (Module) => Unit) extends Pass {
|
||||
|
||||
def run(c: Circuit): Circuit = {
|
||||
val modulesx = c.modules.map {
|
||||
case m: ExtModule => m
|
||||
case m: Module => {
|
||||
enumerate(m)
|
||||
m
|
||||
}
|
||||
}
|
||||
Circuit(c.info, modulesx, c.main)
|
||||
}
|
||||
}
|
||||
|
||||
class EnumerateModules(enumerate: (Module) => Unit)
|
||||
extends Transform
|
||||
with SeqTransformBased
|
||||
with DependencyAPIMigration {
|
||||
|
||||
override def prerequisites: Seq[TransformDependency] = Forms.LowForm
|
||||
override def optionalPrerequisites: Seq[TransformDependency] = Forms.LowFormOptimized
|
||||
override def optionalPrerequisiteOf: Seq[TransformDependency] = Forms.LowEmitters
|
||||
override def invalidates(a: Transform): Boolean = false
|
||||
|
||||
def transforms: Seq[Transform] = Seq(new EnumerateModulesPass(enumerate))
|
||||
|
||||
def execute(state: CircuitState): CircuitState = {
|
||||
runTransforms(state)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
// See LICENSE for license details.
|
||||
|
||||
package barstools.tapeout.transforms
|
||||
|
||||
import firrtl.Mappers._
|
||||
import firrtl._
|
||||
import firrtl.annotations.{CircuitTarget, ModuleTarget, SingleTargetAnnotation}
|
||||
import firrtl.ir._
|
||||
import firrtl.stage.Forms
|
||||
import firrtl.stage.TransformManager.TransformDependency
|
||||
import firrtl.options.{Dependency}
|
||||
|
||||
class ExtraLowTransforms extends Transform with DependencyAPIMigration {
|
||||
// this PropagatePresetAnnotations is needed to run the RemoveValidIf pass (that is removed from CIRCT).
|
||||
// additionally, since that pass isn't explicitly a prereq of the LowFormEmitter it
|
||||
// needs to wrapped in this xform
|
||||
override def prerequisites: Seq[TransformDependency] = Forms.LowForm :+
|
||||
Dependency[firrtl.transforms.PropagatePresetAnnotations]
|
||||
override def optionalPrerequisites: Seq[TransformDependency] = Forms.LowFormOptimized
|
||||
override def optionalPrerequisiteOf: Seq[TransformDependency] = Forms.LowEmitters
|
||||
override def invalidates(a: Transform): Boolean = false
|
||||
|
||||
def execute(state: CircuitState): CircuitState = {
|
||||
state
|
||||
}
|
||||
}
|
||||
@@ -5,9 +5,7 @@ import firrtl._
|
||||
import firrtl.annotations._
|
||||
import firrtl.ir._
|
||||
import firrtl.options.{Dependency, InputAnnotationFileAnnotation, StageMain}
|
||||
import firrtl.passes.memlib.ReplSeqMemAnnotation
|
||||
import firrtl.stage.{FirrtlCircuitAnnotation, FirrtlStage, OutputFileAnnotation, RunFirrtlTransformAnnotation}
|
||||
import firrtl.transforms.BlackBoxResourceFileNameAnno
|
||||
import firrtl.stage.{FirrtlCircuitAnnotation, FirrtlStage, RunFirrtlTransformAnnotation}
|
||||
import logger.LazyLogging
|
||||
|
||||
private class GenerateModelStageMain(annotations: AnnotationSeq) extends LazyLogging {
|
||||
@@ -38,15 +36,23 @@ private class GenerateModelStageMain(annotations: AnnotationSeq) extends LazyLog
|
||||
}
|
||||
|
||||
def executeStageMain(): Unit = {
|
||||
val annos = new FirrtlStage().execute(Array.empty, annotations)
|
||||
val appendedAnnotations = annotations.filter(_ match {
|
||||
case CompilerNameAnnotation(_) => true
|
||||
case _ => false
|
||||
}).map(_ match {
|
||||
case CompilerNameAnnotation("low") => Some(RunFirrtlTransformAnnotation(Dependency[ExtraLowTransforms]))
|
||||
case _ => None
|
||||
}).flatten
|
||||
val annos = new FirrtlStage().execute(Array.empty, annotations ++ appendedAnnotations)
|
||||
|
||||
annos.collectFirst { case FirrtlCircuitAnnotation(circuit) => circuit } match {
|
||||
case Some(circuit) =>
|
||||
dumpAnnos(annos)
|
||||
case _ =>
|
||||
throw new Exception(s"executeTop failed while executing FIRRTL!\n")
|
||||
throw new Exception(s"executeStageMain failed while executing FIRRTL!\n")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// main run class
|
||||
object GenerateModelStageMain extends StageMain(new TapeoutStage())
|
||||
|
||||
@@ -1,76 +0,0 @@
|
||||
// See LICENSE for license details.
|
||||
|
||||
package barstools.tapeout.transforms
|
||||
|
||||
import firrtl._
|
||||
import firrtl.annotations._
|
||||
import firrtl.options.Dependency
|
||||
import firrtl.stage.Forms
|
||||
import firrtl.stage.TransformManager.TransformDependency
|
||||
import firrtl.annotations.TargetToken.{Instance, OfModule}
|
||||
|
||||
case class ReParentCircuitAnnotation(target: ModuleTarget) extends SingleTargetAnnotation[ModuleTarget] {
|
||||
def duplicate(n: ModuleTarget) = this.copy(n)
|
||||
}
|
||||
|
||||
class ReParentCircuit extends Transform with DependencyAPIMigration {
|
||||
|
||||
override def prerequisites: Seq[TransformDependency] = Forms.HighForm
|
||||
override def optionalPrerequisites: Seq[TransformDependency] = Seq.empty
|
||||
override def optionalPrerequisiteOf: Seq[TransformDependency] = {
|
||||
Forms.HighEmitters :+ Dependency[RemoveUnusedModules]
|
||||
}
|
||||
override def invalidates(a: Transform): Boolean = false
|
||||
|
||||
def execute(state: CircuitState): CircuitState = {
|
||||
val c = state.circuit
|
||||
val newTopName = state.annotations.collectFirst { case ReParentCircuitAnnotation(tgt) =>
|
||||
tgt.module
|
||||
}
|
||||
val newCircuit = c.copy(main = newTopName.getOrElse(c.main))
|
||||
val mainRename = newTopName.map { s =>
|
||||
val rmap = RenameMap()
|
||||
rmap.record(CircuitTarget(c.main), CircuitTarget(s))
|
||||
rmap
|
||||
}
|
||||
|
||||
val newAnnotations = newTopName
|
||||
.map({ topName =>
|
||||
// Update InstanceTargets and ReferenceTargets
|
||||
// Yes, these are identical functions, but the copy methods force separate implementations
|
||||
def updateInstance(t: InstanceTarget): Option[InstanceTarget] = {
|
||||
val idx = t.path.lastIndexWhere(_._2.value == topName)
|
||||
if (idx == -1) Some(t.copy(circuit = topName))
|
||||
else Some(t.copy(circuit = topName, module = topName, path = t.path.drop(idx + 1)))
|
||||
}
|
||||
def updateReference(t: ReferenceTarget): Option[ReferenceTarget] = {
|
||||
val idx = t.path.lastIndexWhere(_._2.value == topName)
|
||||
if (idx == -1) Some(t.copy(circuit = topName))
|
||||
else Some(t.copy(circuit = topName, module = topName, path = t.path.drop(idx + 1)))
|
||||
}
|
||||
|
||||
AnnotationSeq(
|
||||
state.annotations.toSeq
|
||||
.map({
|
||||
case x: SingleTargetAnnotation[InstanceTarget] if x.target.isInstanceOf[InstanceTarget] =>
|
||||
updateInstance(x.target).map(y => x.duplicate(y))
|
||||
case x: SingleTargetAnnotation[ReferenceTarget] if x.target.isInstanceOf[ReferenceTarget] =>
|
||||
updateReference(x.target).map(y => x.duplicate(y))
|
||||
case x: MultiTargetAnnotation =>
|
||||
val newTargets: Seq[Seq[Option[Target]]] = x.targets.map(_.map({
|
||||
case y: InstanceTarget => updateInstance(y)
|
||||
case y: ReferenceTarget => updateReference(y)
|
||||
case y => Some(y)
|
||||
}))
|
||||
if (newTargets.flatten.forall(_.isDefined)) Some(x.duplicate(newTargets.map(_.map(_.get)))) else None
|
||||
case x => Some(x)
|
||||
})
|
||||
.filter(_.isDefined)
|
||||
.map(_.get)
|
||||
)
|
||||
})
|
||||
.getOrElse(state.annotations)
|
||||
|
||||
state.copy(circuit = newCircuit, renames = mainRename, annotations = newAnnotations)
|
||||
}
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
// See LICENSE for license details.
|
||||
|
||||
package barstools.tapeout.transforms
|
||||
|
||||
import firrtl._
|
||||
import firrtl.annotations.ModuleTarget
|
||||
import firrtl.ir._
|
||||
import firrtl.options.Dependency
|
||||
import firrtl.passes.memlib.ReplSeqMem
|
||||
import firrtl.stage.Forms
|
||||
import firrtl.stage.TransformManager.TransformDependency
|
||||
|
||||
// Removes all the unused modules in a circuit by recursing through every
|
||||
// instance (starting at the main module)
|
||||
class RemoveUnusedModules extends Transform with DependencyAPIMigration {
|
||||
|
||||
override def prerequisites: Seq[TransformDependency] = Forms.HighForm
|
||||
override def optionalPrerequisites: Seq[TransformDependency] = Seq.empty
|
||||
override def optionalPrerequisiteOf: Seq[TransformDependency] = {
|
||||
Forms.HighEmitters :+ Dependency[ReplSeqMem]
|
||||
}
|
||||
override def invalidates(a: Transform): Boolean = false
|
||||
|
||||
def execute(state: CircuitState): CircuitState = {
|
||||
val modulesByName = state.circuit.modules.map {
|
||||
case m: Module => (m.name, Some(m))
|
||||
case m: ExtModule => (m.name, None)
|
||||
}.toMap
|
||||
|
||||
def getUsedModules(om: Option[Module]): Set[String] = {
|
||||
om match {
|
||||
case Some(m) => {
|
||||
def someStatements(statement: Statement): Seq[Statement] =
|
||||
statement match {
|
||||
case b: Block =>
|
||||
b.stmts.map { someStatements(_) }
|
||||
.foldLeft(Seq[Statement]())(_ ++ _)
|
||||
case when: Conditionally =>
|
||||
someStatements(when.conseq) ++ someStatements(when.alt)
|
||||
case i: DefInstance => Seq(i)
|
||||
case _ => Seq()
|
||||
}
|
||||
|
||||
someStatements(m.body).map {
|
||||
case s: DefInstance => Set(s.module) | getUsedModules(modulesByName(s.module))
|
||||
case _ => Set[String]()
|
||||
}.foldLeft(Set(m.name))(_ | _)
|
||||
}
|
||||
|
||||
case None => Set.empty[String]
|
||||
}
|
||||
}
|
||||
val usedModuleSet = getUsedModules(modulesByName(state.circuit.main))
|
||||
|
||||
val usedModuleSeq = state.circuit.modules.filter { usedModuleSet contains _.name }
|
||||
val usedModuleNames = usedModuleSeq.map(_.name)
|
||||
|
||||
val renames = state.renames.getOrElse(RenameMap())
|
||||
|
||||
state.circuit.modules.filterNot { usedModuleSet contains _.name }.foreach { x =>
|
||||
renames.record(ModuleTarget(state.circuit.main, x.name), Nil)
|
||||
}
|
||||
|
||||
val newCircuit = Circuit(state.circuit.info, usedModuleSeq, state.circuit.main)
|
||||
state.copy(circuit = newCircuit, renames = Some(renames))
|
||||
}
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
// See LICENSE for license details.
|
||||
|
||||
package barstools.tapeout.transforms
|
||||
|
||||
import chisel3.experimental.RunFirrtlTransform
|
||||
import firrtl.PrimOps.Not
|
||||
import firrtl.annotations.{Annotation, CircuitName, ModuleName, SingleTargetAnnotation}
|
||||
import firrtl.ir._
|
||||
import firrtl.passes.Pass
|
||||
import firrtl.stage.Forms
|
||||
import firrtl.stage.TransformManager.TransformDependency
|
||||
import firrtl.{CircuitState, DependencyAPIMigration, Transform}
|
||||
|
||||
case class ResetInverterAnnotation(target: ModuleName) extends SingleTargetAnnotation[ModuleName] {
|
||||
override def duplicate(n: ModuleName): Annotation = ResetInverterAnnotation(n)
|
||||
}
|
||||
|
||||
object ResetN extends Pass {
|
||||
private val Bool = UIntType(IntWidth(1))
|
||||
// Only works on Modules with a Bool port named reset
|
||||
def invertReset(mod: Module): Module = {
|
||||
// Check that it actually has reset
|
||||
require(mod.ports.exists(p => p.name == "reset" && p.tpe == Bool), "Can only invert reset on a module with reset!")
|
||||
// Rename "reset" to "reset_n"
|
||||
val portsx = mod.ports.map {
|
||||
case Port(info, "reset", Input, Bool) =>
|
||||
Port(info, "reset_n", Input, Bool)
|
||||
case other => other
|
||||
}
|
||||
val newReset = DefNode(NoInfo, "reset", DoPrim(Not, Seq(Reference("reset_n", Bool)), Seq.empty, Bool))
|
||||
val bodyx = Block(Seq(newReset, mod.body))
|
||||
mod.copy(ports = portsx, body = bodyx)
|
||||
}
|
||||
|
||||
def run(c: Circuit): Circuit = {
|
||||
c.copy(modules = c.modules.map {
|
||||
case mod: Module if mod.name == c.main => invertReset(mod)
|
||||
case other => other
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
class ResetInverterTransform extends Transform with DependencyAPIMigration {
|
||||
|
||||
override def prerequisites: Seq[TransformDependency] = Forms.LowForm
|
||||
override def optionalPrerequisites: Seq[TransformDependency] = Forms.LowFormOptimized
|
||||
override def optionalPrerequisiteOf: Seq[TransformDependency] = Forms.LowEmitters
|
||||
override def invalidates(a: Transform): Boolean = false
|
||||
|
||||
override def execute(state: CircuitState): CircuitState = {
|
||||
state.annotations.filter(_.isInstanceOf[ResetInverterAnnotation]) match {
|
||||
case Nil => state
|
||||
case Seq(ResetInverterAnnotation(ModuleName(state.circuit.main, CircuitName(_)))) =>
|
||||
state.copy(circuit = ResetN.run(state.circuit))
|
||||
case annotations =>
|
||||
throw new Exception(s"There should be only one InvertReset annotation: got ${annotations.mkString(" -- ")}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
trait ResetInverter {
|
||||
self: chisel3.Module =>
|
||||
def invert[T <: chisel3.Module](module: T): Unit = {
|
||||
chisel3.experimental.annotate(new chisel3.experimental.ChiselAnnotation with RunFirrtlTransform {
|
||||
def transformClass: Class[_ <: Transform] = classOf[ResetInverterTransform]
|
||||
def toFirrtl: Annotation = ResetInverterAnnotation(module.toNamed)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ package barstools.tapeout.transforms.stage
|
||||
|
||||
import barstools.tapeout.transforms.GenerateModelStageMain
|
||||
import chisel3.stage.ChiselCli
|
||||
import firrtl.stage.{RunFirrtlTransformAnnotation}
|
||||
import firrtl.AnnotationSeq
|
||||
import firrtl.annotations.{Annotation, NoTargetAnnotation}
|
||||
import firrtl.options.{HasShellOptions, Shell, ShellOption, Stage, Unserializable}
|
||||
@@ -27,12 +28,32 @@ object OutAnnoAnnotation extends HasShellOptions {
|
||||
)
|
||||
}
|
||||
|
||||
case class CompilerNameAnnotation(name: String) extends NoTargetAnnotation with TapeoutOption
|
||||
|
||||
// duplicate of firrtl.stage.CompilerAnnotation but needed so that you can have a
|
||||
// CompilerAnnotation to match on when adding new transforms
|
||||
object DuplicateCompilerAnnotation extends HasShellOptions {
|
||||
val options: Seq[ShellOption[_]] = Seq(
|
||||
new ShellOption[String](
|
||||
longOption = "duplicate-compiler",
|
||||
shortOption = Some("DX"),
|
||||
toAnnotationSeq = (s: String) => {
|
||||
Seq(
|
||||
CompilerNameAnnotation(s))
|
||||
},
|
||||
helpText = "duplicate-compiler",
|
||||
helpValueName = Some("same as --compiler FIRRTL flag")
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
trait TapeoutCli {
|
||||
this: Shell =>
|
||||
parser.note("Tapeout specific options")
|
||||
|
||||
Seq(
|
||||
OutAnnoAnnotation
|
||||
OutAnnoAnnotation,
|
||||
DuplicateCompilerAnnotation
|
||||
).foreach(_.addOptions(parser))
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user