aboutsummaryrefslogtreecommitdiff
path: root/src/main/scala/firrtl/passes/memlib
diff options
context:
space:
mode:
authorjackkoenig2016-10-20 00:19:01 -0700
committerJack Koenig2016-11-04 13:29:09 -0700
commit8fa9429a6e916ab2a789f5d81fa803b022805b52 (patch)
treefac2efcbd0a68bfb1916f09afc7f003c7a3d6528 /src/main/scala/firrtl/passes/memlib
parent62133264a788f46b319ebab9c31424b7e0536101 (diff)
Refactor Compilers and Transforms
* Transform Ids now handled by Class[_ <: Transform] instead of magic numbers * Transforms define inputForm and outputForm * Custom transforms can be inserted at runtime into compiler or the Driver * Current "built-in" custom transforms handled via above mechanism * Verilog-specific passes moved to the Verilog emitter
Diffstat (limited to 'src/main/scala/firrtl/passes/memlib')
-rw-r--r--src/main/scala/firrtl/passes/memlib/DecorateMems.scala22
-rw-r--r--src/main/scala/firrtl/passes/memlib/InferReadWrite.scala21
-rw-r--r--src/main/scala/firrtl/passes/memlib/ReplaceMemMacros.scala24
-rw-r--r--src/main/scala/firrtl/passes/memlib/ReplaceMemTransform.scala89
4 files changed, 86 insertions, 70 deletions
diff --git a/src/main/scala/firrtl/passes/memlib/DecorateMems.scala b/src/main/scala/firrtl/passes/memlib/DecorateMems.scala
index 10cc8f88..c98dd4ca 100644
--- a/src/main/scala/firrtl/passes/memlib/DecorateMems.scala
+++ b/src/main/scala/firrtl/passes/memlib/DecorateMems.scala
@@ -5,20 +5,22 @@ import ir._
import Annotations._
import wiring._
-class CreateMemoryAnnotations(reader: Option[YamlFileReader], replaceID: TransID, wiringID: TransID) extends Transform {
- def name = "Create Memory Annotations"
- def execute(c: Circuit, map: AnnotationMap): TransformResult = reader match {
- case None => TransformResult(c)
+class CreateMemoryAnnotations(reader: Option[YamlFileReader]) extends Transform {
+ def inputForm = MidForm
+ def outputForm = MidForm
+ override def name = "Create Memory Annotations"
+ def execute(state: CircuitState): CircuitState = reader match {
+ case None => state
case Some(r) =>
import CustomYAMLProtocol._
r.parse[Config] match {
case Seq(config) =>
- val cN = CircuitName(c.main)
- val top = TopAnnotation(ModuleName(config.top.name, cN), wiringID)
- val source = SourceAnnotation(ComponentName(config.source.name, ModuleName(config.source.module, cN)), wiringID)
- val pin = PinAnnotation(cN, replaceID, config.pin.name)
- TransformResult(c, None, Some(AnnotationMap(Seq(top, source, pin))))
- case Nil => TransformResult(c, None, None)
+ val cN = CircuitName(state.circuit.main)
+ val top = TopAnnotation(ModuleName(config.top.name, cN))
+ val source = SourceAnnotation(ComponentName(config.source.name, ModuleName(config.source.module, cN)))
+ val pin = PinAnnotation(cN, config.pin.name)
+ state.copy(annotations = Some(AnnotationMap(Seq(top, source, pin))))
+ case Nil => state
case _ => error("Can only have one config in yaml file")
}
}
diff --git a/src/main/scala/firrtl/passes/memlib/InferReadWrite.scala b/src/main/scala/firrtl/passes/memlib/InferReadWrite.scala
index 28291135..2d6f4e96 100644
--- a/src/main/scala/firrtl/passes/memlib/InferReadWrite.scala
+++ b/src/main/scala/firrtl/passes/memlib/InferReadWrite.scala
@@ -38,10 +38,10 @@ import firrtl.passes.memlib.AnalysisUtils.{Connects, getConnects, getOrigin}
import WrappedExpression.weq
import Annotations._
-case class InferReadWriteAnnotation(t: String, tID: TransID)
- extends Annotation with Loose with Unstable {
+case class InferReadWriteAnnotation(t: String) extends Annotation with Loose with Unstable {
val target = CircuitName(t)
def duplicate(n: Named) = this.copy(t=n.name)
+ def transform = classOf[InferReadWrite]
}
// This pass examine the enable signals of the read & write ports of memories
@@ -168,7 +168,9 @@ object InferReadWritePass extends Pass {
// Transform input: Middle Firrtl. Called after "HighFirrtlToMidleFirrtl"
// To use this transform, circuit name should be annotated with its TransId.
-class InferReadWrite(transID: TransID) extends Transform with SimpleRun {
+class InferReadWrite extends Transform with PassBased {
+ def inputForm = MidForm
+ def outputForm = MidForm
def passSeq = Seq(
InferReadWritePass,
CheckInitialization,
@@ -176,11 +178,12 @@ class InferReadWrite(transID: TransID) extends Transform with SimpleRun {
ResolveKinds,
ResolveGenders
)
- def execute(c: Circuit, map: AnnotationMap) = map get transID match {
- case Some(p) => p get CircuitName(c.main) match {
- case Some(InferReadWriteAnnotation(_, _)) => run(c, passSeq)
- case _ => sys.error("Unexpected annotation for InferReadWrite")
- }
- case _ => TransformResult(c)
+ def execute(state: CircuitState): CircuitState = {
+ val result = for {
+ myAnnotations <- getMyAnnotations(state)
+ InferReadWriteAnnotation(_) <- myAnnotations get CircuitName(state.circuit.main)
+ resCircuit = runPasses(state.circuit)
+ } yield state.copy(circuit = resCircuit)
+ result getOrElse state // Return state if nothing to do
}
}
diff --git a/src/main/scala/firrtl/passes/memlib/ReplaceMemMacros.scala b/src/main/scala/firrtl/passes/memlib/ReplaceMemMacros.scala
index 9ab496d2..ae872639 100644
--- a/src/main/scala/firrtl/passes/memlib/ReplaceMemMacros.scala
+++ b/src/main/scala/firrtl/passes/memlib/ReplaceMemMacros.scala
@@ -16,7 +16,8 @@ import wiring._
/** Annotates the name of the pin to add for WiringTransform
*/
-case class PinAnnotation(target: CircuitName, tID: TransID, pin: String) extends Annotation with Loose with Unstable {
+case class PinAnnotation(target: CircuitName, pin: String) extends Annotation with Loose with Unstable {
+ def transform = classOf[ReplaceMemMacros]
def duplicate(n: Named) = n match {
case n: CircuitName => this.copy(target = n)
case _ => throwInternalError
@@ -27,8 +28,10 @@ case class PinAnnotation(target: CircuitName, tID: TransID, pin: String) extends
* This will not generate wmask ports if not needed.
* Creates the minimum # of black boxes needed by the design.
*/
-class ReplaceMemMacros(writer: ConfWriter, myID: TransID, wiringID: TransID) extends Transform {
- def name = "Replace Memory Macros"
+class ReplaceMemMacros(writer: ConfWriter) extends Transform {
+ override def name = "Replace Memory Macros"
+ def inputForm = MidForm
+ def outputForm = MidForm
/** Return true if mask granularity is per bit, false if per byte or unspecified
*/
@@ -206,7 +209,8 @@ class ReplaceMemMacros(writer: ConfWriter, myID: TransID, wiringID: TransID) ext
map updateStmtRefs(memPortMap))
}
- def execute(c: Circuit, map: AnnotationMap): TransformResult = {
+ def execute(state: CircuitState): CircuitState = {
+ val c = state.circuit
val namespace = Namespace(c)
val memMods = new Modules
val nameMap = new NameMap
@@ -214,15 +218,15 @@ class ReplaceMemMacros(writer: ConfWriter, myID: TransID, wiringID: TransID) ext
val modules = c.modules map updateMemMods(namespace, nameMap, memMods)
// print conf
writer.serialize()
- val pin = map get myID match {
- case Some(p) =>
+ val pin = getMyAnnotations(state) match {
+ case Some(p) =>
p.values.head match {
- case PinAnnotation(c, _, pin) => pin
+ case PinAnnotation(c, pin) => pin
case _ => error(s"Bad Annotations: ${p.values}")
}
case None => "pin"
}
- val annos = memMods.collect { case m: ExtModule => SinkAnnotation(ModuleName(m.name, CircuitName(c.main)), wiringID, pin) }
- TransformResult(c.copy(modules = modules ++ memMods), None, Some(AnnotationMap(annos)))
- }
+ val annos = memMods.collect { case m: ExtModule => SinkAnnotation(ModuleName(m.name, CircuitName(c.main)), pin) }
+ CircuitState(c.copy(modules = modules ++ memMods), inputForm, Some(AnnotationMap(annos)))
+ }
}
diff --git a/src/main/scala/firrtl/passes/memlib/ReplaceMemTransform.scala b/src/main/scala/firrtl/passes/memlib/ReplaceMemTransform.scala
index 01f020f5..818bd9cc 100644
--- a/src/main/scala/firrtl/passes/memlib/ReplaceMemTransform.scala
+++ b/src/main/scala/firrtl/passes/memlib/ReplaceMemTransform.scala
@@ -61,8 +61,7 @@ class ConfWriter(filename: String) {
}
}
-case class ReplSeqMemAnnotation(t: String, tID: TransID)
- extends Annotation with Loose with Unstable {
+case class ReplSeqMemAnnotation(t: String) extends Annotation with Loose with Unstable {
val usage = """
[Optional] ReplSeqMem
@@ -91,52 +90,60 @@ Optional Arguments:
)
val target = CircuitName(passCircuit)
def duplicate(n: Named) = this copy (t = t.replace(s"-c:$passCircuit", s"-c:${n.name}"))
+ def transform = classOf[ReplSeqMem]
}
-case class SimpleTransform(p: Pass) extends Transform {
- def execute(c: Circuit, map: AnnotationMap): TransformResult =
- TransformResult(p.run(c))
+class SimpleTransform(p: Pass, form: CircuitForm) extends Transform {
+ def inputForm = form
+ def outputForm = form
+ def execute(state: CircuitState): CircuitState = state.copy(circuit = p.run(state.circuit))
}
-class ReplSeqMem(transID: TransID) extends Transform with SimpleRun {
+class SimpleMidTransform(p: Pass) extends SimpleTransform(p, MidForm)
+
+// SimpleRun instead of PassBased because of the arguments to passSeq
+class ReplSeqMem extends Transform with SimpleRun {
+ def inputForm = MidForm
+ def outputForm = MidForm
def passSeq(inConfigFile: Option[YamlFileReader], outConfigFile: ConfWriter): Seq[Transform] =
- Seq(SimpleTransform(Legalize),
- SimpleTransform(ToMemIR),
- SimpleTransform(ResolveMaskGranularity),
- SimpleTransform(RenameAnnotatedMemoryPorts),
- SimpleTransform(ResolveMemoryReference),
- new CreateMemoryAnnotations(inConfigFile, TransID(-7), TransID(-8)),
- new ReplaceMemMacros(outConfigFile, TransID(-7), TransID(-8)),
- new WiringTransform(TransID(-8)),
- SimpleTransform(RemoveEmpty),
- SimpleTransform(CheckInitialization),
- SimpleTransform(InferTypes),
- SimpleTransform(Uniquify),
- SimpleTransform(ResolveKinds),
- SimpleTransform(ResolveGenders))
- def run(circuit: Circuit, map: AnnotationMap, xForms: Seq[Transform]): TransformResult = {
- (xForms.foldLeft(TransformResult(circuit, None, Some(map)))) { case (tr: TransformResult, xForm: Transform) =>
- val x = xForm.execute(tr.circuit, tr.annotation.get)
- x.annotation match {
- case None => TransformResult(x.circuit, None, Some(map))
- case Some(ann) => TransformResult(x.circuit, None, Some(
- AnnotationMap(ann.annotations ++ tr.annotation.get.annotations)))
+ Seq(new SimpleMidTransform(Legalize),
+ new SimpleMidTransform(ToMemIR),
+ new SimpleMidTransform(ResolveMaskGranularity),
+ new SimpleMidTransform(RenameAnnotatedMemoryPorts),
+ new SimpleMidTransform(ResolveMemoryReference),
+ new CreateMemoryAnnotations(inConfigFile),
+ new ReplaceMemMacros(outConfigFile),
+ new WiringTransform,
+ new SimpleMidTransform(RemoveEmpty),
+ new SimpleMidTransform(CheckInitialization),
+ new SimpleMidTransform(InferTypes),
+ new SimpleMidTransform(Uniquify),
+ new SimpleMidTransform(ResolveKinds),
+ new SimpleMidTransform(ResolveGenders))
+ def run(state: CircuitState, xForms: Seq[Transform]): CircuitState = {
+ xForms.foldLeft(state) { case (curState: CircuitState, xForm: Transform) =>
+ val res = xForm.execute(state)
+ res.annotations match {
+ case None => CircuitState(res.circuit, res.form, state.annotations)
+ case Some(ann) => CircuitState(res.circuit, res.form, Some(
+ AnnotationMap(ann.annotations ++ curState.annotations.get.annotations)))
}
}
}
- def execute(c: Circuit, map: AnnotationMap) = map get transID match {
- case Some(p) => p get CircuitName(c.main) match {
- case Some(ReplSeqMemAnnotation(t, _)) =>
- val inputFileName = PassConfigUtil.getPassOptions(t).getOrElse(InputConfigFileName, "")
- val inConfigFile = {
- if (inputFileName.isEmpty) None
- else if (new File(inputFileName).exists) Some(new YamlFileReader(inputFileName))
- else error("Input configuration file does not exist!")
- }
- val outConfigFile = new ConfWriter(PassConfigUtil.getPassOptions(t)(OutputConfigFileName))
- run(c, map, passSeq(inConfigFile, outConfigFile))
- case _ => error("Unexpected transform annotation")
+ def execute(state: CircuitState): CircuitState =
+ getMyAnnotations(state) match {
+ case Some(p) => p get CircuitName(state.circuit.main) match {
+ case Some(ReplSeqMemAnnotation(t)) =>
+ val inputFileName = PassConfigUtil.getPassOptions(t).getOrElse(InputConfigFileName, "")
+ val inConfigFile = {
+ if (inputFileName.isEmpty) None
+ else if (new File(inputFileName).exists) Some(new YamlFileReader(inputFileName))
+ else error("Input configuration file does not exist!")
+ }
+ val outConfigFile = new ConfWriter(PassConfigUtil.getPassOptions(t)(OutputConfigFileName))
+ run(state, passSeq(inConfigFile, outConfigFile))
+ case _ => error("Unexpected transform annotation")
+ }
+ case None => state // Do nothing if there are no annotations
}
- case _ => TransformResult(c)
- }
}