diff options
| author | jackkoenig | 2016-10-20 00:19:01 -0700 |
|---|---|---|
| committer | Jack Koenig | 2016-11-04 13:29:09 -0700 |
| commit | 8fa9429a6e916ab2a789f5d81fa803b022805b52 (patch) | |
| tree | fac2efcbd0a68bfb1916f09afc7f003c7a3d6528 /src/main/scala/firrtl/passes/memlib | |
| parent | 62133264a788f46b319ebab9c31424b7e0536101 (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')
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) - } } |
