Bump to new dep. API | Automatically avoid renaming ExtMod's and circuit top mod

This commit is contained in:
abejgonzalez
2020-11-25 16:27:52 -08:00
parent 845af06b15
commit 9be550e23d
8 changed files with 77 additions and 43 deletions

View File

@@ -4,10 +4,10 @@ package barstools.tapeout.transforms
import firrtl._
import firrtl.ir._
import firrtl.annotations._
import firrtl.Mappers._
import firrtl.stage.Forms
import firrtl.stage.TransformManager.TransformDependency
import firrtl.annotations.{ModuleTarget, SingleTargetAnnotation, CircuitTarget}
import firrtl.stage.TransformManager.{TransformDependency}
import firrtl.stage.{Forms}
case class KeepNameAnnotation(target: ModuleTarget)
extends SingleTargetAnnotation[ModuleTarget] {
@@ -19,32 +19,36 @@ case class ModuleNameSuffixAnnotation(target: CircuitTarget, suffix: String)
def duplicate(n: CircuitTarget) = this.copy(target = n)
}
// This doesn't rename ExtModules under the assumption that they're some
// Verilog black box and therefore can't be renamed. Since the point is to
// allow FIRRTL to be linked together using "cat" and ExtModules don't get
// emitted, this should be safe.
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 processAnnos(annos: AnnotationSeq): (AnnotationSeq, (String) => String) = {
val whitelist = annos.collect({ case KeepNameAnnotation(tgt) => tgt.module }).toSet
val newAnnos = annos.filterNot(_.isInstanceOf[ModuleNameSuffixAnnotation])
val suffixes = annos.collect({ case ModuleNameSuffixAnnotation(_, suffix) => suffix })
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("")
val renamer = { name: String => if (whitelist(name)) name else name + suffix }
// 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 m: WDefInstance => new WDefInstance(m.info, m.name, renamer(m.module), m.tpe)
case s => s map renameInstanceModules(renamer)
case s => s.map(renameInstanceModules(renamer)) // if is statement, recurse
}
}
@@ -61,7 +65,7 @@ class AddSuffixToModuleNames extends Transform with DependencyAPIMigration {
}
def execute(state: CircuitState): CircuitState = {
val (newAnnos, renamer) = processAnnos(state.annotations)
val (newAnnos, renamer) = determineRenamerandAnnos(state)
val (ret, renames) = run(state, renamer)
state.copy(circuit = ret, annotations = newAnnos, renames = Some(renames))
}

View File

@@ -4,13 +4,20 @@ package barstools.tapeout.transforms
import firrtl._
import firrtl.ir._
import firrtl.annotations._
import firrtl.annotations.{NoTargetAnnotation}
import firrtl.options.{Dependency}
import firrtl.stage.TransformManager.{TransformDependency}
import firrtl.stage.{Forms}
case class LinkExtModulesAnnotation(mustLink: Seq[ExtModule]) extends NoTargetAnnotation
class AvoidExtModuleCollisions extends Transform {
def inputForm = HighForm
def outputForm = HighForm
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
override def invalidates(a: Transform): Boolean = false
def execute(state: CircuitState): CircuitState = {
val mustLink = state.annotations.flatMap {
case LinkExtModulesAnnotation(mustLink) => mustLink

View File

@@ -3,9 +3,12 @@
package barstools.tapeout.transforms
import firrtl._
import firrtl.annotations._
import firrtl.ir._
import firrtl.passes.Pass
import firrtl.annotations.{ModuleTarget, SingleTargetAnnotation, ReferenceTarget}
import firrtl.stage.TransformManager.{TransformDependency}
import firrtl.stage.{Forms}
import firrtl.options.{Dependency}
import firrtl.passes.memlib.{ReplSeqMem}
case class ConvertToExtModAnnotation(target: ModuleTarget)
extends SingleTargetAnnotation[ModuleTarget] {
@@ -15,9 +18,14 @@ case class ConvertToExtModAnnotation(target: ModuleTarget)
// 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 {
def inputForm = HighForm
def outputForm = HighForm
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()

View File

@@ -28,6 +28,7 @@ class EnumerateModules(enumerate: (Module) => Unit)
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))

View File

@@ -5,7 +5,7 @@ import firrtl.annotations._
import firrtl.ir._
import firrtl.passes.memlib.ReplSeqMemAnnotation
import firrtl.stage.FirrtlCircuitAnnotation
import firrtl.transforms.BlackBoxResourceFileNameAnno
import firrtl.transforms.{BlackBoxResourceFileNameAnno, DedupModules}
import logger.LazyLogging
trait HasTapeoutOptions { self: ExecutionOptionsManager with HasFirrtlOptions =>
@@ -156,6 +156,7 @@ sealed trait GenerateTopAndHarnessApp extends LazyLogging { this: App =>
// FIRRTL options
lazy val annoFiles = firrtlOptions.annotationFileNames
// order is determined by DependencyAPIMigration
val topTransforms = Seq(
new ReParentCircuit,
new RemoveUnusedModules
@@ -171,6 +172,7 @@ sealed trait GenerateTopAndHarnessApp extends LazyLogging { this: App =>
annotations = firrtlOptions.annotations ++ topAnnos
)
// order is determined by DependencyAPIMigration
val harnessTransforms = Seq(
new ConvertToExtMod,
new RemoveUnusedModules,
@@ -216,11 +218,8 @@ sealed trait GenerateTopAndHarnessApp extends LazyLogging { this: App =>
// Execute top and get list of ExtModules to avoid collisions
val topExtModules = executeTop()
val externals = Seq("SimSerial", "SimDTM", "plusarg_reader") ++ harnessTop ++ synTop
val harnessAnnos =
tapeoutOptions.harnessDotfOut.map(BlackBoxResourceFileNameAnno(_)).toSeq ++
externals.map(ext => KeepNameAnnotation(rootCircuitTarget.module(ext))) ++
harnessTop.map(ht => ModuleNameSuffixAnnotation(rootCircuitTarget, s"_in${ht}")) ++
synTop.map(st => ConvertToExtModAnnotation(rootCircuitTarget.module(st))) :+
LinkExtModulesAnnotation(topExtModules)

View File

@@ -4,17 +4,24 @@ package barstools.tapeout.transforms
import firrtl._
import firrtl.ir._
import firrtl.passes.Pass
import firrtl.annotations._
import firrtl.options.{Dependency}
import firrtl.stage.TransformManager.{TransformDependency}
import firrtl.stage.{Forms}
case class ReParentCircuitAnnotation(target: ModuleTarget)
extends SingleTargetAnnotation[ModuleTarget] {
def duplicate(n: ModuleTarget) = this.copy(n)
}
class ReParentCircuit extends Transform {
def inputForm = HighForm
def outputForm = HighForm
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

View File

@@ -4,15 +4,22 @@ package barstools.tapeout.transforms
import firrtl._
import firrtl.ir._
import firrtl.passes.Pass
import firrtl.annotations._
import firrtl.transforms.DontTouchAnnotation
import firrtl.annotations.{ModuleTarget}
import firrtl.stage.TransformManager.{TransformDependency}
import firrtl.options.{Dependency}
import firrtl.stage.{Forms}
import firrtl.passes.memlib.{ReplSeqMem}
// Removes all the unused modules in a circuit by recursing through every
// instance (starting at the main module)
class RemoveUnusedModules extends Transform {
def inputForm = HighForm
def outputForm = HighForm
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{
@@ -25,19 +32,17 @@ class RemoveUnusedModules extends Transform {
case Some(m) => {
def someStatements(statement: Statement): Seq[Statement] =
statement match {
case b: Block =>
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 w: WDefInstance => Seq(w)
case _ => Seq()
}
someStatements(m.body).map{
case s: DefInstance => Set(s.module) | getUsedModules(modulesByName(s.module))
case s: WDefInstance => Set(s.module) | getUsedModules(modulesByName(s.module))
case _ => Set[String]()
}.foldLeft(Set(m.name))(_ | _)
}
@@ -52,7 +57,9 @@ class RemoveUnusedModules extends Transform {
val renames = state.renames.getOrElse(RenameMap())
state.circuit.modules.filterNot { usedModuleSet contains _.name } foreach { x => renames.record(ModuleTarget(state.circuit.main, x.name), Nil) }
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))

View File

@@ -46,6 +46,7 @@ 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 {