Bump to new dep. API | Automatically avoid renaming ExtMod's and circuit top mod
This commit is contained in:
@@ -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))
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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))
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user