aboutsummaryrefslogtreecommitdiff
path: root/src/main/scala/firrtl/passes/memlib
diff options
context:
space:
mode:
authorJack Koenig2018-02-27 18:07:11 -0800
committerGitHub2018-02-27 18:07:11 -0800
commitc7eb1570dfb1c7701ea32d1209982a053f3cec1d (patch)
tree3f509b202d82841c5dad5588d1f953a25d389b44 /src/main/scala/firrtl/passes/memlib
parentb90fc784a1819c1d7905910130a7da022214bc22 (diff)
Refactor Annotations (#721)
- Old Annotation renamed to deprecated LegacyAnnotation - Annotation is now a trait that can be extended - New JsonProtocol for Annotation [de]serialization - Replace AnnotationMap with AnnotationSeq - Deprecate Transform.getMyAnnotations - Update Transforms - Turn on deprecation warnings - Remove deprecated Driver.compile - Make AnnotationTests abstract with Legacy and Json subclasses - Add functionality to convert LegacyAnnotations of built-in annos This will give a noisy warning and is more of a best effort than a robust solution. Fixes #475 Closes #609
Diffstat (limited to 'src/main/scala/firrtl/passes/memlib')
-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
5 files changed, 38 insertions, 76 deletions
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))
}