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._
|
||||||
import firrtl.ir._
|
import firrtl.ir._
|
||||||
import firrtl.annotations._
|
|
||||||
import firrtl.Mappers._
|
import firrtl.Mappers._
|
||||||
import firrtl.stage.Forms
|
import firrtl.annotations.{ModuleTarget, SingleTargetAnnotation, CircuitTarget}
|
||||||
import firrtl.stage.TransformManager.TransformDependency
|
import firrtl.stage.TransformManager.{TransformDependency}
|
||||||
|
import firrtl.stage.{Forms}
|
||||||
|
|
||||||
case class KeepNameAnnotation(target: ModuleTarget)
|
case class KeepNameAnnotation(target: ModuleTarget)
|
||||||
extends SingleTargetAnnotation[ModuleTarget] {
|
extends SingleTargetAnnotation[ModuleTarget] {
|
||||||
@@ -19,32 +19,36 @@ case class ModuleNameSuffixAnnotation(target: CircuitTarget, suffix: String)
|
|||||||
def duplicate(n: CircuitTarget) = this.copy(target = n)
|
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 {
|
class AddSuffixToModuleNames extends Transform with DependencyAPIMigration {
|
||||||
|
|
||||||
override def prerequisites: Seq[TransformDependency] = Forms.LowForm
|
override def prerequisites: Seq[TransformDependency] = Forms.LowForm
|
||||||
override def optionalPrerequisites: Seq[TransformDependency] = Forms.LowFormOptimized
|
override def optionalPrerequisites: Seq[TransformDependency] = Forms.LowFormOptimized
|
||||||
override def optionalPrerequisiteOf: Seq[TransformDependency] = Forms.LowEmitters
|
override def optionalPrerequisiteOf: Seq[TransformDependency] = Forms.LowEmitters
|
||||||
|
override def invalidates(a: Transform): Boolean = false
|
||||||
|
|
||||||
def processAnnos(annos: AnnotationSeq): (AnnotationSeq, (String) => String) = {
|
def determineRenamerandAnnos(state: CircuitState): (AnnotationSeq, (String) => String) = {
|
||||||
val whitelist = annos.collect({ case KeepNameAnnotation(tgt) => tgt.module }).toSet
|
// remove determine suffix annotation
|
||||||
val newAnnos = annos.filterNot(_.isInstanceOf[ModuleNameSuffixAnnotation])
|
val newAnnos = state.annotations.filterNot(_.isInstanceOf[ModuleNameSuffixAnnotation])
|
||||||
val suffixes = annos.collect({ case ModuleNameSuffixAnnotation(_, suffix) => suffix })
|
val suffixes = state.annotations.collect({ case ModuleNameSuffixAnnotation(_, suffix) => suffix })
|
||||||
require(suffixes.length <= 1)
|
require(suffixes.length <= 1)
|
||||||
|
|
||||||
val suffix = suffixes.headOption.getOrElse("")
|
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)
|
(newAnnos, renamer)
|
||||||
}
|
}
|
||||||
|
|
||||||
def renameInstanceModules(renamer: (String) => String)(stmt: Statement): Statement = {
|
def renameInstanceModules(renamer: (String) => String)(stmt: Statement): Statement = {
|
||||||
stmt match {
|
stmt match {
|
||||||
case m: DefInstance => new DefInstance(m.info, m.name, renamer(m.module))
|
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)) // if is statement, recurse
|
||||||
case s => s map renameInstanceModules(renamer)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,7 +65,7 @@ class AddSuffixToModuleNames extends Transform with DependencyAPIMigration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
def execute(state: CircuitState): CircuitState = {
|
def execute(state: CircuitState): CircuitState = {
|
||||||
val (newAnnos, renamer) = processAnnos(state.annotations)
|
val (newAnnos, renamer) = determineRenamerandAnnos(state)
|
||||||
val (ret, renames) = run(state, renamer)
|
val (ret, renames) = run(state, renamer)
|
||||||
state.copy(circuit = ret, annotations = newAnnos, renames = Some(renames))
|
state.copy(circuit = ret, annotations = newAnnos, renames = Some(renames))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,13 +4,20 @@ package barstools.tapeout.transforms
|
|||||||
|
|
||||||
import firrtl._
|
import firrtl._
|
||||||
import firrtl.ir._
|
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
|
case class LinkExtModulesAnnotation(mustLink: Seq[ExtModule]) extends NoTargetAnnotation
|
||||||
|
|
||||||
class AvoidExtModuleCollisions extends Transform {
|
class AvoidExtModuleCollisions extends Transform with DependencyAPIMigration {
|
||||||
def inputForm = HighForm
|
|
||||||
def outputForm = HighForm
|
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 = {
|
def execute(state: CircuitState): CircuitState = {
|
||||||
val mustLink = state.annotations.flatMap {
|
val mustLink = state.annotations.flatMap {
|
||||||
case LinkExtModulesAnnotation(mustLink) => mustLink
|
case LinkExtModulesAnnotation(mustLink) => mustLink
|
||||||
|
|||||||
@@ -3,9 +3,12 @@
|
|||||||
package barstools.tapeout.transforms
|
package barstools.tapeout.transforms
|
||||||
|
|
||||||
import firrtl._
|
import firrtl._
|
||||||
import firrtl.annotations._
|
|
||||||
import firrtl.ir._
|
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)
|
case class ConvertToExtModAnnotation(target: ModuleTarget)
|
||||||
extends SingleTargetAnnotation[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
|
// Converts some modules to external modules, based on a given function. If
|
||||||
// that function returns "true" then the module is converted into an ExtModule,
|
// that function returns "true" then the module is converted into an ExtModule,
|
||||||
// otherwise it's left alone.
|
// otherwise it's left alone.
|
||||||
class ConvertToExtMod extends Transform {
|
class ConvertToExtMod extends Transform with DependencyAPIMigration {
|
||||||
def inputForm = HighForm
|
|
||||||
def outputForm = HighForm
|
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) = {
|
def run(state: CircuitState, makeExt: Set[String]): (Circuit, RenameMap) = {
|
||||||
val renames = RenameMap()
|
val renames = RenameMap()
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ class EnumerateModules(enumerate: (Module) => Unit)
|
|||||||
override def prerequisites: Seq[TransformDependency] = Forms.LowForm
|
override def prerequisites: Seq[TransformDependency] = Forms.LowForm
|
||||||
override def optionalPrerequisites: Seq[TransformDependency] = Forms.LowFormOptimized
|
override def optionalPrerequisites: Seq[TransformDependency] = Forms.LowFormOptimized
|
||||||
override def optionalPrerequisiteOf: Seq[TransformDependency] = Forms.LowEmitters
|
override def optionalPrerequisiteOf: Seq[TransformDependency] = Forms.LowEmitters
|
||||||
|
override def invalidates(a: Transform): Boolean = false
|
||||||
|
|
||||||
def transforms: Seq[Transform] = Seq(new EnumerateModulesPass(enumerate))
|
def transforms: Seq[Transform] = Seq(new EnumerateModulesPass(enumerate))
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import firrtl.annotations._
|
|||||||
import firrtl.ir._
|
import firrtl.ir._
|
||||||
import firrtl.passes.memlib.ReplSeqMemAnnotation
|
import firrtl.passes.memlib.ReplSeqMemAnnotation
|
||||||
import firrtl.stage.FirrtlCircuitAnnotation
|
import firrtl.stage.FirrtlCircuitAnnotation
|
||||||
import firrtl.transforms.BlackBoxResourceFileNameAnno
|
import firrtl.transforms.{BlackBoxResourceFileNameAnno, DedupModules}
|
||||||
import logger.LazyLogging
|
import logger.LazyLogging
|
||||||
|
|
||||||
trait HasTapeoutOptions { self: ExecutionOptionsManager with HasFirrtlOptions =>
|
trait HasTapeoutOptions { self: ExecutionOptionsManager with HasFirrtlOptions =>
|
||||||
@@ -156,6 +156,7 @@ sealed trait GenerateTopAndHarnessApp extends LazyLogging { this: App =>
|
|||||||
// FIRRTL options
|
// FIRRTL options
|
||||||
lazy val annoFiles = firrtlOptions.annotationFileNames
|
lazy val annoFiles = firrtlOptions.annotationFileNames
|
||||||
|
|
||||||
|
// order is determined by DependencyAPIMigration
|
||||||
val topTransforms = Seq(
|
val topTransforms = Seq(
|
||||||
new ReParentCircuit,
|
new ReParentCircuit,
|
||||||
new RemoveUnusedModules
|
new RemoveUnusedModules
|
||||||
@@ -171,6 +172,7 @@ sealed trait GenerateTopAndHarnessApp extends LazyLogging { this: App =>
|
|||||||
annotations = firrtlOptions.annotations ++ topAnnos
|
annotations = firrtlOptions.annotations ++ topAnnos
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// order is determined by DependencyAPIMigration
|
||||||
val harnessTransforms = Seq(
|
val harnessTransforms = Seq(
|
||||||
new ConvertToExtMod,
|
new ConvertToExtMod,
|
||||||
new RemoveUnusedModules,
|
new RemoveUnusedModules,
|
||||||
@@ -216,11 +218,8 @@ sealed trait GenerateTopAndHarnessApp extends LazyLogging { this: App =>
|
|||||||
// Execute top and get list of ExtModules to avoid collisions
|
// Execute top and get list of ExtModules to avoid collisions
|
||||||
val topExtModules = executeTop()
|
val topExtModules = executeTop()
|
||||||
|
|
||||||
val externals = Seq("SimSerial", "SimDTM", "plusarg_reader") ++ harnessTop ++ synTop
|
|
||||||
|
|
||||||
val harnessAnnos =
|
val harnessAnnos =
|
||||||
tapeoutOptions.harnessDotfOut.map(BlackBoxResourceFileNameAnno(_)).toSeq ++
|
tapeoutOptions.harnessDotfOut.map(BlackBoxResourceFileNameAnno(_)).toSeq ++
|
||||||
externals.map(ext => KeepNameAnnotation(rootCircuitTarget.module(ext))) ++
|
|
||||||
harnessTop.map(ht => ModuleNameSuffixAnnotation(rootCircuitTarget, s"_in${ht}")) ++
|
harnessTop.map(ht => ModuleNameSuffixAnnotation(rootCircuitTarget, s"_in${ht}")) ++
|
||||||
synTop.map(st => ConvertToExtModAnnotation(rootCircuitTarget.module(st))) :+
|
synTop.map(st => ConvertToExtModAnnotation(rootCircuitTarget.module(st))) :+
|
||||||
LinkExtModulesAnnotation(topExtModules)
|
LinkExtModulesAnnotation(topExtModules)
|
||||||
|
|||||||
@@ -4,17 +4,24 @@ package barstools.tapeout.transforms
|
|||||||
|
|
||||||
import firrtl._
|
import firrtl._
|
||||||
import firrtl.ir._
|
import firrtl.ir._
|
||||||
import firrtl.passes.Pass
|
|
||||||
import firrtl.annotations._
|
import firrtl.annotations._
|
||||||
|
import firrtl.options.{Dependency}
|
||||||
|
import firrtl.stage.TransformManager.{TransformDependency}
|
||||||
|
import firrtl.stage.{Forms}
|
||||||
|
|
||||||
case class ReParentCircuitAnnotation(target: ModuleTarget)
|
case class ReParentCircuitAnnotation(target: ModuleTarget)
|
||||||
extends SingleTargetAnnotation[ModuleTarget] {
|
extends SingleTargetAnnotation[ModuleTarget] {
|
||||||
def duplicate(n: ModuleTarget) = this.copy(n)
|
def duplicate(n: ModuleTarget) = this.copy(n)
|
||||||
}
|
}
|
||||||
|
|
||||||
class ReParentCircuit extends Transform {
|
class ReParentCircuit extends Transform with DependencyAPIMigration {
|
||||||
def inputForm = HighForm
|
|
||||||
def outputForm = HighForm
|
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 = {
|
def execute(state: CircuitState): CircuitState = {
|
||||||
val c = state.circuit
|
val c = state.circuit
|
||||||
|
|||||||
@@ -4,15 +4,22 @@ package barstools.tapeout.transforms
|
|||||||
|
|
||||||
import firrtl._
|
import firrtl._
|
||||||
import firrtl.ir._
|
import firrtl.ir._
|
||||||
import firrtl.passes.Pass
|
import firrtl.annotations.{ModuleTarget}
|
||||||
import firrtl.annotations._
|
import firrtl.stage.TransformManager.{TransformDependency}
|
||||||
import firrtl.transforms.DontTouchAnnotation
|
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
|
// Removes all the unused modules in a circuit by recursing through every
|
||||||
// instance (starting at the main module)
|
// instance (starting at the main module)
|
||||||
class RemoveUnusedModules extends Transform {
|
class RemoveUnusedModules extends Transform with DependencyAPIMigration {
|
||||||
def inputForm = HighForm
|
|
||||||
def outputForm = HighForm
|
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 = {
|
def execute(state: CircuitState): CircuitState = {
|
||||||
val modulesByName = state.circuit.modules.map{
|
val modulesByName = state.circuit.modules.map{
|
||||||
@@ -25,19 +32,17 @@ class RemoveUnusedModules extends Transform {
|
|||||||
case Some(m) => {
|
case Some(m) => {
|
||||||
def someStatements(statement: Statement): Seq[Statement] =
|
def someStatements(statement: Statement): Seq[Statement] =
|
||||||
statement match {
|
statement match {
|
||||||
case b: Block =>
|
case b: Block =>
|
||||||
b.stmts.map{ someStatements(_) }
|
b.stmts.map{ someStatements(_) }
|
||||||
.foldLeft(Seq[Statement]())(_ ++ _)
|
.foldLeft(Seq[Statement]())(_ ++ _)
|
||||||
case when: Conditionally =>
|
case when: Conditionally =>
|
||||||
someStatements(when.conseq) ++ someStatements(when.alt)
|
someStatements(when.conseq) ++ someStatements(when.alt)
|
||||||
case i: DefInstance => Seq(i)
|
case i: DefInstance => Seq(i)
|
||||||
case w: WDefInstance => Seq(w)
|
|
||||||
case _ => Seq()
|
case _ => Seq()
|
||||||
}
|
}
|
||||||
|
|
||||||
someStatements(m.body).map{
|
someStatements(m.body).map{
|
||||||
case s: DefInstance => Set(s.module) | getUsedModules(modulesByName(s.module))
|
case s: DefInstance => Set(s.module) | getUsedModules(modulesByName(s.module))
|
||||||
case s: WDefInstance => Set(s.module) | getUsedModules(modulesByName(s.module))
|
|
||||||
case _ => Set[String]()
|
case _ => Set[String]()
|
||||||
}.foldLeft(Set(m.name))(_ | _)
|
}.foldLeft(Set(m.name))(_ | _)
|
||||||
}
|
}
|
||||||
@@ -52,7 +57,9 @@ class RemoveUnusedModules extends Transform {
|
|||||||
|
|
||||||
val renames = state.renames.getOrElse(RenameMap())
|
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)
|
val newCircuit = Circuit(state.circuit.info, usedModuleSeq, state.circuit.main)
|
||||||
state.copy(circuit = newCircuit, renames = Some(renames))
|
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 prerequisites: Seq[TransformDependency] = Forms.LowForm
|
||||||
override def optionalPrerequisites: Seq[TransformDependency] = Forms.LowFormOptimized
|
override def optionalPrerequisites: Seq[TransformDependency] = Forms.LowFormOptimized
|
||||||
override def optionalPrerequisiteOf: Seq[TransformDependency] = Forms.LowEmitters
|
override def optionalPrerequisiteOf: Seq[TransformDependency] = Forms.LowEmitters
|
||||||
|
override def invalidates(a: Transform): Boolean = false
|
||||||
|
|
||||||
override def execute(state: CircuitState): CircuitState = {
|
override def execute(state: CircuitState): CircuitState = {
|
||||||
state.annotations.filter(_.isInstanceOf[ResetInverterAnnotation]) match {
|
state.annotations.filter(_.isInstanceOf[ResetInverterAnnotation]) match {
|
||||||
|
|||||||
Reference in New Issue
Block a user