diff options
| author | chick | 2020-08-14 19:47:53 -0700 |
|---|---|---|
| committer | Jack Koenig | 2020-08-14 19:47:53 -0700 |
| commit | 6fc742bfaf5ee508a34189400a1a7dbffe3f1cac (patch) | |
| tree | 2ed103ee80b0fba613c88a66af854ae9952610ce /src/main/scala/firrtl/analyses | |
| parent | b516293f703c4de86397862fee1897aded2ae140 (diff) | |
All of src/ formatted with scalafmt
Diffstat (limited to 'src/main/scala/firrtl/analyses')
| -rw-r--r-- | src/main/scala/firrtl/analyses/CircuitGraph.scala | 7 | ||||
| -rw-r--r-- | src/main/scala/firrtl/analyses/ConnectionGraph.scala | 146 | ||||
| -rw-r--r-- | src/main/scala/firrtl/analyses/IRLookup.scala | 189 | ||||
| -rw-r--r-- | src/main/scala/firrtl/analyses/InstanceGraph.scala | 30 | ||||
| -rw-r--r-- | src/main/scala/firrtl/analyses/InstanceKeyGraph.scala | 36 | ||||
| -rw-r--r-- | src/main/scala/firrtl/analyses/NodeCount.scala | 11 | ||||
| -rw-r--r-- | src/main/scala/firrtl/analyses/SymbolTable.scala | 27 |
7 files changed, 273 insertions, 173 deletions
diff --git a/src/main/scala/firrtl/analyses/CircuitGraph.scala b/src/main/scala/firrtl/analyses/CircuitGraph.scala index 506bba57..a1fb0f19 100644 --- a/src/main/scala/firrtl/analyses/CircuitGraph.scala +++ b/src/main/scala/firrtl/analyses/CircuitGraph.scala @@ -80,9 +80,10 @@ class CircuitGraph private[analyses] (connectionGraph: ConnectionGraph) { * @return */ def absolutePaths(mt: ModuleTarget): Seq[IsModule] = instanceGraph.findInstancesInHierarchy(mt.module).map { - case seq if seq.nonEmpty => seq.foldLeft(CircuitTarget(circuit.main).module(circuit.main): IsModule) { - case (it, InstanceKey(instance, ofModule)) => it.instOf(instance, ofModule) - } + case seq if seq.nonEmpty => + seq.foldLeft(CircuitTarget(circuit.main).module(circuit.main): IsModule) { + case (it, InstanceKey(instance, ofModule)) => it.instOf(instance, ofModule) + } } /** Return the sequence of nodes from source to sink, inclusive diff --git a/src/main/scala/firrtl/analyses/ConnectionGraph.scala b/src/main/scala/firrtl/analyses/ConnectionGraph.scala index 0e13711a..f98cf14c 100644 --- a/src/main/scala/firrtl/analyses/ConnectionGraph.scala +++ b/src/main/scala/firrtl/analyses/ConnectionGraph.scala @@ -16,22 +16,24 @@ import scala.collection.mutable * @param circuit firrtl AST of this graph. * @param digraph Directed graph of ReferenceTarget in the AST. * @param irLookup [[IRLookup]] instance of circuit graph. - * */ -class ConnectionGraph protected(val circuit: Circuit, - val digraph: DiGraph[ReferenceTarget], - val irLookup: IRLookup) - extends DiGraph[ReferenceTarget](digraph.getEdgeMap.asInstanceOf[mutable.LinkedHashMap[ReferenceTarget, mutable.LinkedHashSet[ReferenceTarget]]]) { + */ +class ConnectionGraph protected (val circuit: Circuit, val digraph: DiGraph[ReferenceTarget], val irLookup: IRLookup) + extends DiGraph[ReferenceTarget]( + digraph.getEdgeMap.asInstanceOf[mutable.LinkedHashMap[ReferenceTarget, mutable.LinkedHashSet[ReferenceTarget]]] + ) { lazy val serialize: String = s"""{ - |${getEdgeMap.map { case (k, vs) => + |${getEdgeMap.map { + case (k, vs) => s""" "$k": { - | "kind": "${irLookup.kind(k)}", - | "type": "${irLookup.tpe(k)}", - | "expr": "${irLookup.expr(k, irLookup.flow(k))}", - | "sinks": [${vs.map { v => s""""$v"""" }.mkString(", ")}], - | "declaration": "${irLookup.declaration(k)}" - | }""".stripMargin }.mkString(",\n")} - |}""".stripMargin + | "kind": "${irLookup.kind(k)}", + | "type": "${irLookup.tpe(k)}", + | "expr": "${irLookup.expr(k, irLookup.flow(k))}", + | "sinks": [${vs.map { v => s""""$v"""" }.mkString(", ")}], + | "declaration": "${irLookup.declaration(k)}" + | }""".stripMargin + }.mkString(",\n")} + |}""".stripMargin /** Used by BFS to map each visited node to the list of instance inputs visited thus far * @@ -134,7 +136,10 @@ class ConnectionGraph protected(val circuit: Circuit, /** @return a new, reversed connection graph where edges point from sinks to sources. */ def reverseConnectionGraph: ConnectionGraph = new ConnectionGraph(circuit, digraph.reverse, irLookup) - override def BFS(root: ReferenceTarget, blacklist: collection.Set[ReferenceTarget]): collection.Map[ReferenceTarget, ReferenceTarget] = { + override def BFS( + root: ReferenceTarget, + blacklist: collection.Set[ReferenceTarget] + ): collection.Map[ReferenceTarget, ReferenceTarget] = { val prev = new mutable.LinkedHashMap[ReferenceTarget, ReferenceTarget]() val ordering = new Ordering[ReferenceTarget] { override def compare(x: ReferenceTarget, y: ReferenceTarget): Int = x.path.size - y.path.size @@ -216,7 +221,6 @@ class ConnectionGraph protected(val circuit: Circuit, bfsShortCuts.get(localSource) match { case Some(set) => set.map { x => x.setPathTarget(source.pathTarget) } case None => - val pathlessEdges = super.getEdges(localSource) val ret = pathlessEdges.flatMap { @@ -246,7 +250,9 @@ class ConnectionGraph protected(val circuit: Circuit, // Exiting to parent, but had unresolved trip through child, so don't update shortcut portConnectivityStack(localSink) = localSource +: currentStack } - Set[ReferenceTarget](localSink.setPathTarget(source.noComponents.targetParent.asInstanceOf[IsComponent].pathTarget)) + Set[ReferenceTarget]( + localSink.setPathTarget(source.noComponents.targetParent.asInstanceOf[IsComponent].pathTarget) + ) case localSink if enteringChildInstance(source)(localSink) => portConnectivityStack(localSink) = localSource +: portConnectivityStack.getOrElse(localSource, Nil) @@ -265,24 +271,31 @@ class ConnectionGraph protected(val circuit: Circuit, } - override def path(start: ReferenceTarget, end: ReferenceTarget, blacklist: collection.Set[ReferenceTarget]): Seq[ReferenceTarget] = { + override def path( + start: ReferenceTarget, + end: ReferenceTarget, + blacklist: collection.Set[ReferenceTarget] + ): Seq[ReferenceTarget] = { insertShortCuts(super.path(start, end, blacklist)) } private def insertShortCuts(path: Seq[ReferenceTarget]): Seq[ReferenceTarget] = { val soFar = mutable.HashSet[ReferenceTarget]() if (path.size > 1) { - path.head +: path.sliding(2).flatMap { - case Seq(from, to) => - getShortCut(from) match { - case Some(set) if set.contains(to) && soFar.contains(from.pathlessTarget) => - soFar += from.pathlessTarget - Seq(from.pathTarget.ref("..."), to) - case _ => - soFar += from.pathlessTarget - Seq(to) - } - }.toSeq + path.head +: path + .sliding(2) + .flatMap { + case Seq(from, to) => + getShortCut(from) match { + case Some(set) if set.contains(to) && soFar.contains(from.pathlessTarget) => + soFar += from.pathlessTarget + Seq(from.pathTarget.ref("..."), to) + case _ => + soFar += from.pathlessTarget + Seq(to) + } + } + .toSeq } else path } @@ -325,16 +338,16 @@ object ConnectionGraph { * @return */ def asTarget(m: ModuleTarget, tagger: TokenTagger)(e: FirrtlNode): ReferenceTarget = e match { - case l: Literal => m.ref(tagger.getRef(l.value.toString)) + case l: Literal => m.ref(tagger.getRef(l.value.toString)) case r: Reference => m.ref(r.name) - case s: SubIndex => asTarget(m, tagger)(s.expr).index(s.value) - case s: SubField => asTarget(m, tagger)(s.expr).field(s.name) - case d: DoPrim => m.ref(tagger.getRef(d.op.serialize)) - case _: Mux => m.ref(tagger.getRef("mux")) - case _: ValidIf => m.ref(tagger.getRef("validif")) + case s: SubIndex => asTarget(m, tagger)(s.expr).index(s.value) + case s: SubField => asTarget(m, tagger)(s.expr).field(s.name) + case d: DoPrim => m.ref(tagger.getRef(d.op.serialize)) + case _: Mux => m.ref(tagger.getRef("mux")) + case _: ValidIf => m.ref(tagger.getRef("validif")) case WInvalid => m.ref(tagger.getRef("invalid")) case _: Print => m.ref(tagger.getRef("print")) - case _: Stop => m.ref(tagger.getRef("print")) + case _: Stop => m.ref(tagger.getRef("print")) case other => sys.error(s"Unsupported: $other") } @@ -354,30 +367,31 @@ object ConnectionGraph { def enteringNonParentInstance(source: ReferenceTarget)(localSink: ReferenceTarget): Boolean = { source.path.nonEmpty && - (source.noComponents.targetParent.asInstanceOf[InstanceTarget].encapsulatingModule != localSink.module || - localSink.ref != source.path.last._1.value) + (source.noComponents.targetParent.asInstanceOf[InstanceTarget].encapsulatingModule != localSink.module || + localSink.ref != source.path.last._1.value) } def enteringChildInstance(source: ReferenceTarget)(localSink: ReferenceTarget): Boolean = source match { case ReferenceTarget(_, _, _, _, TargetToken.Field(port) +: comps) - if port == localSink.ref && comps == localSink.component => true + if port == localSink.ref && comps == localSink.component => + true case _ => false } def leavingRootInstance(source: ReferenceTarget)(localSink: ReferenceTarget): Boolean = source match { case ReferenceTarget(_, _, Seq(), port, comps) - if port == localSink.component.head.value && comps == localSink.component.tail => true + if port == localSink.component.head.value && comps == localSink.component.tail => + true case _ => false } - private def buildCircuitGraph(circuit: Circuit): ConnectionGraph = { val mdg = new MutableDiGraph[ReferenceTarget]() val declarations = mutable.LinkedHashMap[ModuleTarget, mutable.LinkedHashMap[ReferenceTarget, FirrtlNode]]() val circuitTarget = CircuitTarget(circuit.main) val moduleMap = circuit.modules.map { m => circuitTarget.module(m.name) -> m }.toMap - circuit map buildModule(circuitTarget) + circuit.map(buildModule(circuitTarget)) def addLabeledVertex(v: ReferenceTarget, f: FirrtlNode): Unit = { mdg.addVertex(v) @@ -386,7 +400,7 @@ object ConnectionGraph { def buildModule(c: CircuitTarget)(module: DefModule): DefModule = { val m = c.module(module.name) - module map buildPort(m) map buildStatement(m, new TokenTagger()) + module.map(buildPort(m)).map(buildStatement(m, new TokenTagger())) } def buildPort(m: ModuleTarget)(port: Port): Port = { @@ -412,7 +426,7 @@ object ConnectionGraph { (Utils.flow(instExp), Utils.flow(modExp)) match { case (SourceFlow, SinkFlow) => mdg.addPairWithEdge(it, mt) case (SinkFlow, SourceFlow) => mdg.addPairWithEdge(mt, it) - case _ => sys.error("Something went wrong...") + case _ => sys.error("Something went wrong...") } } } @@ -461,13 +475,14 @@ object ConnectionGraph { // Connect each subTarget to the corresponding init subTarget val allRegTargets = regTarget.leafSubTargets(d.tpe) val allInitTargets = initTarget.leafSubTargets(d.tpe).zip(Utils.create_exps(d.init)) - allRegTargets.zip(allInitTargets).foreach { case (r, (i, e)) => - mdg.addVertex(i) - mdg.addVertex(r) - mdg.addEdge(clockTarget, r) - mdg.addEdge(resetTarget, r) - mdg.addEdge(i, r) - buildExpression(m, tagger, i)(e) + allRegTargets.zip(allInitTargets).foreach { + case (r, (i, e)) => + mdg.addVertex(i) + mdg.addVertex(r) + mdg.addEdge(clockTarget, r) + mdg.addEdge(resetTarget, r) + mdg.addEdge(i, r) + buildExpression(m, tagger, i)(e) } } @@ -480,9 +495,10 @@ object ConnectionGraph { val sinkTarget = m.ref(d.name) addLabeledVertex(sinkTarget, stmt) val nodeTargets = sinkTarget.leafSubTargets(d.value.tpe) - nodeTargets.zip(Utils.create_exps(d.value)).foreach { case (n, e) => - mdg.addVertex(n) - buildExpression(m, tagger, n)(e) + nodeTargets.zip(Utils.create_exps(d.value)).foreach { + case (n, e) => + mdg.addVertex(n) + buildExpression(m, tagger, n)(e) } case c: Connect => @@ -512,10 +528,10 @@ object ConnectionGraph { addLabeledVertex(m.ref(d.name), d) buildMemory(m, d) - /** @todo [[firrtl.Transform.prerequisites]] ++ [[firrtl.passes.ExpandWhensAndCheck]]*/ + /** @todo [[firrtl.Transform.prerequisites]] ++ [[firrtl.passes.ExpandWhensAndCheck]] */ case _: Conditionally => sys.error("Unsupported! Only works on Middle Firrtl") - case s: Block => s map buildStatement(m, tagger) + case s: Block => s.map(buildStatement(m, tagger)) case a: Attach => val attachTargets = a.exprs.map { r => @@ -523,18 +539,25 @@ object ConnectionGraph { mdg.addVertex(at) at } - attachTargets.combinations(2).foreach { case Seq(l, r) => - mdg.addEdge(l, r) - mdg.addEdge(r, l) + attachTargets.combinations(2).foreach { + case Seq(l, r) => + mdg.addEdge(l, r) + mdg.addEdge(r, l) } case p: Print => addLabeledVertex(asTarget(m, tagger)(p), p) - case s: Stop => addLabeledVertex(asTarget(m, tagger)(s), s) + case s: Stop => addLabeledVertex(asTarget(m, tagger)(s), s) case EmptyStmt => } stmt } - def buildExpression(m: ModuleTarget, tagger: TokenTagger, sinkTarget: ReferenceTarget)(expr: Expression): Expression = { + def buildExpression( + m: ModuleTarget, + tagger: TokenTagger, + sinkTarget: ReferenceTarget + )(expr: Expression + ): Expression = { + /** @todo [[firrtl.Transform.prerequisites]] ++ [[firrtl.stage.Forms.Resolved]]. */ val sourceTarget = asTarget(m, tagger)(expr) mdg.addVertex(sourceTarget) @@ -542,7 +565,7 @@ object ConnectionGraph { expr match { case _: DoPrim | _: Mux | _: ValidIf | _: Literal => addLabeledVertex(sourceTarget, expr) - expr map buildExpression(m, tagger, sourceTarget) + expr.map(buildExpression(m, tagger, sourceTarget)) case _ => } expr @@ -552,7 +575,6 @@ object ConnectionGraph { } } - /** Used for obtaining a tag for a given label unnamed Target. */ class TokenTagger { private val counterMap = mutable.HashMap[String, Int]() diff --git a/src/main/scala/firrtl/analyses/IRLookup.scala b/src/main/scala/firrtl/analyses/IRLookup.scala index f9819ebd..b8528a95 100644 --- a/src/main/scala/firrtl/analyses/IRLookup.scala +++ b/src/main/scala/firrtl/analyses/IRLookup.scala @@ -6,7 +6,22 @@ import firrtl.annotations.TargetToken._ import firrtl.annotations._ import firrtl.ir._ import firrtl.passes.MemPortUtils -import firrtl.{DuplexFlow, ExpKind, Flow, InstanceKind, Kind, MemKind, PortKind, RegKind, SinkFlow, SourceFlow, UnknownFlow, Utils, WInvalid, WireKind} +import firrtl.{ + DuplexFlow, + ExpKind, + Flow, + InstanceKind, + Kind, + MemKind, + PortKind, + RegKind, + SinkFlow, + SourceFlow, + UnknownFlow, + Utils, + WInvalid, + WireKind +} import scala.collection.mutable @@ -19,26 +34,33 @@ object IRLookup { * @param declarations Maps references (not subreferences) to declarations * @param modules Maps module targets to modules */ -class IRLookup private[analyses](private val declarations: Map[ModuleTarget, Map[ReferenceTarget, FirrtlNode]], - private val modules: Map[ModuleTarget, DefModule]) { +class IRLookup private[analyses] ( + private val declarations: Map[ModuleTarget, Map[ReferenceTarget, FirrtlNode]], + private val modules: Map[ModuleTarget, DefModule]) { private val flowCache = mutable.HashMap[ModuleTarget, mutable.HashMap[ReferenceTarget, Flow]]() private val kindCache = mutable.HashMap[ModuleTarget, mutable.HashMap[ReferenceTarget, Kind]]() private val tpeCache = mutable.HashMap[ModuleTarget, mutable.HashMap[ReferenceTarget, Type]]() private val exprCache = mutable.HashMap[ModuleTarget, mutable.HashMap[(ReferenceTarget, Flow), Expression]]() - private val refCache = mutable.HashMap[ModuleTarget, mutable.LinkedHashMap[Kind, mutable.ArrayBuffer[ReferenceTarget]]]() - + private val refCache = + mutable.HashMap[ModuleTarget, mutable.LinkedHashMap[Kind, mutable.ArrayBuffer[ReferenceTarget]]]() /** @example Given ~Top|MyModule/inst:Other>foo.bar, returns ~Top|Other>foo * @return the target converted to its local reference */ def asLocalRef(t: ReferenceTarget): ReferenceTarget = t.pathlessTarget.copy(component = Nil) - def flow(t: ReferenceTarget): Flow = flowCache.getOrElseUpdate(t.moduleTarget, mutable.HashMap[ReferenceTarget, Flow]()).getOrElseUpdate(t.pathlessTarget, Utils.flow(expr(t.pathlessTarget))) + def flow(t: ReferenceTarget): Flow = flowCache + .getOrElseUpdate(t.moduleTarget, mutable.HashMap[ReferenceTarget, Flow]()) + .getOrElseUpdate(t.pathlessTarget, Utils.flow(expr(t.pathlessTarget))) - def kind(t: ReferenceTarget): Kind = kindCache.getOrElseUpdate(t.moduleTarget, mutable.HashMap[ReferenceTarget, Kind]()).getOrElseUpdate(t.pathlessTarget, Utils.kind(expr(t.pathlessTarget))) + def kind(t: ReferenceTarget): Kind = kindCache + .getOrElseUpdate(t.moduleTarget, mutable.HashMap[ReferenceTarget, Kind]()) + .getOrElseUpdate(t.pathlessTarget, Utils.kind(expr(t.pathlessTarget))) - def tpe(t: ReferenceTarget): Type = tpeCache.getOrElseUpdate(t.moduleTarget, mutable.HashMap[ReferenceTarget, Type]()).getOrElseUpdate(t.pathlessTarget, expr(t.pathlessTarget).tpe) + def tpe(t: ReferenceTarget): Type = tpeCache + .getOrElseUpdate(t.moduleTarget, mutable.HashMap[ReferenceTarget, Type]()) + .getOrElseUpdate(t.pathlessTarget, expr(t.pathlessTarget).tpe) /** get expression of the target. * It can return None for many reasons, including @@ -54,7 +76,7 @@ class IRLookup private[analyses](private val declarations: Map[ModuleTarget, Map val pathless = t.pathlessTarget inCache(pathless, flow) match { - case e@Some(_) => return e + case e @ Some(_) => return e case None => val mt = pathless.moduleTarget val emt = t.encapsulatingModuleTarget @@ -62,36 +84,50 @@ class IRLookup private[analyses](private val declarations: Map[ModuleTarget, Map declarations(emt)(asLocalRef(t)) match { case e: Expression => require(e.tpe.isInstanceOf[GroundType]) - exprCache.getOrElseUpdate(pathless.moduleTarget, mutable.HashMap[(ReferenceTarget, Flow), Expression]()).getOrElseUpdate((pathless, Utils.flow(e)), e) - case d: IsDeclaration => d match { - case n: DefNode => - updateExpr(mt, Reference(n.name, n.value.tpe, ExpKind, SourceFlow)) - case p: Port => - updateExpr(mt, Reference(p.name, p.tpe, PortKind, Utils.get_flow(p))) - case w: DefInstance => - updateExpr(mt, Reference(w.name, w.tpe, InstanceKind, SourceFlow)) - case w: DefWire => - updateExpr(mt, Reference(w.name, w.tpe, WireKind, SourceFlow)) - updateExpr(mt, Reference(w.name, w.tpe, WireKind, SinkFlow)) - updateExpr(mt, Reference(w.name, w.tpe, WireKind, DuplexFlow)) - case r: DefRegister if pathless.tokens.last == Clock => - exprCache.getOrElseUpdate(pathless.moduleTarget, mutable.HashMap[(ReferenceTarget, Flow), Expression]())((pathless, SourceFlow)) = r.clock - case r: DefRegister if pathless.tokens.isDefinedAt(1) && pathless.tokens(1) == Init => - exprCache.getOrElseUpdate(pathless.moduleTarget, mutable.HashMap[(ReferenceTarget, Flow), Expression]())((pathless, SourceFlow)) = r.init - updateExpr(pathless, r.init) - case r: DefRegister if pathless.tokens.last == Reset => - exprCache.getOrElseUpdate(pathless.moduleTarget, mutable.HashMap[(ReferenceTarget, Flow), Expression]())((pathless, SourceFlow)) = r.reset - case r: DefRegister => - updateExpr(mt, Reference(r.name, r.tpe, RegKind, SourceFlow)) - updateExpr(mt, Reference(r.name, r.tpe, RegKind, SinkFlow)) - updateExpr(mt, Reference(r.name, r.tpe, RegKind, DuplexFlow)) - case m: DefMemory => - updateExpr(mt, Reference(m.name, MemPortUtils.memType(m), MemKind, SourceFlow)) - case other => - sys.error(s"Cannot call expr with: $t, given declaration $other") - } + exprCache + .getOrElseUpdate(pathless.moduleTarget, mutable.HashMap[(ReferenceTarget, Flow), Expression]()) + .getOrElseUpdate((pathless, Utils.flow(e)), e) + case d: IsDeclaration => + d match { + case n: DefNode => + updateExpr(mt, Reference(n.name, n.value.tpe, ExpKind, SourceFlow)) + case p: Port => + updateExpr(mt, Reference(p.name, p.tpe, PortKind, Utils.get_flow(p))) + case w: DefInstance => + updateExpr(mt, Reference(w.name, w.tpe, InstanceKind, SourceFlow)) + case w: DefWire => + updateExpr(mt, Reference(w.name, w.tpe, WireKind, SourceFlow)) + updateExpr(mt, Reference(w.name, w.tpe, WireKind, SinkFlow)) + updateExpr(mt, Reference(w.name, w.tpe, WireKind, DuplexFlow)) + case r: DefRegister if pathless.tokens.last == Clock => + exprCache.getOrElseUpdate( + pathless.moduleTarget, + mutable.HashMap[(ReferenceTarget, Flow), Expression]() + )((pathless, SourceFlow)) = r.clock + case r: DefRegister if pathless.tokens.isDefinedAt(1) && pathless.tokens(1) == Init => + exprCache.getOrElseUpdate( + pathless.moduleTarget, + mutable.HashMap[(ReferenceTarget, Flow), Expression]() + )((pathless, SourceFlow)) = r.init + updateExpr(pathless, r.init) + case r: DefRegister if pathless.tokens.last == Reset => + exprCache.getOrElseUpdate( + pathless.moduleTarget, + mutable.HashMap[(ReferenceTarget, Flow), Expression]() + )((pathless, SourceFlow)) = r.reset + case r: DefRegister => + updateExpr(mt, Reference(r.name, r.tpe, RegKind, SourceFlow)) + updateExpr(mt, Reference(r.name, r.tpe, RegKind, SinkFlow)) + updateExpr(mt, Reference(r.name, r.tpe, RegKind, DuplexFlow)) + case m: DefMemory => + updateExpr(mt, Reference(m.name, MemPortUtils.memType(m), MemKind, SourceFlow)) + case other => + sys.error(s"Cannot call expr with: $t, given declaration $other") + } case _: IsInvalid => - exprCache.getOrElseUpdate(pathless.moduleTarget, mutable.HashMap[(ReferenceTarget, Flow), Expression]())((pathless, SourceFlow)) = WInvalid + exprCache.getOrElseUpdate(pathless.moduleTarget, mutable.HashMap[(ReferenceTarget, Flow), Expression]())( + (pathless, SourceFlow) + ) = WInvalid } } } @@ -118,7 +154,8 @@ class IRLookup private[analyses](private val declarations: Map[ModuleTarget, Map * * @param moduleTarget [[firrtl.annotations.ModuleTarget]] to be queried. * @param kind [[firrtl.Kind]] to be find. - * @return all [[firrtl.annotations.ReferenceTarget]] in this node. */ + * @return all [[firrtl.annotations.ReferenceTarget]] in this node. + */ def kindFinder(moduleTarget: ModuleTarget, kind: Kind): Seq[ReferenceTarget] = { def updateRefs(kind: Kind, rt: ReferenceTarget): Unit = refCache .getOrElseUpdate(rt.moduleTarget, mutable.LinkedHashMap.empty[Kind, mutable.ArrayBuffer[ReferenceTarget]]) @@ -136,7 +173,11 @@ class IRLookup private[analyses](private val declarations: Map[ModuleTarget, Map case (rt, _: Port) => updateRefs(PortKind, rt) case _ => } - refCache.get(moduleTarget).map(_.getOrElse(kind, Seq.empty[ReferenceTarget])).getOrElse(Seq.empty[ReferenceTarget]).toSeq + refCache + .get(moduleTarget) + .map(_.getOrElse(kind, Seq.empty[ReferenceTarget])) + .getOrElse(Seq.empty[ReferenceTarget]) + .toSeq } } @@ -181,7 +222,7 @@ class IRLookup private[analyses](private val declarations: Map[ModuleTarget, Map def moduleLeafPortTargets(m: ModuleTarget): (Seq[(ReferenceTarget, Type)], Seq[(ReferenceTarget, Type)]) = modules(m).ports.flatMap { case Port(_, name, Output, tpe) => Utils.create_exps(Reference(name, tpe, PortKind, SourceFlow)) - case Port(_, name, Input, tpe) => Utils.create_exps(Reference(name, tpe, PortKind, SinkFlow)) + case Port(_, name, Input, tpe) => Utils.create_exps(Reference(name, tpe, PortKind, SinkFlow)) }.foldLeft((Vector.empty[(ReferenceTarget, Type)], Vector.empty[(ReferenceTarget, Type)])) { case ((inputs, outputs), e) if Utils.flow(e) == SourceFlow => (inputs, outputs :+ (ConnectionGraph.asTarget(m, new TokenTagger())(e), e.tpe)) @@ -189,7 +230,6 @@ class IRLookup private[analyses](private val declarations: Map[ModuleTarget, Map (inputs :+ (ConnectionGraph.asTarget(m, new TokenTagger())(e), e.tpe), outputs) } - /** @param t [[firrtl.annotations.ReferenceTarget]] to be queried. * @return whether a ReferenceTarget is contained in this IRLookup */ @@ -213,10 +253,10 @@ class IRLookup private[analyses](private val declarations: Map[ModuleTarget, Map val all = i.pathAsTargets :+ i.encapsulatingModuleTarget.instOf(i.instance, i.ofModule) all.map { x => declarations.contains(x.moduleTarget) && declarations(x.moduleTarget).contains(x.asReference) && - (declarations(x.moduleTarget)(x.asReference) match { - case DefInstance(_, _, of, _) if of == x.ofModule => validPath(x.ofModuleTarget) - case _ => false - }) + (declarations(x.moduleTarget)(x.asReference) match { + case DefInstance(_, _, of, _) if of == x.ofModule => validPath(x.ofModuleTarget) + case _ => false + }) }.reduce(_ && _) } } @@ -248,17 +288,54 @@ class IRLookup private[analyses](private val declarations: Map[ModuleTarget, Map /** Optionally returns the expression corresponding to the target if contained in the expression cache. */ private def inCache(pathless: ReferenceTarget, flow: Flow): Option[Expression] = { - (flow, - exprCache.getOrElseUpdate(pathless.moduleTarget, mutable.HashMap[(ReferenceTarget, Flow), Expression]()).contains((pathless, SourceFlow)), - exprCache.getOrElseUpdate(pathless.moduleTarget, mutable.HashMap[(ReferenceTarget, Flow), Expression]()).contains((pathless, SinkFlow)), - exprCache.getOrElseUpdate(pathless.moduleTarget, mutable.HashMap[(ReferenceTarget, Flow), Expression]()).contains(pathless, DuplexFlow) + ( + flow, + exprCache + .getOrElseUpdate(pathless.moduleTarget, mutable.HashMap[(ReferenceTarget, Flow), Expression]()) + .contains((pathless, SourceFlow)), + exprCache + .getOrElseUpdate(pathless.moduleTarget, mutable.HashMap[(ReferenceTarget, Flow), Expression]()) + .contains((pathless, SinkFlow)), + exprCache + .getOrElseUpdate(pathless.moduleTarget, mutable.HashMap[(ReferenceTarget, Flow), Expression]()) + .contains(pathless, DuplexFlow) ) match { - case (SourceFlow, true, _, _) => Some(exprCache.getOrElseUpdate(pathless.moduleTarget, mutable.HashMap[(ReferenceTarget, Flow), Expression]())((pathless, flow))) - case (SinkFlow, _, true, _) => Some(exprCache.getOrElseUpdate(pathless.moduleTarget, mutable.HashMap[(ReferenceTarget, Flow), Expression]())((pathless, flow))) - case (DuplexFlow, _, _, true) => Some(exprCache.getOrElseUpdate(pathless.moduleTarget, mutable.HashMap[(ReferenceTarget, Flow), Expression]())((pathless, DuplexFlow))) - case (UnknownFlow, _, _, true) => Some(exprCache.getOrElseUpdate(pathless.moduleTarget, mutable.HashMap[(ReferenceTarget, Flow), Expression]())((pathless, DuplexFlow))) - case (UnknownFlow, true, false, false) => Some(exprCache.getOrElseUpdate(pathless.moduleTarget, mutable.HashMap[(ReferenceTarget, Flow), Expression]())((pathless, SourceFlow))) - case (UnknownFlow, false, true, false) => Some(exprCache.getOrElseUpdate(pathless.moduleTarget, mutable.HashMap[(ReferenceTarget, Flow), Expression]())((pathless, SinkFlow))) + case (SourceFlow, true, _, _) => + Some( + exprCache.getOrElseUpdate(pathless.moduleTarget, mutable.HashMap[(ReferenceTarget, Flow), Expression]())( + (pathless, flow) + ) + ) + case (SinkFlow, _, true, _) => + Some( + exprCache.getOrElseUpdate(pathless.moduleTarget, mutable.HashMap[(ReferenceTarget, Flow), Expression]())( + (pathless, flow) + ) + ) + case (DuplexFlow, _, _, true) => + Some( + exprCache.getOrElseUpdate(pathless.moduleTarget, mutable.HashMap[(ReferenceTarget, Flow), Expression]())( + (pathless, DuplexFlow) + ) + ) + case (UnknownFlow, _, _, true) => + Some( + exprCache.getOrElseUpdate(pathless.moduleTarget, mutable.HashMap[(ReferenceTarget, Flow), Expression]())( + (pathless, DuplexFlow) + ) + ) + case (UnknownFlow, true, false, false) => + Some( + exprCache.getOrElseUpdate(pathless.moduleTarget, mutable.HashMap[(ReferenceTarget, Flow), Expression]())( + (pathless, SourceFlow) + ) + ) + case (UnknownFlow, false, true, false) => + Some( + exprCache.getOrElseUpdate(pathless.moduleTarget, mutable.HashMap[(ReferenceTarget, Flow), Expression]())( + (pathless, SinkFlow) + ) + ) case _ => None } } diff --git a/src/main/scala/firrtl/analyses/InstanceGraph.scala b/src/main/scala/firrtl/analyses/InstanceGraph.scala index f994b39a..4aab9a3a 100644 --- a/src/main/scala/firrtl/analyses/InstanceGraph.scala +++ b/src/main/scala/firrtl/analyses/InstanceGraph.scala @@ -10,7 +10,6 @@ import firrtl.Utils._ import firrtl.traversals.Foreachers._ import firrtl.annotations.TargetToken._ - /** A class representing the instance hierarchy of a working IR Circuit * * @constructor constructs an instance graph from a Circuit @@ -29,7 +28,7 @@ import firrtl.annotations.TargetToken._ class InstanceGraph(c: Circuit) { @deprecated("Use InstanceKeyGraph.moduleMap instead.", "FIRRTL 1.4") - val moduleMap = c.modules.map({m => (m.name,m) }).toMap + val moduleMap = c.modules.map({ m => (m.name, m) }).toMap private val instantiated = new mutable.LinkedHashSet[String] private val childInstances = new mutable.LinkedHashMap[String, mutable.LinkedHashSet[DefInstance]] @@ -43,7 +42,7 @@ class InstanceGraph(c: Circuit) { private val instanceQueue = new mutable.Queue[DefInstance] for (subTop <- c.modules.view.map(_.name).filterNot(instantiated)) { - val topInstance = DefInstance(subTop,subTop) + val topInstance = DefInstance(subTop, subTop) instanceQueue.enqueue(topInstance) while (instanceQueue.nonEmpty) { val current = instanceQueue.dequeue @@ -53,7 +52,7 @@ class InstanceGraph(c: Circuit) { instanceQueue.enqueue(child) instanceGraph.addVertex(child) } - instanceGraph.addEdge(current,child) + instanceGraph.addEdge(current, child) } } } @@ -73,7 +72,7 @@ class InstanceGraph(c: Circuit) { * of all module instances in the Circuit. */ @deprecated("Use InstanceKeyGraph.fullHierarchy instead.", "FIRRTL 1.4") - lazy val fullHierarchy: mutable.LinkedHashMap[DefInstance,Seq[Seq[DefInstance]]] = graph.pathsInDAG(trueTopInstance) + lazy val fullHierarchy: mutable.LinkedHashMap[DefInstance, Seq[Seq[DefInstance]]] = graph.pathsInDAG(trueTopInstance) /** A count of the *static* number of instances of each module. For any module other than the top (main) module, this is * equivalent to the number of inst statements in the circuit instantiating each module, irrespective of the number @@ -85,7 +84,7 @@ class InstanceGraph(c: Circuit) { lazy val staticInstanceCount: Map[OfModule, Int] = { val foo = mutable.LinkedHashMap.empty[OfModule, Int] childInstances.keys.foreach { - case main if main == c.main => foo += main.OfModule -> 1 + case main if main == c.main => foo += main.OfModule -> 1 case other => foo += other.OfModule -> 0 } childInstances.values.flatten.map(_.OfModule).foreach { @@ -106,7 +105,7 @@ class InstanceGraph(c: Circuit) { @deprecated("Use InstanceKeyGraph.findInstancesInHierarchy instead (now with caching of vertices!).", "FIRRTL 1.4") def findInstancesInHierarchy(module: String): Seq[Seq[DefInstance]] = { val instances = graph.getVertices.filter(_.module == module).toSeq - instances flatMap { i => fullHierarchy.getOrElse(i, Nil) } + instances.flatMap { i => fullHierarchy.getOrElse(i, Nil) } } /** An [[firrtl.graph.EulerTour EulerTour]] representation of the [[firrtl.graph.DiGraph DiGraph]] */ @@ -117,8 +116,7 @@ class InstanceGraph(c: Circuit) { * a design */ @deprecated("Use InstanceKeyGraph and EulerTour(iGraph.graph, iGraph.top).rmq(moduleA, moduleB).", "FIRRTL 1.4") - def lowestCommonAncestor(moduleA: Seq[DefInstance], - moduleB: Seq[DefInstance]): Seq[DefInstance] = { + def lowestCommonAncestor(moduleA: Seq[DefInstance], moduleB: Seq[DefInstance]): Seq[DefInstance] = { tour.rmq(moduleA, moduleB) } @@ -131,10 +129,9 @@ class InstanceGraph(c: Circuit) { graph.transformNodes(_.module).linearize.map(moduleMap(_)) } - /** Given a circuit, returns a map from module name to children - * instance/module definitions - */ + * instance/module definitions + */ @deprecated("Use InstanceKeyGraph.getChildInstances instead.", "FIRRTL 1.4") def getChildrenInstances: mutable.LinkedHashMap[String, mutable.LinkedHashSet[DefInstance]] = childInstances @@ -172,7 +169,7 @@ class InstanceGraph(c: Circuit) { /** The set of all modules *not* reachable in the circuit */ @deprecated("Use InstanceKeyGraph.unreachableModules instead.", "FIRRTL 1.4") - lazy val unreachableModules: collection.Set[OfModule] = modules diff reachableModules + lazy val unreachableModules: collection.Set[OfModule] = modules.diff(reachableModules) } @@ -186,10 +183,9 @@ object InstanceGraph { * @return */ @deprecated("Use InstanceKeyGraph.collectInstances instead.", "FIRRTL 1.4") - def collectInstances(insts: mutable.Set[DefInstance]) - (s: Statement): Unit = s match { - case i: DefInstance => insts += i - case i: DefInstance => throwInternalError("Expecting DefInstance, found a DefInstance!") + def collectInstances(insts: mutable.Set[DefInstance])(s: Statement): Unit = s match { + case i: DefInstance => insts += i + case i: DefInstance => throwInternalError("Expecting DefInstance, found a DefInstance!") case i: WDefInstanceConnector => throwInternalError("Expecting DefInstance, found a DefInstanceConnector!") case _ => s.foreach(collectInstances(insts)) } diff --git a/src/main/scala/firrtl/analyses/InstanceKeyGraph.scala b/src/main/scala/firrtl/analyses/InstanceKeyGraph.scala index 761315dc..5354888d 100644 --- a/src/main/scala/firrtl/analyses/InstanceKeyGraph.scala +++ b/src/main/scala/firrtl/analyses/InstanceKeyGraph.scala @@ -14,10 +14,10 @@ import scala.collection.mutable * pairs of InstanceName and Module name as vertex keys instead of using WDefInstance * which will hash the instance type causing some performance issues. */ -class InstanceKeyGraph private(c: ir.Circuit) { +class InstanceKeyGraph private (c: ir.Circuit) { import InstanceKeyGraph._ - private val nameToModule: Map[String, ir.DefModule] = c.modules.map({m => (m.name,m) }).toMap + private val nameToModule: Map[String, ir.DefModule] = c.modules.map({ m => (m.name, m) }).toMap private val childInstances: Seq[(String, Seq[InstanceKey])] = c.modules.map { m => m.name -> InstanceKeyGraph.collectInstances(m) } @@ -37,8 +37,8 @@ class InstanceKeyGraph private(c: ir.Circuit) { circuitTopInstance.OfModule +: internalGraph.reachableFrom(circuitTopInstance).toSeq.map(_.OfModule) private lazy val cachedUnreachableModules: Seq[OfModule] = { - val all = mutable.LinkedHashSet(childInstances.map(c => OfModule(c._1)):_*) - val reachable = mutable.LinkedHashSet(cachedReachableModules:_*) + val all = mutable.LinkedHashSet(childInstances.map(c => OfModule(c._1)): _*) + val reachable = mutable.LinkedHashSet(cachedReachableModules: _*) all.diff(reachable).toSeq } @@ -68,11 +68,11 @@ class InstanceKeyGraph private(c: ir.Circuit) { private lazy val cachedStaticInstanceCount = { val foo = mutable.LinkedHashMap.empty[OfModule, Int] childInstances.foreach { - case (main, _) if main == c.main => foo += main.OfModule -> 1 + case (main, _) if main == c.main => foo += main.OfModule -> 1 case (other, _) => foo += other.OfModule -> 0 } - childInstances.flatMap(_._2).map(_.OfModule).foreach { - mod => foo += mod -> (foo(mod) + 1) + childInstances.flatMap(_._2).map(_.OfModule).foreach { mod => + foo += mod -> (foo(mod) + 1) } foo.toMap } @@ -88,17 +88,18 @@ class InstanceKeyGraph private(c: ir.Circuit) { */ def findInstancesInHierarchy(module: String): Seq[Seq[InstanceKey]] = { val instances = vertices.filter(_.module == module).toSeq - instances.flatMap{ i => cachedFullHierarchy.getOrElse(i, Nil) } + instances.flatMap { i => cachedFullHierarchy.getOrElse(i, Nil) } } /** Given a circuit, returns a map from module name to a map * in turn mapping instances names to corresponding module names */ def getChildInstanceMap: mutable.LinkedHashMap[OfModule, mutable.LinkedHashMap[Instance, OfModule]] = - mutable.LinkedHashMap(childInstances.map { case (k, v) => - val moduleMap: mutable.LinkedHashMap[Instance, OfModule] = mutable.LinkedHashMap(v.map(_.toTokens):_*) - TargetToken.OfModule(k) -> moduleMap - }:_*) + mutable.LinkedHashMap(childInstances.map { + case (k, v) => + val moduleMap: mutable.LinkedHashMap[Instance, OfModule] = mutable.LinkedHashMap(v.map(_.toTokens): _*) + TargetToken.OfModule(k) -> moduleMap + }: _*) /** All modules in the circuit reachable from the top module */ def reachableModules: Seq[OfModule] = cachedReachableModules @@ -110,7 +111,6 @@ class InstanceKeyGraph private(c: ir.Circuit) { def fullHierarchy: mutable.LinkedHashMap[InstanceKey, Seq[Seq[InstanceKey]]] = cachedFullHierarchy } - object InstanceKeyGraph { def apply(c: ir.Circuit): InstanceKeyGraph = new InstanceKeyGraph(c) @@ -126,12 +126,12 @@ object InstanceKeyGraph { /** Finds all instance definitions in a firrtl Module. */ def collectInstances(m: ir.DefModule): Seq[InstanceKey] = m match { - case _ : ir.ExtModule => Seq() + case _: ir.ExtModule => Seq() case ir.Module(_, _, _, body) => { val instances = mutable.ArrayBuffer[InstanceKey]() def onStmt(s: ir.Statement): Unit = s match { case firrtl.WDefInstance(_, name, module, _) => instances += InstanceKey(name, module) - case ir.DefInstance(_, name, module, _) => instances += InstanceKey(name, module) + case ir.DefInstance(_, name, module, _) => instances += InstanceKey(name, module) case _: firrtl.WDefInstanceConnector => firrtl.Utils.throwInternalError("Expecting WDefInstance, found a WDefInstanceConnector!") case other => other.foreachStmt(onStmt) @@ -143,8 +143,10 @@ object InstanceKeyGraph { private def topKey(module: String): InstanceKey = InstanceKey(module, module) - private def buildGraph(childInstances: Seq[(String, Seq[InstanceKey])], roots: Iterable[String]): - DiGraph[InstanceKey] = { + private def buildGraph( + childInstances: Seq[(String, Seq[InstanceKey])], + roots: Iterable[String] + ): DiGraph[InstanceKey] = { val instanceGraph = new MutableDiGraph[InstanceKey] val childInstanceMap = childInstances.toMap diff --git a/src/main/scala/firrtl/analyses/NodeCount.scala b/src/main/scala/firrtl/analyses/NodeCount.scala index 0276f4f5..63571503 100644 --- a/src/main/scala/firrtl/analyses/NodeCount.scala +++ b/src/main/scala/firrtl/analyses/NodeCount.scala @@ -21,18 +21,19 @@ class NodeCount private (node: FirrtlNode) { @tailrec private final def rec(xs: List[Any]): Unit = - if (xs.isEmpty) { } - else { + if (xs.isEmpty) {} else { val node = xs.head - require(node.isInstanceOf[Product] || !node.isInstanceOf[FirrtlNode], - "Unexpected FirrtlNode that does not implement Product!") + require( + node.isInstanceOf[Product] || !node.isInstanceOf[FirrtlNode], + "Unexpected FirrtlNode that does not implement Product!" + ) val moreToVisit = if (identityMap.containsKey(node)) List.empty else { // Haven't seen yet identityMap.put(node, true) regularSet += node node match { // FirrtlNodes are Products - case p: Product => p.productIterator + case p: Product => p.productIterator case i: Iterable[Any] => i case _ => List.empty } diff --git a/src/main/scala/firrtl/analyses/SymbolTable.scala b/src/main/scala/firrtl/analyses/SymbolTable.scala index 53ad1614..36549160 100644 --- a/src/main/scala/firrtl/analyses/SymbolTable.scala +++ b/src/main/scala/firrtl/analyses/SymbolTable.scala @@ -17,26 +17,27 @@ import scala.collection.mutable * Different implementations of SymbolTable might want to store different * information (e.g., only the names without the types) or build * different indices depending on what information the transform needs. - * */ + */ trait SymbolTable { // methods that need to be implemented by any Symbol table - def declare(name: String, tpe: Type, kind: Kind): Unit + def declare(name: String, tpe: Type, kind: Kind): Unit def declareInstance(name: String, module: String): Unit // convenience methods def declare(d: DefInstance): Unit = declareInstance(d.name, d.module) - def declare(d: DefMemory): Unit = declare(d.name, MemPortUtils.memType(d), firrtl.MemKind) - def declare(d: DefNode): Unit = declare(d.name, d.value.tpe, firrtl.NodeKind) - def declare(d: DefWire): Unit = declare(d.name, d.tpe, firrtl.WireKind) + def declare(d: DefMemory): Unit = declare(d.name, MemPortUtils.memType(d), firrtl.MemKind) + def declare(d: DefNode): Unit = declare(d.name, d.value.tpe, firrtl.NodeKind) + def declare(d: DefWire): Unit = declare(d.name, d.tpe, firrtl.WireKind) def declare(d: DefRegister): Unit = declare(d.name, d.tpe, firrtl.RegKind) - def declare(d: Port): Unit = declare(d.name, d.tpe, firrtl.PortKind) + def declare(d: Port): Unit = declare(d.name, d.tpe, firrtl.PortKind) } /** Trusts the type annotation on DefInstance nodes instead of re-deriving the type from - * the module ports which would require global (cross-module) information. */ + * the module ports which would require global (cross-module) information. + */ private[firrtl] abstract class LocalSymbolTable extends SymbolTable { def declareInstance(name: String, module: String): Unit = declare(name, UnknownType, InstanceKind) - override def declare(d: WDefInstance): Unit = declare(d.name, d.tpe, InstanceKind) + override def declare(d: WDefInstance): Unit = declare(d.name, d.tpe, InstanceKind) } /** Uses a function to derive instance types from module names */ @@ -63,10 +64,10 @@ private[firrtl] trait WithMap extends SymbolTable { } private case class Sym(name: String, tpe: Type, kind: Kind) extends Symbol -private[firrtl] trait Symbol { def name: String; def tpe: Type; def kind: Kind } +private[firrtl] trait Symbol { def name: String; def tpe: Type; def kind: Kind } /** only remembers the names of symbols */ -private[firrtl] class NamespaceTable extends LocalSymbolTable { +private[firrtl] class NamespaceTable extends LocalSymbolTable { private var names = List[String]() override def declare(name: String, tpe: Type, kind: Kind): Unit = names = name :: names def getNames: Seq[String] = names @@ -82,9 +83,9 @@ object SymbolTable { } private def scanStatement(s: Statement)(implicit table: SymbolTable): Unit = s match { case d: DefInstance => table.declare(d) - case d: DefMemory => table.declare(d) - case d: DefNode => table.declare(d) - case d: DefWire => table.declare(d) + case d: DefMemory => table.declare(d) + case d: DefNode => table.declare(d) + case d: DefWire => table.declare(d) case d: DefRegister => table.declare(d) case other => other.foreachStmt(scanStatement) } |
