diff options
Diffstat (limited to 'src/main/scala/firrtl/analyses/IRLookup.scala')
| -rw-r--r-- | src/main/scala/firrtl/analyses/IRLookup.scala | 189 |
1 files changed, 133 insertions, 56 deletions
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 } } |
