aboutsummaryrefslogtreecommitdiff
path: root/src/main/scala/firrtl/transforms/TopWiring.scala
diff options
context:
space:
mode:
authorchick2020-08-14 19:47:53 -0700
committerJack Koenig2020-08-14 19:47:53 -0700
commit6fc742bfaf5ee508a34189400a1a7dbffe3f1cac (patch)
tree2ed103ee80b0fba613c88a66af854ae9952610ce /src/main/scala/firrtl/transforms/TopWiring.scala
parentb516293f703c4de86397862fee1897aded2ae140 (diff)
All of src/ formatted with scalafmt
Diffstat (limited to 'src/main/scala/firrtl/transforms/TopWiring.scala')
-rw-r--r--src/main/scala/firrtl/transforms/TopWiring.scala269
1 files changed, 145 insertions, 124 deletions
diff --git a/src/main/scala/firrtl/transforms/TopWiring.scala b/src/main/scala/firrtl/transforms/TopWiring.scala
index f5a5e2a3..b35fed22 100644
--- a/src/main/scala/firrtl/transforms/TopWiring.scala
+++ b/src/main/scala/firrtl/transforms/TopWiring.scala
@@ -4,7 +4,7 @@ package TopWiring
import firrtl._
import firrtl.ir._
-import firrtl.passes.{InferTypes, LowerTypes, ResolveKinds, ResolveFlows, ExpandConnects}
+import firrtl.passes.{ExpandConnects, InferTypes, LowerTypes, ResolveFlows, ResolveKinds}
import firrtl.annotations._
import firrtl.Mappers._
import firrtl.analyses.InstanceKeyGraph
@@ -13,22 +13,21 @@ import firrtl.options.Dependency
import collection.mutable
-/** Annotation for optional output files, and what directory to put those files in (absolute path) **/
-case class TopWiringOutputFilesAnnotation(dirName: String,
- outputFunction: (String,Seq[((ComponentName, Type, Boolean,
- Seq[String],String), Int)],
- CircuitState) => CircuitState) extends NoTargetAnnotation
+/** Annotation for optional output files, and what directory to put those files in (absolute path) * */
+case class TopWiringOutputFilesAnnotation(
+ dirName: String,
+ outputFunction: (String, Seq[((ComponentName, Type, Boolean, Seq[String], String), Int)],
+ CircuitState) => CircuitState)
+ extends NoTargetAnnotation
/** Annotation for indicating component to be wired, and what prefix to add to the ports that are generated */
-case class TopWiringAnnotation(target: ComponentName, prefix: String) extends
- SingleTargetAnnotation[ComponentName] {
+case class TopWiringAnnotation(target: ComponentName, prefix: String) extends SingleTargetAnnotation[ComponentName] {
def duplicate(n: ComponentName) = this.copy(target = n)
}
-
/** Punch out annotated ports out to the toplevel of the circuit.
- This also has an option to pass a function as a parmeter to generate
- custom output files as a result of the additional ports
+ * This also has an option to pass a function as a parmeter to generate
+ * custom output files as a result of the additional ports
* @note This *does* work for deduped modules
*/
class TopWiringTransform extends Transform with DependencyAPIMigration {
@@ -39,116 +38,133 @@ class TopWiringTransform extends Transform with DependencyAPIMigration {
override def invalidates(a: Transform): Boolean = a match {
case InferTypes | ResolveKinds | ResolveFlows | ExpandConnects => true
- case _ => false
+ case _ => false
}
type InstPath = Seq[String]
/** Get the names of the targets that need to be wired */
private def getSourceNames(state: CircuitState): Map[ComponentName, String] = {
- state.annotations.collect { case TopWiringAnnotation(srcname,prefix) =>
- (srcname -> prefix) }.toMap.withDefaultValue("")
+ state.annotations.collect {
+ case TopWiringAnnotation(srcname, prefix) =>
+ (srcname -> prefix)
+ }.toMap.withDefaultValue("")
}
-
/** Get the names of the modules which include the targets that need to be wired */
private def getSourceModNames(state: CircuitState): Seq[String] = {
- state.annotations.collect { case TopWiringAnnotation(ComponentName(_,ModuleName(srcmodname, _)),_) => srcmodname }
+ state.annotations.collect { case TopWiringAnnotation(ComponentName(_, ModuleName(srcmodname, _)), _) => srcmodname }
}
-
-
/** Get the Type of each wire to be connected
*
* Find the definition of each wire in sourceList, and get the type and whether or not it's a port
* Update the results in sourceMap
*/
- private def getSourceTypes(sourceList: Map[ComponentName, String],
- sourceMap: mutable.Map[String, Seq[(ComponentName, Type, Boolean, InstPath, String)]],
- currentmodule: ModuleName, state: CircuitState)(s: Statement): Statement = s match {
+ private def getSourceTypes(
+ sourceList: Map[ComponentName, String],
+ sourceMap: mutable.Map[String, Seq[(ComponentName, Type, Boolean, InstPath, String)]],
+ currentmodule: ModuleName,
+ state: CircuitState
+ )(s: Statement
+ ): Statement = s match {
// If target wire, add name and size to to sourceMap
case w: IsDeclaration =>
if (sourceList.keys.toSeq.contains(ComponentName(w.name, currentmodule))) {
- val (isport, tpe, prefix) = w match {
- case d: DefWire => (false, d.tpe, sourceList(ComponentName(w.name,currentmodule)))
- case d: DefNode => (false, d.value.tpe, sourceList(ComponentName(w.name,currentmodule)))
- case d: DefRegister => (false, d.tpe, sourceList(ComponentName(w.name,currentmodule)))
- case d: Port => (true, d.tpe, sourceList(ComponentName(w.name,currentmodule)))
- case _ => throw new Exception(s"Cannot wire this type of declaration! ${w.serialize}")
- }
- sourceMap.get(currentmodule.name) match {
- case Some(xs:Seq[(ComponentName, Type, Boolean, InstPath, String)]) =>
- sourceMap.update(currentmodule.name, xs :+(
- (ComponentName(w.name,currentmodule), tpe, isport ,Seq[String](w.name), prefix) ))
- case None =>
- sourceMap(currentmodule.name) = Seq((ComponentName(w.name,currentmodule),
- tpe, isport ,Seq[String](w.name), prefix))
- }
+ val (isport, tpe, prefix) = w match {
+ case d: DefWire => (false, d.tpe, sourceList(ComponentName(w.name, currentmodule)))
+ case d: DefNode => (false, d.value.tpe, sourceList(ComponentName(w.name, currentmodule)))
+ case d: DefRegister => (false, d.tpe, sourceList(ComponentName(w.name, currentmodule)))
+ case d: Port => (true, d.tpe, sourceList(ComponentName(w.name, currentmodule)))
+ case _ => throw new Exception(s"Cannot wire this type of declaration! ${w.serialize}")
+ }
+ sourceMap.get(currentmodule.name) match {
+ case Some(xs: Seq[(ComponentName, Type, Boolean, InstPath, String)]) =>
+ sourceMap.update(
+ currentmodule.name,
+ xs :+ ((ComponentName(w.name, currentmodule), tpe, isport, Seq[String](w.name), prefix))
+ )
+ case None =>
+ sourceMap(currentmodule.name) = Seq(
+ (ComponentName(w.name, currentmodule), tpe, isport, Seq[String](w.name), prefix)
+ )
+ }
}
w // Return argument unchanged (ok because DefWire has no Statement children)
// If not, apply to all children Statement
- case _ => s map getSourceTypes(sourceList, sourceMap, currentmodule, state)
+ case _ => s.map(getSourceTypes(sourceList, sourceMap, currentmodule, state))
}
-
-
/** Get the Type of each port to be connected
*
* Similar to getSourceTypes, but specifically for ports since they are not found in statements.
* Find the definition of each port in sourceList, and get the type and whether or not it's a port
* Update the results in sourceMap
*/
- private def getSourceTypesPorts(sourceList: Map[ComponentName, String], sourceMap: mutable.Map[String,
- Seq[(ComponentName, Type, Boolean, InstPath, String)]],
- currentmodule: ModuleName, state: CircuitState)(s: Port): CircuitState = s match {
+ private def getSourceTypesPorts(
+ sourceList: Map[ComponentName, String],
+ sourceMap: mutable.Map[String, Seq[(ComponentName, Type, Boolean, InstPath, String)]],
+ currentmodule: ModuleName,
+ state: CircuitState
+ )(s: Port
+ ): CircuitState = s match {
// If target port, add name and size to to sourceMap
case w: IsDeclaration =>
if (sourceList.keys.toSeq.contains(ComponentName(w.name, currentmodule))) {
- val (isport, tpe, prefix) = w match {
- case d: Port => (true, d.tpe, sourceList(ComponentName(w.name,currentmodule)))
- case _ => throw new Exception(s"Cannot wire this type of declaration! ${w.serialize}")
- }
- sourceMap.get(currentmodule.name) match {
- case Some(xs:Seq[(ComponentName, Type, Boolean, InstPath, String)]) =>
- sourceMap.update(currentmodule.name, xs :+(
- (ComponentName(w.name,currentmodule), tpe, isport ,Seq[String](w.name), prefix) ))
- case None =>
- sourceMap(currentmodule.name) = Seq((ComponentName(w.name,currentmodule),
- tpe, isport ,Seq[String](w.name), prefix))
- }
+ val (isport, tpe, prefix) = w match {
+ case d: Port => (true, d.tpe, sourceList(ComponentName(w.name, currentmodule)))
+ case _ => throw new Exception(s"Cannot wire this type of declaration! ${w.serialize}")
+ }
+ sourceMap.get(currentmodule.name) match {
+ case Some(xs: Seq[(ComponentName, Type, Boolean, InstPath, String)]) =>
+ sourceMap.update(
+ currentmodule.name,
+ xs :+ ((ComponentName(w.name, currentmodule), tpe, isport, Seq[String](w.name), prefix))
+ )
+ case None =>
+ sourceMap(currentmodule.name) = Seq(
+ (ComponentName(w.name, currentmodule), tpe, isport, Seq[String](w.name), prefix)
+ )
+ }
}
state // Return argument unchanged (ok because DefWire has no Statement children)
// If not, apply to all children Statement
case _ => state
}
-
/** Create a map of Module name to target wires under this module
*
* These paths are relative but cross module (they refer down through instance hierarchy)
*/
- private def getSourcesMap(state: CircuitState): Map[String,Seq[(ComponentName, Type, Boolean, InstPath, String)]] = {
+ private def getSourcesMap(state: CircuitState): Map[String, Seq[(ComponentName, Type, Boolean, InstPath, String)]] = {
val sSourcesModNames = getSourceModNames(state)
val sSourcesNames = getSourceNames(state)
val instGraph = firrtl.analyses.InstanceKeyGraph(state.circuit)
- val cMap = instGraph.getChildInstances.map{ case (m, wdis) =>
- (m -> wdis.map{ case wdi => (wdi.name, wdi.module) }.toSeq) }.toMap
+ val cMap = instGraph.getChildInstances.map {
+ case (m, wdis) =>
+ (m -> wdis.map { case wdi => (wdi.name, wdi.module) }.toSeq)
+ }.toMap
val topSort = instGraph.moduleOrder.reverse
// Map of component name to relative instance paths that result in a debug wire
val sourcemods: mutable.Map[String, Seq[(ComponentName, Type, Boolean, InstPath, String)]] =
mutable.Map(sSourcesModNames.map(_ -> Seq()): _*)
- state.circuit.modules.foreach { m => m map
- getSourceTypes(sSourcesNames, sourcemods, ModuleName(m.name, CircuitName(state.circuit.main)) , state) }
- state.circuit.modules.foreach { m => m.ports.foreach {
- p => Seq(p) map
- getSourceTypesPorts(sSourcesNames, sourcemods, ModuleName(m.name, CircuitName(state.circuit.main)) , state) }}
+ state.circuit.modules.foreach { m =>
+ m.map(getSourceTypes(sSourcesNames, sourcemods, ModuleName(m.name, CircuitName(state.circuit.main)), state))
+ }
+ state.circuit.modules.foreach { m =>
+ m.ports.foreach { p =>
+ Seq(p).map(
+ getSourceTypesPorts(sSourcesNames, sourcemods, ModuleName(m.name, CircuitName(state.circuit.main)), state)
+ )
+ }
+ }
for (mod <- topSort) {
- val seqChildren: Seq[(ComponentName,Type,Boolean,InstPath,String)] = cMap(mod.name).flatMap {
+ val seqChildren: Seq[(ComponentName, Type, Boolean, InstPath, String)] = cMap(mod.name).flatMap {
case (inst, module) =>
- sourcemods.get(module).map( _.map { case (a,b,c,path,p) => (a,b,c, inst +: path, p)})
+ sourcemods.get(module).map(_.map { case (a, b, c, path, p) => (a, b, c, inst +: path, p) })
}.flatten
if (seqChildren.nonEmpty) {
sourcemods(mod.name) = sourcemods.getOrElse(mod.name, Seq()) ++ seqChildren
@@ -158,108 +174,113 @@ class TopWiringTransform extends Transform with DependencyAPIMigration {
sourcemods.toMap
}
-
-
/** Process a given DefModule
*
* For Modules that contain or are in the parent hierarchy to modules containing target wires
* 1. Add ports for each target wire this module is parent to
* 2. Connect these ports to ports of instances that are parents to some number of target wires
*/
- private def onModule(sources: Map[String, Seq[(ComponentName, Type, Boolean, InstPath, String)]],
- portnamesmap : mutable.Map[String,String],
- instgraph : firrtl.analyses.InstanceKeyGraph,
- namespacemap : Map[String, Namespace])
- (module: DefModule): DefModule = {
+ private def onModule(
+ sources: Map[String, Seq[(ComponentName, Type, Boolean, InstPath, String)]],
+ portnamesmap: mutable.Map[String, String],
+ instgraph: firrtl.analyses.InstanceKeyGraph,
+ namespacemap: Map[String, Namespace]
+ )(module: DefModule
+ ): DefModule = {
val namespace = namespacemap(module.name)
sources.get(module.name) match {
case Some(p) =>
- val newPorts = p.map{ case (ComponentName(cname,_), tpe, _ , path, prefix) => {
- val newportname = portnamesmap.get(prefix + path.mkString("_")) match {
- case Some(pn) => pn
- case None => {
- val npn = namespace.newName(prefix + path.mkString("_"))
- portnamesmap(prefix + path.mkString("_")) = npn
- npn
- }
+ val newPorts = p.map {
+ case (ComponentName(cname, _), tpe, _, path, prefix) => {
+ val newportname = portnamesmap.get(prefix + path.mkString("_")) match {
+ case Some(pn) => pn
+ case None => {
+ val npn = namespace.newName(prefix + path.mkString("_"))
+ portnamesmap(prefix + path.mkString("_")) = npn
+ npn
}
- Port(NoInfo, newportname, Output, tpe)
- } }
+ }
+ Port(NoInfo, newportname, Output, tpe)
+ }
+ }
// Add connections to Module
val childInstances = instgraph.getChildInstances.toMap
module match {
case m: Module =>
- val connections: Seq[Connect] = p.map { case (ComponentName(cname,_), _, _ , path, prefix) =>
+ val connections: Seq[Connect] = p.map {
+ case (ComponentName(cname, _), _, _, path, prefix) =>
val modRef = portnamesmap.get(prefix + path.mkString("_")) match {
- case Some(pn) => WRef(pn)
- case None => {
- portnamesmap(prefix + path.mkString("_")) = namespace.newName(prefix + path.mkString("_"))
- WRef(portnamesmap(prefix + path.mkString("_")))
- }
+ case Some(pn) => WRef(pn)
+ case None => {
+ portnamesmap(prefix + path.mkString("_")) = namespace.newName(prefix + path.mkString("_"))
+ WRef(portnamesmap(prefix + path.mkString("_")))
+ }
}
path.size match {
- case 1 => {
- val leafRef = WRef(path.head.mkString(""))
- Connect(NoInfo, modRef, leafRef)
- }
- case _ => {
- val instportname = portnamesmap.get(prefix + path.tail.mkString("_")) match {
- case Some(ipn) => ipn
- case None => {
- val instmod = childInstances(module.name).collectFirst {
- case wdi if wdi.name == path.head => wdi.module}.get
- val instnamespace = namespacemap(instmod)
- portnamesmap(prefix + path.tail.mkString("_")) =
- instnamespace.newName(prefix + path.tail.mkString("_"))
- portnamesmap(prefix + path.tail.mkString("_"))
- }
- }
- val instRef = WSubField(WRef(path.head), instportname)
- Connect(NoInfo, modRef, instRef)
+ case 1 => {
+ val leafRef = WRef(path.head.mkString(""))
+ Connect(NoInfo, modRef, leafRef)
+ }
+ case _ => {
+ val instportname = portnamesmap.get(prefix + path.tail.mkString("_")) match {
+ case Some(ipn) => ipn
+ case None => {
+ val instmod = childInstances(module.name).collectFirst {
+ case wdi if wdi.name == path.head => wdi.module
+ }.get
+ val instnamespace = namespacemap(instmod)
+ portnamesmap(prefix + path.tail.mkString("_")) =
+ instnamespace.newName(prefix + path.tail.mkString("_"))
+ portnamesmap(prefix + path.tail.mkString("_"))
+ }
+ }
+ val instRef = WSubField(WRef(path.head), instportname)
+ Connect(NoInfo, modRef, instRef)
}
}
}
- m.copy(ports = m.ports ++ newPorts, body = Block(Seq(m.body) ++ connections ))
+ m.copy(ports = m.ports ++ newPorts, body = Block(Seq(m.body) ++ connections))
case e: ExtModule =>
e.copy(ports = e.ports ++ newPorts)
- }
+ }
case None => module // unchanged if no paths
}
}
- /** Dummy function that is currently unused. Can be used to fill an outputFunction requirment in the future */
- def topWiringDummyOutputFilesFunction(dir: String,
- mapping: Seq[((ComponentName, Type, Boolean, InstPath, String), Int)],
- state: CircuitState): CircuitState = {
- state
+ /** Dummy function that is currently unused. Can be used to fill an outputFunction requirment in the future */
+ def topWiringDummyOutputFilesFunction(
+ dir: String,
+ mapping: Seq[((ComponentName, Type, Boolean, InstPath, String), Int)],
+ state: CircuitState
+ ): CircuitState = {
+ state
}
-
def execute(state: CircuitState): CircuitState = {
- val outputTuples: Seq[(String,
- (String,Seq[((ComponentName, Type, Boolean, InstPath, String), Int)],
- CircuitState) => CircuitState)] = state.annotations.collect {
- case TopWiringOutputFilesAnnotation(td,of) => (td, of) }
+ val outputTuples: Seq[
+ (String, (String, Seq[((ComponentName, Type, Boolean, InstPath, String), Int)], CircuitState) => CircuitState)
+ ] = state.annotations.collect {
+ case TopWiringOutputFilesAnnotation(td, of) => (td, of)
+ }
// Do actual work of this transform
val sources = getSourcesMap(state)
val (nstate, nmappings) = if (sources.nonEmpty) {
- val portnamesmap: mutable.Map[String,String] = mutable.Map()
+ val portnamesmap: mutable.Map[String, String] = mutable.Map()
val instgraph = InstanceKeyGraph(state.circuit)
- val namespacemap = state.circuit.modules.map{ case m => (m.name -> Namespace(m)) }.toMap
- val modulesx = state.circuit.modules map onModule(sources, portnamesmap, instgraph, namespacemap)
+ val namespacemap = state.circuit.modules.map { case m => (m.name -> Namespace(m)) }.toMap
+ val modulesx = state.circuit.modules.map(onModule(sources, portnamesmap, instgraph, namespacemap))
val newCircuit = state.circuit.copy(modules = modulesx)
val mappings = sources(state.circuit.main).zipWithIndex
val annosx = state.annotations.filter {
case _: TopWiringAnnotation => false
- case _ => true
+ case _ => true
}
(state.copy(circuit = newCircuit, annotations = annosx), mappings)
- }
- else { (state, List.empty) }
+ } else { (state, List.empty) }
//Generate output files based on the mapping.
outputTuples.map { case (dir, outputfunction) => outputfunction(dir, nmappings, nstate) }
nstate