From 9be550e23d2f6a2968f35719ba55edb8aefaf138 Mon Sep 17 00:00:00 2001 From: abejgonzalez Date: Wed, 25 Nov 2020 16:27:52 -0800 Subject: [PATCH] Bump to new dep. API | Automatically avoid renaming ExtMod's and circuit top mod --- .../transforms/AddSuffixToModuleNames.scala | 36 ++++++++++--------- .../transforms/AvoidExtModuleCollisions.scala | 15 +++++--- .../transforms/ConvertToExtModPass.scala | 18 +++++++--- .../scala/transforms/EnumerateModules.scala | 1 + .../src/main/scala/transforms/Generate.scala | 7 ++-- .../scala/transforms/ReParentCircuit.scala | 15 +++++--- .../transforms/RemoveUnusedModules.scala | 27 ++++++++------ .../main/scala/transforms/ResetInverter.scala | 1 + 8 files changed, 77 insertions(+), 43 deletions(-) diff --git a/tapeout/src/main/scala/transforms/AddSuffixToModuleNames.scala b/tapeout/src/main/scala/transforms/AddSuffixToModuleNames.scala index ab1dd487..26de5425 100644 --- a/tapeout/src/main/scala/transforms/AddSuffixToModuleNames.scala +++ b/tapeout/src/main/scala/transforms/AddSuffixToModuleNames.scala @@ -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)) } diff --git a/tapeout/src/main/scala/transforms/AvoidExtModuleCollisions.scala b/tapeout/src/main/scala/transforms/AvoidExtModuleCollisions.scala index df1e272e..74dfda2f 100644 --- a/tapeout/src/main/scala/transforms/AvoidExtModuleCollisions.scala +++ b/tapeout/src/main/scala/transforms/AvoidExtModuleCollisions.scala @@ -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 diff --git a/tapeout/src/main/scala/transforms/ConvertToExtModPass.scala b/tapeout/src/main/scala/transforms/ConvertToExtModPass.scala index 83486fd5..04e645fd 100644 --- a/tapeout/src/main/scala/transforms/ConvertToExtModPass.scala +++ b/tapeout/src/main/scala/transforms/ConvertToExtModPass.scala @@ -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() diff --git a/tapeout/src/main/scala/transforms/EnumerateModules.scala b/tapeout/src/main/scala/transforms/EnumerateModules.scala index a2b499fd..6a732d75 100644 --- a/tapeout/src/main/scala/transforms/EnumerateModules.scala +++ b/tapeout/src/main/scala/transforms/EnumerateModules.scala @@ -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)) diff --git a/tapeout/src/main/scala/transforms/Generate.scala b/tapeout/src/main/scala/transforms/Generate.scala index 12e222e5..17b8781d 100644 --- a/tapeout/src/main/scala/transforms/Generate.scala +++ b/tapeout/src/main/scala/transforms/Generate.scala @@ -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) diff --git a/tapeout/src/main/scala/transforms/ReParentCircuit.scala b/tapeout/src/main/scala/transforms/ReParentCircuit.scala index 574d9dda..cbf4d2f8 100644 --- a/tapeout/src/main/scala/transforms/ReParentCircuit.scala +++ b/tapeout/src/main/scala/transforms/ReParentCircuit.scala @@ -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 diff --git a/tapeout/src/main/scala/transforms/RemoveUnusedModules.scala b/tapeout/src/main/scala/transforms/RemoveUnusedModules.scala index 24eb35f6..3feb6736 100644 --- a/tapeout/src/main/scala/transforms/RemoveUnusedModules.scala +++ b/tapeout/src/main/scala/transforms/RemoveUnusedModules.scala @@ -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)) diff --git a/tapeout/src/main/scala/transforms/ResetInverter.scala b/tapeout/src/main/scala/transforms/ResetInverter.scala index f9282251..1ccb1888 100644 --- a/tapeout/src/main/scala/transforms/ResetInverter.scala +++ b/tapeout/src/main/scala/transforms/ResetInverter.scala @@ -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 {