aboutsummaryrefslogtreecommitdiff
path: root/src/main/scala/firrtl/passes
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/scala/firrtl/passes')
-rw-r--r--src/main/scala/firrtl/passes/Inline.scala26
-rw-r--r--src/main/scala/firrtl/passes/clocklist/ClockList.scala2
-rw-r--r--src/main/scala/firrtl/passes/clocklist/ClockListTransform.scala37
-rw-r--r--src/main/scala/firrtl/passes/memlib/DecorateMems.scala4
-rw-r--r--src/main/scala/firrtl/passes/memlib/InferReadWrite.scala19
-rw-r--r--src/main/scala/firrtl/passes/memlib/ReplaceMemMacros.scala35
-rw-r--r--src/main/scala/firrtl/passes/memlib/ReplaceMemTransform.scala38
-rw-r--r--src/main/scala/firrtl/passes/memlib/ResolveMemoryReference.scala18
-rw-r--r--src/main/scala/firrtl/passes/wiring/WiringTransform.scala78
9 files changed, 100 insertions, 157 deletions
diff --git a/src/main/scala/firrtl/passes/Inline.scala b/src/main/scala/firrtl/passes/Inline.scala
index 2e15f09c..0ba0c5d9 100644
--- a/src/main/scala/firrtl/passes/Inline.scala
+++ b/src/main/scala/firrtl/passes/Inline.scala
@@ -10,14 +10,9 @@ import firrtl.annotations._
// Datastructures
import scala.collection.mutable
-// Tags an annotation to be consumed by this pass
-object InlineAnnotation {
- def apply(target: Named): Annotation = Annotation(target, classOf[InlineInstances], "")
-
- def unapply(a: Annotation): Option[Named] = a match {
- case Annotation(named, t, _) if t == classOf[InlineInstances] => Some(named)
- case _ => None
- }
+/** Indicates that something should be inlined */
+case class InlineAnnotation(target: Named) extends SingleTargetAnnotation[Named] {
+ def duplicate(n: Named) = InlineAnnotation(n)
}
// Only use on legal Firrtl. Specifically, the restriction of
@@ -37,18 +32,17 @@ class InlineInstances extends Transform {
}.toSet, instNames)
case InlineAnnotation(ModuleName(mod, cir)) => (modNames + ModuleName(mod, cir), instNames)
case InlineAnnotation(ComponentName(com, mod)) => (modNames, instNames + ComponentName(com, mod))
- case _ => throw new PassException("Annotation must be InlineAnnotation")
+ case _ => (modNames, instNames)
}
}
def execute(state: CircuitState): CircuitState = {
// TODO Add error check for more than one annotation for inlining
- // TODO Propagate other annotations
- getMyAnnotations(state) match {
- case Nil => CircuitState(state.circuit, state.form)
- case myAnnotations =>
- val (modNames, instNames) = collectAnns(state.circuit, myAnnotations)
- run(state.circuit, modNames, instNames, state.annotations)
+ val (modNames, instNames) = collectAnns(state.circuit, state.annotations)
+ if (modNames.nonEmpty || instNames.nonEmpty) {
+ run(state.circuit, modNames, instNames, state.annotations)
+ } else {
+ state
}
}
@@ -92,7 +86,7 @@ class InlineInstances extends Transform {
}
- def run(c: Circuit, modsToInline: Set[ModuleName], instsToInline: Set[ComponentName], annos: Option[AnnotationMap]): CircuitState = {
+ def run(c: Circuit, modsToInline: Set[ModuleName], instsToInline: Set[ComponentName], annos: AnnotationSeq): CircuitState = {
def getInstancesOf(c: Circuit, modules: Set[String]): Set[String] =
c.modules.foldLeft(Set[String]()) { (set, d) =>
d match {
diff --git a/src/main/scala/firrtl/passes/clocklist/ClockList.scala b/src/main/scala/firrtl/passes/clocklist/ClockList.scala
index be4d99fc..fcc3cd5e 100644
--- a/src/main/scala/firrtl/passes/clocklist/ClockList.scala
+++ b/src/main/scala/firrtl/passes/clocklist/ClockList.scala
@@ -43,7 +43,7 @@ class ClockList(top: String, writer: Writer) extends Pass {
// Inline the clock-only circuit up to the specified top module
val modulesToInline = (c.modules.collect { case Module(_, n, _, _) if n != top => ModuleName(n, CircuitName(c.main)) }).toSet
val inlineTransform = new InlineInstances
- val inlinedCircuit = inlineTransform.run(onlyClockCircuit, modulesToInline, Set(), None).circuit
+ val inlinedCircuit = inlineTransform.run(onlyClockCircuit, modulesToInline, Set(), Seq()).circuit
val topModule = inlinedCircuit.modules.find(_.name == top).getOrElse(throwInternalError(Some("no top module")))
// Build a hashmap of connections to use for getOrigins
diff --git a/src/main/scala/firrtl/passes/clocklist/ClockListTransform.scala b/src/main/scala/firrtl/passes/clocklist/ClockListTransform.scala
index 24f25525..6c7b2e18 100644
--- a/src/main/scala/firrtl/passes/clocklist/ClockListTransform.scala
+++ b/src/main/scala/firrtl/passes/clocklist/ClockListTransform.scala
@@ -15,8 +15,13 @@ import memlib.AnalysisUtils._
import memlib._
import Mappers._
+case class ClockListAnnotation(target: ModuleName, outputConfig: String) extends
+ SingleTargetAnnotation[ModuleName] {
+ def duplicate(n: ModuleName) = ClockListAnnotation(n, outputConfig)
+}
+
object ClockListAnnotation {
- def apply(t: String): Annotation = {
+ def parse(t: String): ClockListAnnotation = {
val usage = """
[Optional] ClockList
List which signal drives each clock of every descendent of specified module
@@ -45,16 +50,7 @@ Usage:
case None =>
}
val target = ModuleName(passModule, CircuitName(passCircuit))
- Annotation(target, classOf[ClockListTransform], outputConfig)
- }
-
- def apply(target: ModuleName, outputConfig: String): Annotation =
- Annotation(target, classOf[ClockListTransform], outputConfig)
-
- def unapply(a: Annotation): Option[(ModuleName, String)] = a match {
- case Annotation(ModuleName(m, c), t, outputConfig) if t == classOf[ClockListTransform] =>
- Some((ModuleName(m, c), outputConfig))
- case _ => None
+ ClockListAnnotation(target, outputConfig)
}
}
@@ -63,13 +59,16 @@ class ClockListTransform extends Transform {
def outputForm = LowForm
def passSeq(top: String, writer: Writer): Seq[Pass] =
Seq(new ClockList(top, writer))
- def execute(state: CircuitState): CircuitState = getMyAnnotations(state) match {
- case Seq(ClockListAnnotation(ModuleName(top, CircuitName(state.circuit.main)), out)) =>
- val outputFile = new PrintWriter(out)
- val newC = (new ClockList(top, outputFile)).run(state.circuit)
- outputFile.close()
- CircuitState(newC, state.form, state.annotations)
- case Nil => state
- case seq => error(s"Found illegal clock list annotation(s): $seq")
+ def execute(state: CircuitState): CircuitState = {
+ val annos = state.annotations.collect { case a: ClockListAnnotation => a }
+ annos match {
+ case Seq(ClockListAnnotation(ModuleName(top, CircuitName(state.circuit.main)), out)) =>
+ val outputFile = new PrintWriter(out)
+ val newC = (new ClockList(top, outputFile)).run(state.circuit)
+ outputFile.close()
+ CircuitState(newC, state.form, state.annotations)
+ case Nil => state
+ case seq => error(s"Found illegal clock list annotation(s): $seq")
+ }
}
}
diff --git a/src/main/scala/firrtl/passes/memlib/DecorateMems.scala b/src/main/scala/firrtl/passes/memlib/DecorateMems.scala
index ad3616ad..c5302a38 100644
--- a/src/main/scala/firrtl/passes/memlib/DecorateMems.scala
+++ b/src/main/scala/firrtl/passes/memlib/DecorateMems.scala
@@ -16,11 +16,11 @@ class CreateMemoryAnnotations(reader: Option[YamlFileReader]) extends Transform
import CustomYAMLProtocol._
val configs = r.parse[Config]
val cN = CircuitName(state.circuit.main)
- val oldAnnos = state.annotations.getOrElse(AnnotationMap(Seq.empty)).annotations
+ val oldAnnos = state.annotations
val (as, pins) = configs.foldLeft((oldAnnos, Seq.empty[String])) { case ((annos, pins), config) =>
val source = SourceAnnotation(ComponentName(config.source.name, ModuleName(config.source.module, cN)), config.pin.name)
(annos, pins :+ config.pin.name)
}
- state.copy(annotations = Some(AnnotationMap(as :+ PinAnnotation(cN, pins.toSeq))))
+ state.copy(annotations = PinAnnotation(pins.toSeq) +: as)
}
}
diff --git a/src/main/scala/firrtl/passes/memlib/InferReadWrite.scala b/src/main/scala/firrtl/passes/memlib/InferReadWrite.scala
index 73fec1ee..661d6df4 100644
--- a/src/main/scala/firrtl/passes/memlib/InferReadWrite.scala
+++ b/src/main/scala/firrtl/passes/memlib/InferReadWrite.scala
@@ -13,15 +13,7 @@ import firrtl.passes.memlib.AnalysisUtils.{Connects, getConnects, getOrigin}
import WrappedExpression.weq
import annotations._
-object InferReadWriteAnnotation {
- def apply(t: String) = Annotation(CircuitName(t), classOf[InferReadWrite], "")
- def apply(target: CircuitName) = Annotation(target, classOf[InferReadWrite], "")
- def unapply(a: Annotation): Option[(CircuitName)] = a match {
- case Annotation(CircuitName(t), transform, "") if transform == classOf[InferReadWrite] =>
- Some(CircuitName(t))
- case _ => None
- }
-}
+case object InferReadWriteAnnotation extends NoTargetAnnotation
// This pass examine the enable signals of the read & write ports of memories
// whose readLatency is greater than 1 (usually SeqMem in Chisel).
@@ -159,10 +151,13 @@ class InferReadWrite extends Transform with SeqTransformBased {
ResolveKinds,
ResolveGenders
)
- def execute(state: CircuitState): CircuitState = getMyAnnotations(state) match {
- case Nil => state
- case Seq(InferReadWriteAnnotation(CircuitName(state.circuit.main))) =>
+ def execute(state: CircuitState): CircuitState = {
+ val runTransform = state.annotations.contains(InferReadWriteAnnotation)
+ if (runTransform) {
val ret = runTransforms(state)
CircuitState(ret.circuit, outputForm, ret.annotations, ret.renames)
+ } else {
+ state
+ }
}
}
diff --git a/src/main/scala/firrtl/passes/memlib/ReplaceMemMacros.scala b/src/main/scala/firrtl/passes/memlib/ReplaceMemMacros.scala
index bf0612ac..5ac9e63e 100644
--- a/src/main/scala/firrtl/passes/memlib/ReplaceMemMacros.scala
+++ b/src/main/scala/firrtl/passes/memlib/ReplaceMemMacros.scala
@@ -14,19 +14,8 @@ import firrtl.annotations._
import wiring._
-/** Annotates the name of the pin to add for WiringTransform
- */
-object PinAnnotation {
- def apply(target: CircuitName, pins: Seq[String]): Annotation = {
- Annotation(target, classOf[ReplaceMemMacros], s"pins:${pins.mkString(" ")}")
- }
- private val matcher = "pins:(.*)".r
- def unapply(a: Annotation): Option[(CircuitName, Seq[String])] = a match {
- case Annotation(CircuitName(c), _, matcher(rest)) =>
- Some((CircuitName(c), rest.split(" ")))
- case _ => None
- }
-}
+/** Annotates the name of the pins to add for WiringTransform */
+case class PinAnnotation(pins: Seq[String]) extends NoTargetAnnotation
/** Replace DefAnnotatedMemory with memory blackbox + wrapper + conf file.
* This will not generate wmask ports if not needed.
@@ -221,19 +210,17 @@ class ReplaceMemMacros(writer: ConfWriter) extends Transform {
val modules = c.modules map updateMemMods(namespace, nameMap, memMods)
// print conf
writer.serialize()
- val pins = getMyAnnotations(state) match {
- case Nil => Nil
- case Seq(PinAnnotation(CircuitName(c), pins)) => pins
+ val pannos = state.annotations.collect { case a: PinAnnotation => a }
+ val pins = pannos match {
+ case Seq() => Nil
+ case Seq(PinAnnotation(pins)) => pins
case _ => throwInternalError(Some(s"execute: getMyAnnotations - ${getMyAnnotations(state)}"))
}
- val annos = (pins.foldLeft(Seq[Annotation]()) { (seq, pin) =>
- seq ++ memMods.collect {
- case m: ExtModule => SinkAnnotation(ModuleName(m.name, CircuitName(c.main)), pin)
+ val annos = pins.foldLeft(Seq[Annotation]()) { (seq, pin) =>
+ seq ++ memMods.collect {
+ case m: ExtModule => SinkAnnotation(ModuleName(m.name, CircuitName(c.main)), pin)
}
- }) ++ (state.annotations match {
- case None => Seq.empty
- case Some(a) => a.annotations
- })
- CircuitState(c.copy(modules = modules ++ memMods), inputForm, Some(AnnotationMap(annos)))
+ } ++ state.annotations
+ CircuitState(c.copy(modules = modules ++ memMods), inputForm, annos)
}
}
diff --git a/src/main/scala/firrtl/passes/memlib/ReplaceMemTransform.scala b/src/main/scala/firrtl/passes/memlib/ReplaceMemTransform.scala
index 8cbf9da7..311813db 100644
--- a/src/main/scala/firrtl/passes/memlib/ReplaceMemTransform.scala
+++ b/src/main/scala/firrtl/passes/memlib/ReplaceMemTransform.scala
@@ -64,13 +64,15 @@ class ConfWriter(filename: String) {
}
}
+case class ReplSeqMemAnnotation(inputFileName: String, outputConfig: String) extends NoTargetAnnotation
+
object ReplSeqMemAnnotation {
- def apply(t: String): Annotation = {
+ def parse(t: String): ReplSeqMemAnnotation = {
val usage = """
[Optional] ReplSeqMem
Pass to replace sequential memories with blackboxes + configuration file
-Usage:
+Usage:
--replSeqMem -c:<circuit>:-i:<filename>:-o:<filename>
*** Note: sub-arguments to --replSeqMem should be delimited by : and not white space!
@@ -80,30 +82,15 @@ Required Arguments:
Optional Arguments:
-i<filename> Specify the input configuration file (for additional optimizations)
-"""
+"""
val passOptions = PassConfigUtil.getPassOptions(t, usage)
val outputConfig = passOptions.getOrElse(
- OutputConfigFileName,
+ OutputConfigFileName,
error("No output config file provided for ReplSeqMem!" + usage)
)
val inputFileName = PassConfigUtil.getPassOptions(t).getOrElse(InputConfigFileName, "")
- val passCircuit = passOptions.getOrElse(
- PassCircuitName,
- error("No circuit name specified for ReplSeqMem!" + usage)
- )
- val target = CircuitName(passCircuit)
- Annotation(target, classOf[ReplSeqMem], s"$inputFileName $outputConfig")
- }
-
- def apply(target: CircuitName, inputFileName: String, outputConfig: String): Annotation =
- Annotation(target, classOf[ReplSeqMem], s"$inputFileName $outputConfig")
-
- private val matcher = "([^ ]*) ([^ ]+)".r
- def unapply(a: Annotation): Option[(CircuitName, String, String)] = a match {
- case Annotation(CircuitName(c), t, matcher(inputFileName, outputConfig)) if t == classOf[ReplSeqMem] =>
- Some((CircuitName(c), inputFileName, outputConfig))
- case _ => None
+ ReplSeqMemAnnotation(inputFileName, outputConfig)
}
}
@@ -135,12 +122,13 @@ class ReplSeqMem extends Transform {
new SimpleMidTransform(ResolveKinds),
new SimpleMidTransform(ResolveGenders))
- def execute(state: CircuitState): CircuitState = getMyAnnotations(state) match {
- case Nil => state // Do nothing if there are no annotations
- case p => (p.collectFirst { case a if (a.target == CircuitName(state.circuit.main)) => a }) match {
- case Some(ReplSeqMemAnnotation(target, inputFileName, outputConfig)) =>
+ def execute(state: CircuitState): CircuitState = {
+ val annos = state.annotations.collect { case a: ReplSeqMemAnnotation => a }
+ annos match {
+ case Nil => state // Do nothing if there are no annotations
+ case Seq(ReplSeqMemAnnotation(inputFileName, outputConfig)) =>
val inConfigFile = {
- if (inputFileName.isEmpty) None
+ if (inputFileName.isEmpty) None
else if (new File(inputFileName).exists) Some(new YamlFileReader(inputFileName))
else error("Input configuration file does not exist!")
}
diff --git a/src/main/scala/firrtl/passes/memlib/ResolveMemoryReference.scala b/src/main/scala/firrtl/passes/memlib/ResolveMemoryReference.scala
index e132e369..d195ea55 100644
--- a/src/main/scala/firrtl/passes/memlib/ResolveMemoryReference.scala
+++ b/src/main/scala/firrtl/passes/memlib/ResolveMemoryReference.scala
@@ -8,15 +8,9 @@ import AnalysisUtils.eqMems
import firrtl.Mappers._
import firrtl.annotations._
-/** A component, e.g. register etc. Must be declared only once under the TopAnnotation
- */
-object NoDedupMemAnnotation {
- def apply(target: ComponentName): Annotation = Annotation(target, classOf[ResolveMemoryReference], s"nodedupmem!")
-
- def unapply(a: Annotation): Option[ComponentName] = a match {
- case Annotation(ComponentName(n, mn), _, "nodedupmem!") => Some(ComponentName(n, mn))
- case _ => None
- }
+/** A component, e.g. register etc. Must be declared only once under the TopAnnotation */
+case class NoDedupMemAnnotation(target: ComponentName) extends SingleTargetAnnotation[ComponentName] {
+ def duplicate(n: ComponentName) = NoDedupMemAnnotation(n)
}
/** Resolves annotation ref to memories that exactly match (except name) another memory
@@ -46,10 +40,8 @@ class ResolveMemoryReference extends Transform {
c copy (modules = c.modules map (m => m map updateMemStmts(m.name, uniqueMems, noDeDupeMems)))
}
def execute(state: CircuitState): CircuitState = {
- val noDedups = getMyAnnotations(state) match {
- case Nil => Seq.empty
- case annos =>
- annos.collect { case NoDedupMemAnnotation(ComponentName(cn, _)) => cn }
+ val noDedups = state.annotations.collect {
+ case NoDedupMemAnnotation(ComponentName(cn, _)) => cn
}
state.copy(circuit=run(state.circuit, noDedups))
}
diff --git a/src/main/scala/firrtl/passes/wiring/WiringTransform.scala b/src/main/scala/firrtl/passes/wiring/WiringTransform.scala
index 01e6f83a..9a82f8a0 100644
--- a/src/main/scala/firrtl/passes/wiring/WiringTransform.scala
+++ b/src/main/scala/firrtl/passes/wiring/WiringTransform.scala
@@ -14,32 +14,16 @@ import WiringUtils._
/** A class for all exceptions originating from firrtl.passes.wiring */
case class WiringException(msg: String) extends PassException(msg)
-/** An extractor of annotated source components */
-object SourceAnnotation {
- def apply(target: ComponentName, pin: String): Annotation =
- Annotation(target, classOf[WiringTransform], s"source $pin")
-
- private val matcher = "source (.+)".r
- def unapply(a: Annotation): Option[(ComponentName, String)] = a match {
- case Annotation(ComponentName(n, m), _, matcher(pin)) =>
- Some((ComponentName(n, m), pin))
- case _ => None
- }
+/** A component, e.g. register etc. Must be declared only once under the TopAnnotation */
+case class SourceAnnotation(target: ComponentName, pin: String) extends
+ SingleTargetAnnotation[ComponentName] {
+ def duplicate(n: ComponentName) = this.copy(target = n)
}
-/** An extractor of annotation sink components or modules */
-object SinkAnnotation {
- def apply(target: Named, pin: String): Annotation =
- Annotation(target, classOf[WiringTransform], s"sink $pin")
-
- private val matcher = "sink (.+)".r
- def unapply(a: Annotation): Option[(Named, String)] = a match {
- case Annotation(ModuleName(n, c), _, matcher(pin)) =>
- Some((ModuleName(n, c), pin))
- case Annotation(ComponentName(n, m), _, matcher(pin)) =>
- Some((ComponentName(n, m), pin))
- case _ => None
- }
+/** A module, e.g. ExtModule etc., that should add the input pin */
+case class SinkAnnotation(target: Named, pin: String) extends
+ SingleTargetAnnotation[Named] {
+ def duplicate(n: Named) = this.copy(target = n)
}
/** Wires a Module's Source Component to one or more Sink
@@ -64,26 +48,30 @@ class WiringTransform extends Transform {
new Wiring(w),
ToWorkingIR
)
-
- def execute(state: CircuitState): CircuitState = getMyAnnotations(state) match {
- case Nil => state
- case p =>
- val sinks = mutable.HashMap[String, Seq[Named]]()
- val sources = mutable.HashMap[String, ComponentName]()
- p.foreach {
- case SinkAnnotation(m, pin) =>
- sinks(pin) = sinks.getOrElse(pin, Seq.empty) :+ m
- case SourceAnnotation(c, pin) =>
- sources(pin) = c
- }
- (sources.size, sinks.size) match {
- case (0, p) => state
- case (s, p) if (p > 0) =>
- val wis = sources.foldLeft(Seq[WiringInfo]()) { case (seq, (pin, source)) =>
- seq :+ WiringInfo(source, sinks(pin), pin)
- }
- transforms(wis).foldLeft(state) { (in, xform) => xform.runTransform(in) }
- case _ => error("Wrong number of sources or sinks!")
- }
+ def execute(state: CircuitState): CircuitState = {
+ val annos = state.annotations.collect {
+ case a @ (_: SinkAnnotation | _: SourceAnnotation) => a
+ }
+ annos match {
+ case Seq() => state
+ case p =>
+ val sinks = mutable.HashMap[String, Seq[Named]]()
+ val sources = mutable.HashMap[String, ComponentName]()
+ p.foreach {
+ case SinkAnnotation(m, pin) =>
+ sinks(pin) = sinks.getOrElse(pin, Seq.empty) :+ m
+ case SourceAnnotation(c, pin) =>
+ sources(pin) = c
+ }
+ (sources.size, sinks.size) match {
+ case (0, p) => state
+ case (s, p) if (p > 0) =>
+ val wis = sources.foldLeft(Seq[WiringInfo]()) { case (seq, (pin, source)) =>
+ seq :+ WiringInfo(source, sinks(pin), pin)
+ }
+ transforms(wis).foldLeft(state) { (in, xform) => xform.runTransform(in) }
+ case _ => error("Wrong number of sources or sinks!")
+ }
+ }
}
}