aboutsummaryrefslogtreecommitdiff
path: root/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'src/main')
-rw-r--r--src/main/scala/firrtl/Compiler.scala83
-rw-r--r--src/main/scala/firrtl/Driver.scala109
-rw-r--r--src/main/scala/firrtl/LoweringAnnotations.scala88
-rw-r--r--src/main/scala/firrtl/LoweringCompilers.scala20
-rw-r--r--src/main/scala/firrtl/passes/Inline.scala67
5 files changed, 156 insertions, 211 deletions
diff --git a/src/main/scala/firrtl/Compiler.scala b/src/main/scala/firrtl/Compiler.scala
index 49bf9395..4bc60c00 100644
--- a/src/main/scala/firrtl/Compiler.scala
+++ b/src/main/scala/firrtl/Compiler.scala
@@ -28,79 +28,64 @@ MODIFICATIONS.
package firrtl
import com.typesafe.scalalogging.LazyLogging
+import scala.collection.mutable
import java.io.Writer
+import Annotations._
-import firrtl.ir._
-import Utils._
-import firrtl.passes._
-
-
-// ===========================================
-// Annotations
-// -------------------------------------------
-case class AnnotationException(message: String) extends Exception(message)
-trait Named { def name: String }
-case class ModuleName(name: String) extends Named
-case class ComponentName(name: String, module: ModuleName) extends Named
-
-// - Associated with an arbitrary serializable annotation
-trait Annotation {
- def serialize: String
-}
-
-// - Used to identify which annotation is consumed by which pass
-trait CircuitAnnotationKind
-case object UnknownCAKind extends CircuitAnnotationKind
-
-// - A collection of annotations on a given circuit
-// - Call update to keep annotations synced with circuit after
-// a transformation modifies module or component names
-trait CircuitAnnotation {
- def kind: CircuitAnnotationKind
- def update (renames: RenameMap): CircuitAnnotation
-}
-
-// - A class that contains a map from old name to modified names
-// - Generated by transformations that modify names
-trait RenameMap { def map: Map[Named, Seq[Named]] }
-case class BasicRenameMap(map: Map[Named,Seq[Named]]) extends RenameMap
-
+import firrtl.ir.Circuit
+/**
+ * RenameMap maps old names to modified names. Generated by transformations
+ * that modify names
+ */
+case class RenameMap(map: Map[Named, Seq[Named]])
// ===========================================
// Transforms
// -------------------------------------------
case class TransformResult (
- circuit: Circuit,
- renames: Option[RenameMap] = None,
- annotation: Option[CircuitAnnotation] = None)
+ circuit: Circuit,
+ renames: Option[RenameMap] = None,
+ annotation: Option[AnnotationMap] = None)
// - Transforms a circuit
// - Can consume multiple CircuitAnnotation's
trait Transform {
- def execute (circuit: Circuit, annotations: Seq[CircuitAnnotation]): TransformResult
+ def execute (circuit: Circuit, annotationMap: AnnotationMap): TransformResult
}
+
// ===========================================
// Compilers
// -------------------------------------------
-case class CompilerResult (circuit: Circuit, annotations: Seq[CircuitAnnotation])
+case class CompilerResult (circuit: Circuit, annotationMap: AnnotationMap)
// - A sequence of transformations
// - Call compile to executes each transformation in sequence onto
// a given circuit.
-trait Compiler extends LazyLogging {
+trait Compiler {
def transforms(w: Writer): Seq[Transform]
- def compile(circuit: Circuit, annotations: Seq[CircuitAnnotation], writer: Writer): CompilerResult = {
- transforms(writer).foldLeft(CompilerResult(circuit,annotations))((in: CompilerResult, xform: Transform) => {
- val result = xform.execute(in.circuit,in.annotations)
- val in_remapped = result.renames match {
- case Some(renames) => in.annotations.map(_.update(renames))
- case None => in.annotations
+ def compile(circuit: Circuit, annotationMap: AnnotationMap, writer: Writer): CompilerResult = {
+ transforms(writer).foldLeft(CompilerResult(circuit,annotationMap))((in: CompilerResult, xform: Transform) => {
+ val result = xform.execute(in.circuit,in.annotationMap)
+ val remappedAnnotations: Seq[Annotation] = result.renames match {
+ case Some(RenameMap(rmap)) => {
+ // For each key in the rename map (rmap), obtain the
+ // corresponding annotations (in.annotationMap.get(from)). If any
+ // annotations exist, for each annotation, create a sequence of
+ // annotations with the names in rmap's value.
+ for{
+ (oldName, newNames) <- rmap.toSeq
+ tID2OldAnnos <- in.annotationMap.get(oldName).toSeq
+ oldAnno <- tID2OldAnnos.values
+ newAnno <- oldAnno.update(newNames)
+ } yield newAnno
+ }
+ case _ => in.annotationMap.annotations
}
- val full_annotations = in_remapped ++ result.annotation
- CompilerResult(result.circuit,full_annotations)
+ val full_annotations = new AnnotationMap((remappedAnnotations ++ result.annotation.getOrElse(new AnnotationMap(Seq.empty)).annotations).toSeq)
+ CompilerResult(result.circuit, full_annotations)
})
}
}
diff --git a/src/main/scala/firrtl/Driver.scala b/src/main/scala/firrtl/Driver.scala
index 684bc569..59a2bb87 100644
--- a/src/main/scala/firrtl/Driver.scala
+++ b/src/main/scala/firrtl/Driver.scala
@@ -30,6 +30,7 @@ package firrtl
import java.io.{PrintWriter, Writer, File}
import scala.io.Source
import scala.collection.mutable
+import Annotations._
import Utils._
import Parser.{InfoMode, IgnoreInfo, UseInfo, GenInfo, AppendInfo}
@@ -53,57 +54,98 @@ Options:
output: String,
compiler: Compiler,
infoMode: InfoMode = IgnoreInfo,
- annotations: Seq[CircuitAnnotation] = Seq.empty) = {
+ annotations: AnnotationMap = new AnnotationMap(Seq.empty)) = {
val parsedInput = Parser.parse(Source.fromFile(input).getLines, infoMode)
val writerOutput = new PrintWriter(new File(output))
compiler.compile(parsedInput, annotations, writerOutput)
writerOutput.close
}
- // Arguments specify the compiler, input file, and output file
+ /**
+ * Implements the default Firrtl compilers and an inlining pass.
+ *
+ * Arguments specify the compiler, input file, output file, and
+ * optionally the module/instances to inline.
+ */
def main(args: Array[String]) = {
- val arglist = args.toList
+ val usage = """
+ Usage: sbt "run-main firrtl.google.Driver -i <input_file> -o <output_file> -X <compiler> [--inline [<module_name>|<module_name>.<instance_name>]]"
+ firrtl -i <input_file> -o <output_file> -X <compiler> [--inline [<module_name>|<module_name>.<instance_name>]]
+ Options:
+ -X <compiler> Specify the target compiler
+ Currently supported: high low verilog
+ """
+
+ def handleInlineOption(value: String): Annotation =
+ value.split('.') match {
+ case Array(circuit) =>
+ passes.InlineAnnotation(CircuitName(circuit), TransID(0))
+ case Array(circuit, module) =>
+ passes.InlineAnnotation(ModuleName(module, CircuitName(circuit)), TransID(0))
+ case Array(circuit, module, inst) =>
+ passes.InlineAnnotation((ComponentName(inst,ModuleName(module,CircuitName(circuit)))), TransID(0))
+ case _ => throw new Exception(s"Bad inline instance/module name: $value")
+ }
+ run(args: Array[String],
+ Map( "high" -> new HighFirrtlCompiler(),
+ "low" -> new LowFirrtlCompiler(),
+ "verilog" -> new VerilogCompiler()),
+ Map("--inline" -> handleInlineOption _),
+ usage
+ )
+ }
+
+ /**
+ * Runs a Firrtl compiler.
+ *
+ * @param args list of commandline arguments
+ * @param compilers mapping a compiler name to a compiler
+ * @param customOptions mapping a custom option name to a function that returns an annotation
+ * @param usage describes the commandline API
+ */
+ def run(args: Array[String], compilers: Map[String,Compiler], customOptions: Map[String, String=>Annotation], usage: String) = {
+ /**
+ * Keys commandline values specified by user in OptionMap
+ */
sealed trait CompilerOption
case object InputFileName extends CompilerOption
case object OutputFileName extends CompilerOption
case object CompilerName extends CompilerOption
+ case object AnnotationOption extends CompilerOption
case object InfoModeOption extends CompilerOption
- val defaultOptions = Map[CompilerOption, String]()
-
- // Inline Annotation datastructure/function
- val inlineAnnotations = mutable.HashMap[Named,Annotation]()
- def handleInlineOption(value: String): Unit =
- value.split('.') match {
- case Array(module) =>
- inlineAnnotations(ModuleName(module)) = TagAnnotation
- case Array(module, inst) =>
- inlineAnnotations(ComponentName(inst,ModuleName(module))) = TagAnnotation
- case _ => throw new Exception(s"Bad inline instance/module name: $value")
- }
-
+ /**
+ * Maps compiler option to user-specified value
+ */
type OptionMap = Map[CompilerOption, String]
+
+ /**
+ * Populated by custom annotations returned from corresponding function
+ * held in customOptions
+ */
+ val annotations = mutable.ArrayBuffer[Annotation]()
def nextOption(map: OptionMap, list: List[String]): OptionMap = {
list match {
case Nil => map
- case "--inline" :: value :: tail =>
- handleInlineOption(value)
- nextOption(map, tail)
- case "-X" :: value :: tail =>
- nextOption(map + (CompilerName -> value), tail)
case "-i" :: value :: tail =>
- nextOption(map + (InputFileName -> value), tail)
+ nextOption(map + (InputFileName -> value), tail)
case "-o" :: value :: tail =>
- nextOption(map + (OutputFileName -> value), tail)
+ nextOption(map + (OutputFileName -> value), tail)
+ case "-X" :: value :: tail =>
+ nextOption(map + (CompilerName -> value), tail)
case "--info-mode" :: value :: tail =>
- nextOption(map + (InfoModeOption -> value), tail)
+ nextOption(map + (InfoModeOption -> value), tail)
+ case flag :: value :: tail if(customOptions.contains(flag)) =>
+ annotations += customOptions(flag)(value)
+ nextOption(map, tail)
case ("-h" | "--help") :: tail => { println(usage); sys.exit(0) }
case option :: tail =>
- throw new Exception("Unknown option " + option)
+ throw new Exception("Unknown option " + option)
}
}
- val options = nextOption(defaultOptions, arglist)
+ val arglist = args.toList
+ val options = nextOption(Map[CompilerOption, String](), arglist)
// Get input circuit/output filenames
val input = options.getOrElse(InputFileName, throw new Exception("No input file provided!" + usage))
@@ -117,18 +159,13 @@ Options:
case Some(other) => throw new Exception("Unknown info mode option: " + other)
}
- // Construct all Circuit Annotations
- val inlineCA =
- if (inlineAnnotations.isEmpty) Seq.empty
- else Seq(StickyCircuitAnnotation(passes.InlineCAKind, inlineAnnotations.toMap))
- val allAnnotations = inlineCA // other annotations will be added here
-
// Execute selected compiler - error if not recognized compiler
options.get(CompilerName) match {
- case Some("high") => compile(input, output, new HighFirrtlCompiler(), infoMode, allAnnotations)
- case Some("low") => compile(input, output, new LowFirrtlCompiler(), infoMode, allAnnotations)
- case Some("verilog") => compile(input, output, new VerilogCompiler(), infoMode, allAnnotations)
- case Some(other) => throw new Exception("Unknown compiler option: " + other)
+ case Some(name) =>
+ compilers.get(name) match {
+ case Some(compiler) => compile(input, output, compiler, infoMode, new AnnotationMap(annotations.toSeq))
+ case None => throw new Exception("Unknown compiler option: " + name)
+ }
case None => throw new Exception("No specified compiler option.")
}
}
diff --git a/src/main/scala/firrtl/LoweringAnnotations.scala b/src/main/scala/firrtl/LoweringAnnotations.scala
deleted file mode 100644
index ac09f67a..00000000
--- a/src/main/scala/firrtl/LoweringAnnotations.scala
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
-Copyright (c) 2014 - 2016 The Regents of the University of
-California (Regents). All Rights Reserved. Redistribution and use in
-source and binary forms, with or without modification, are permitted
-provided that the following conditions are met:
- * Redistributions of source code must retain the above
- copyright notice, this list of conditions and the following
- two paragraphs of disclaimer.
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following
- two paragraphs of disclaimer in the documentation and/or other materials
- provided with the distribution.
- * Neither the name of the Regents nor the names of its contributors
- may be used to endorse or promote products derived from this
- software without specific prior written permission.
-IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
-SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS,
-ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
-REGENTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF
-ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION
-TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
-MODIFICATIONS.
-*/
-
-package firrtl
-
-// ===========================================
-// Lowering Annotations
-// -------------------------------------------
-
-case object TagAnnotation extends Annotation {
- def serialize: String = this.toString
-}
-case class StringAnnotation (string: String) extends Annotation {
- def serialize: String = string
-}
-
-// Annotated names cannot be renamed, split, or removed
-case class BrittleCircuitAnnotation(kind: CircuitAnnotationKind, map: Map[Named,Annotation]) extends CircuitAnnotation {
- def check(renames: RenameMap): Unit = {
- map.keys.foreach { mn => {
- renames.map.get(mn) match {
- case None => {}
- case Some(rename) => rename.size match {
- case 1 if (rename.head.name == mn.name) => {} // Ok case
- case 0 => throw new AnnotationException(s"Cannot remove $mn.")
- case 1 => throw new AnnotationException(s"Cannot rename $mn into ${rename.head.name}.")
- case _ =>
- throw new AnnotationException(s"Cannot split ${mn.name}into " + rename.map(_.name).reduce(_ + " and " + _) + ".")
- }
- }
- }}
- }
- def update(renames: RenameMap): BrittleCircuitAnnotation = {
- check(renames)
- BrittleCircuitAnnotation(kind, map)
- }
-}
-
-// Annotation moves with renamed and split names. Removed annotated names do not trigger an error.
-case class StickyCircuitAnnotation(kind: CircuitAnnotationKind, map: Map[Named,Annotation]) extends CircuitAnnotation {
- def get(name: Named): Annotation = map(name)
- def update(renames: RenameMap): StickyCircuitAnnotation = {
- val mapx = renames.map.foldLeft(Map[Named, Annotation]()){
- case (newmap: Map[Named, Annotation],(name: Named, renames: Seq[Named])) => {
- if (map.contains(name)) {
- renames.map(rename => Map(rename -> map(name))).reduce(_ ++ _) ++ newmap
- } else newmap
- }
- }
- StickyCircuitAnnotation(kind, mapx)
- }
- def getModuleNames: Seq[ModuleName] = map.keys.flatMap{
- _ match {
- case x: ModuleName => Seq(x)
- case _ => Seq.empty
- }
- }.toSeq
- def getComponentNames: Seq[ComponentName] = map.keys.flatMap{
- _ match {
- case x: ComponentName => Seq(x)
- case _ => Seq.empty
- }
- }.toSeq
-}
diff --git a/src/main/scala/firrtl/LoweringCompilers.scala b/src/main/scala/firrtl/LoweringCompilers.scala
index 036156dc..8beaf7f9 100644
--- a/src/main/scala/firrtl/LoweringCompilers.scala
+++ b/src/main/scala/firrtl/LoweringCompilers.scala
@@ -31,6 +31,7 @@ import com.typesafe.scalalogging.LazyLogging
import java.io.Writer
import firrtl.passes.Pass
import firrtl.ir.Circuit
+import Annotations._
// ===========================================
// Utility Traits
@@ -65,7 +66,7 @@ class Chisel3ToHighFirrtl () extends Transform with SimpleRun {
passes.CInferTypes,
passes.CInferMDir,
passes.RemoveCHIRRTL)
- def execute (circuit: Circuit, annotations: Seq[CircuitAnnotation]): TransformResult =
+ def execute (circuit: Circuit, annotationMap: AnnotationMap): TransformResult =
run(circuit, passSeq)
}
@@ -73,7 +74,7 @@ class Chisel3ToHighFirrtl () extends Transform with SimpleRun {
// to a working representation (WIR.scala)
class IRToWorkingIR () extends Transform with SimpleRun {
val passSeq = Seq(passes.ToWorkingIR)
- def execute (circuit: Circuit, annotations: Seq[CircuitAnnotation]): TransformResult =
+ def execute (circuit: Circuit, annotationMap: AnnotationMap): TransformResult =
run(circuit, passSeq)
}
@@ -92,7 +93,7 @@ class ResolveAndCheck () extends Transform with SimpleRun {
passes.CheckGenders,
passes.InferWidths,
passes.CheckWidths)
- def execute (circuit: Circuit, annotations: Seq[CircuitAnnotation]): TransformResult =
+ def execute (circuit: Circuit, annotationMap: AnnotationMap): TransformResult =
run(circuit, passSeq)
}
@@ -107,12 +108,13 @@ class HighFirrtlToMiddleFirrtl () extends Transform with SimpleRun {
passes.RemoveAccesses,
passes.ExpandWhens,
passes.CheckInitialization,
+ passes.ConstProp,
passes.ResolveKinds,
passes.InferTypes,
passes.ResolveGenders)
//passes.InferWidths,
//passes.CheckWidths)
- def execute (circuit: Circuit, annotations: Seq[CircuitAnnotation]): TransformResult =
+ def execute (circuit: Circuit, annotationMap: AnnotationMap): TransformResult =
run(circuit, passSeq)
}
@@ -128,7 +130,7 @@ class MiddleFirrtlToLowFirrtl () extends Transform with SimpleRun {
passes.InferTypes,
passes.ResolveGenders,
passes.InferWidths)
- def execute (circuit: Circuit, annotations: Seq[CircuitAnnotation]): TransformResult =
+ def execute (circuit: Circuit, annotationMap: AnnotationMap): TransformResult =
run(circuit, passSeq)
}
@@ -149,7 +151,7 @@ class EmitVerilogFromLowFirrtl (val writer: Writer) extends Transform with Simpl
passes.CommonSubexpressionElimination,
passes.DeadCodeElimination,
passes.VerilogRename)
- def execute (circuit: Circuit, annotations: Seq[CircuitAnnotation]): TransformResult = {
+ def execute (circuit: Circuit, annotationMap: AnnotationMap): TransformResult = {
val result = run(circuit, passSeq)
(new VerilogEmitter).run(result.circuit, writer)
result
@@ -159,7 +161,7 @@ class EmitVerilogFromLowFirrtl (val writer: Writer) extends Transform with Simpl
// Emits Firrtl.
// Operates on WIR/IR nodes.
class EmitFirrtl (val writer: Writer) extends Transform {
- def execute (circuit: Circuit, annotations: Seq[CircuitAnnotation]): TransformResult = {
+ def execute (circuit: Circuit, annotationMap: AnnotationMap): TransformResult = {
FIRRTLEmitter.run(circuit, writer)
TransformResult(circuit)
}
@@ -184,7 +186,7 @@ class LowFirrtlCompiler extends Compiler {
def transforms(writer: Writer): Seq[Transform] = Seq(
new Chisel3ToHighFirrtl(),
new IRToWorkingIR(),
- passes.InlineInstances,
+ new passes.InlineInstances(TransID(0)),
new ResolveAndCheck(),
new HighFirrtlToMiddleFirrtl(),
new MiddleFirrtlToLowFirrtl(),
@@ -200,7 +202,7 @@ class VerilogCompiler extends Compiler {
new ResolveAndCheck(),
new HighFirrtlToMiddleFirrtl(),
new MiddleFirrtlToLowFirrtl(),
- passes.InlineInstances,
+ new passes.InlineInstances(TransID(0)),
new EmitVerilogFromLowFirrtl(writer)
)
}
diff --git a/src/main/scala/firrtl/passes/Inline.scala b/src/main/scala/firrtl/passes/Inline.scala
index 3801f8cb..7793c85c 100644
--- a/src/main/scala/firrtl/passes/Inline.scala
+++ b/src/main/scala/firrtl/passes/Inline.scala
@@ -7,43 +7,49 @@ import scala.collection.mutable
import firrtl.Mappers.{ExpMap,StmtMap}
import firrtl.Utils.WithAs
import firrtl.ir._
+import firrtl.passes.{PassException,PassExceptions}
+import Annotations.{Loose, Unstable, Annotation, TransID, Named, ModuleName, ComponentName, CircuitName, AnnotationMap}
// Tags an annotation to be consumed by this pass
-case object InlineCAKind extends CircuitAnnotationKind
+case class InlineAnnotation(target: Named, tID: TransID) extends Annotation with Loose with Unstable {
+ def duplicate(n: Named) = this.copy(target=n)
+}
// Only use on legal Firrtl. Specifically, the restriction of
// instance loops must have been checked, or else this pass can
// infinitely recurse
-object InlineInstances extends Transform {
+class InlineInstances (transID: TransID) extends Transform {
val inlineDelim = "$"
def name = "Inline Instances"
- def execute(circuit: Circuit, annotations: Seq[CircuitAnnotation]): TransformResult = {
- annotations.count(_.kind == InlineCAKind) match {
- case 0 => TransformResult(circuit, None, None)
- case 1 => {
- // This could potentially be cleaned up, but the best solution is unclear at the moment.
- val myAnnotation = annotations.find(_.kind == InlineCAKind).get match {
- case x: StickyCircuitAnnotation => x
- case _ => throw new PassException("Circuit annotation must be StickyCircuitAnnotation")
- }
- check(circuit, myAnnotation)
- run(circuit, myAnnotation.getModuleNames, myAnnotation.getComponentNames)
- }
- // Default behavior is to error if more than one annotation for inlining
- // This could potentially change
- case _ => throw new PassException("Found more than one circuit annotation of InlineCAKind!")
- }
+ def execute(circuit: Circuit, annotationMap: AnnotationMap): TransformResult = {
+ annotationMap.get(transID) match {
+ case None => TransformResult(circuit, None, None)
+ case Some(map) => {
+ val moduleNames = mutable.HashSet[ModuleName]()
+ val instanceNames = mutable.HashSet[ComponentName]()
+ map.values.foreach {x: Annotation => x match {
+ case InlineAnnotation(ModuleName(mod, cir), _) => moduleNames += ModuleName(mod, cir)
+ case InlineAnnotation(ComponentName(com, mod), _) => instanceNames += ComponentName(com, mod)
+ case _ => throw new PassException("Annotation must be InlineAnnotation")
+ }}
+ check(circuit, moduleNames.toSet, instanceNames.toSet)
+ run(circuit, moduleNames.toSet, instanceNames.toSet)
+ }
+
+ // Default behavior is to error if more than one annotation for inlining
+ // This could potentially change
+ case _ => throw new PassException("Found more than one circuit annotation of InlineCAKind!")
+ }
}
// Checks the following properties:
// 1) All annotated modules exist
// 2) All annotated modules are InModules (can be inlined)
// 3) All annotated instances exist, and their modules can be inline
- def check(c: Circuit, ca: StickyCircuitAnnotation): Unit = {
+ def check(c: Circuit, moduleNames: Set[ModuleName], instanceNames: Set[ComponentName]): Unit = {
val errors = mutable.ArrayBuffer[PassException]()
val moduleMap = (for(m <- c.modules) yield m.name -> m).toMap
- val annModuleNames = ca.getModuleNames.map(_.name) ++ ca.getComponentNames.map(_.module.name)
def checkExists(name: String): Unit =
if (!moduleMap.contains(name))
errors += new PassException(s"Annotated module does not exist: ${name}")
@@ -67,15 +73,16 @@ object InlineInstances extends Transform {
onStmt(cn.name)(moduleMap(cn.module.name).asInstanceOf[Module].body)
if (!containsCN) errors += new PassException(s"Annotated instance does not exist: ${cn.module.name}.${cn.name}")
}
- annModuleNames.foreach{n => checkExists(n)}
+
+ moduleNames.foreach{mn => checkExists(mn.name)}
if (!errors.isEmpty) throw new PassExceptions(errors)
- annModuleNames.foreach{n => checkExternal(n)}
+ moduleNames.foreach{mn => checkExternal(mn.name)}
if (!errors.isEmpty) throw new PassExceptions(errors)
- ca.getComponentNames.foreach{cn => checkInstance(cn)}
+ instanceNames.foreach{cn => checkInstance(cn)}
if (!errors.isEmpty) throw new PassExceptions(errors)
}
- def run(c: Circuit, modsToInline: Seq[ModuleName], instsToInline: Seq[ComponentName]): TransformResult = {
+ def run(c: Circuit, modsToInline: Set[ModuleName], instsToInline: Set[ComponentName]): TransformResult = {
// ---- Rename functions/data ----
val renameMap = mutable.HashMap[Named,Seq[Named]]()
// Updates renameMap with new names
@@ -83,12 +90,14 @@ object InlineInstances extends Transform {
val existing = renameMap.getOrElse(name, Seq[Named]())
if (!existing.contains(rename)) renameMap(name) = existing.:+(rename)
}
+ def set(name: Named, renames: Seq[Named]) = renameMap(name) = renames
// ---- Pass functions/data ----
// Contains all unaltered modules
val originalModules = mutable.HashMap[String,DefModule]()
// Contains modules whose direct/indirect children modules have been inlined, and whose tagged instances have been inlined.
val inlinedModules = mutable.HashMap[String,DefModule]()
+ val cname = CircuitName(c.main)
// Recursive.
def onModule(m: DefModule): DefModule = {
@@ -99,7 +108,7 @@ object InlineInstances extends Transform {
// Relies on instance declaration before any instance references
if (inlinedInstances.contains(ref)) {
val newName = ref + inlineDelim + field
- update(ComponentName(ref, ModuleName(m.name)), ComponentName(newName, ModuleName(m.name)))
+ set(ComponentName(ref, ModuleName(m.name, cname)), Seq.empty)
WRef(newName, tpe, WireKind(), gen)
}
else e
@@ -111,7 +120,7 @@ object InlineInstances extends Transform {
case WDefInstance(info, instName, moduleName, instTpe) => {
def rename(name:String): String = {
val newName = instName + inlineDelim + name
- update(ComponentName(name, ModuleName(moduleName)), ComponentName(newName, ModuleName(m.name)))
+ update(ComponentName(name, ModuleName(moduleName, cname)), ComponentName(newName, ModuleName(m.name, cname)))
newName
}
// Rewrites references in inlined statements from ref to inst$ref
@@ -125,8 +134,8 @@ object InlineInstances extends Transform {
s map rename map renameStmt map renameExp
}
val shouldInline =
- modsToInline.contains(ModuleName(moduleName)) ||
- instsToInline.contains(ComponentName(instName, ModuleName(m.name)))
+ modsToInline.contains(ModuleName(moduleName, cname)) ||
+ instsToInline.contains(ComponentName(instName, ModuleName(m.name, cname)))
// Used memoized instance if available
val instModule =
if (inlinedModules.contains(name)) inlinedModules(name)
@@ -167,6 +176,6 @@ object InlineInstances extends Transform {
val top = c.modules.find(m => m.name == c.main).get
onModule(top)
val modulesx = c.modules.map(m => inlinedModules(m.name))
- TransformResult(Circuit(c.info, modulesx, c.main), Some(BasicRenameMap(renameMap.toMap)), None)
+ TransformResult(Circuit(c.info, modulesx, c.main), Some(RenameMap(renameMap.toMap)), None)
}
}