diff options
Diffstat (limited to 'src/main/scala/firrtl/Utils.scala')
| -rw-r--r-- | src/main/scala/firrtl/Utils.scala | 48 |
1 files changed, 45 insertions, 3 deletions
diff --git a/src/main/scala/firrtl/Utils.scala b/src/main/scala/firrtl/Utils.scala index 32893411..2d1b0b74 100644 --- a/src/main/scala/firrtl/Utils.scala +++ b/src/main/scala/firrtl/Utils.scala @@ -7,11 +7,14 @@ import firrtl.PrimOps._ import firrtl.Mappers._ import firrtl.WrappedExpression._ import firrtl.WrappedType._ + import scala.collection.mutable -import scala.collection.mutable.{StringBuilder, ArrayBuffer, LinkedHashMap, HashMap, HashSet} +import scala.collection.mutable.{ArrayBuffer, HashMap, HashSet, LinkedHashMap, StringBuilder} import scala.util.matching.Regex import java.io.PrintWriter -import logger.LazyLogging + +import firrtl.annotations.{ReferenceTarget, TargetToken} +import _root_.logger.LazyLogging object FIRRTLException { def defaultMessage(message: String, cause: Throwable) = { @@ -178,7 +181,7 @@ object Utils extends LazyLogging { error("Internal Error! %sPlease file an issue at https://github.com/ucb-bar/firrtl/issues".format(string), throwable) } - private[firrtl] def time[R](block: => R): (Double, R) = { + def time[R](block: => R): (Double, R) = { val t0 = System.nanoTime() val result = block val t1 = System.nanoTime() @@ -259,6 +262,45 @@ object Utils extends LazyLogging { exps ++ create_exps(WSubIndex(ex, i, t.tpe,gender(ex)))) } } + + /** Like create_exps, but returns intermediate Expressions as well + * @param e + * @return + */ + def expandRef(e: Expression): Seq[Expression] = e match { + case ex: Mux => + val e1s = expandRef(ex.tval) + val e2s = expandRef(ex.fval) + e1s zip e2s map {case (e1, e2) => + Mux(ex.cond, e1, e2, mux_type_and_widths(e1, e2)) + } + case ex: ValidIf => expandRef(ex.value) map (e1 => ValidIf(ex.cond, e1, e1.tpe)) + case ex => ex.tpe match { + case (_: GroundType) => Seq(ex) + case (t: BundleType) => (t.fields foldLeft Seq[Expression](ex))((exps, f) => + exps ++ create_exps(WSubField(ex, f.name, f.tpe,times(gender(ex), f.flip)))) + case (t: VectorType) => (0 until t.size foldLeft Seq[Expression](ex))((exps, i) => + exps ++ create_exps(WSubIndex(ex, i, t.tpe,gender(ex)))) + } + } + def toTarget(main: String, module: String)(expression: Expression): ReferenceTarget = { + val tokens = mutable.ArrayBuffer[TargetToken]() + var ref = "???" + def onExp(expr: Expression): Expression = { + expr map onExp match { + case e: WRef => ref = e.name + case e: Reference => tokens += TargetToken.Ref(e.name) + case e: WSubField => tokens += TargetToken.Field(e.name) + case e: SubField => tokens += TargetToken.Field(e.name) + case e: WSubIndex => tokens += TargetToken.Index(e.value) + case e: SubIndex => tokens += TargetToken.Index(e.value) + case other => throwInternalError("Cannot call Utils.toTarget on non-referencing expression") + } + expr + } + onExp(expression) + ReferenceTarget(main, module, Nil, ref, tokens) + } def get_flip(t: Type, i: Int, f: Orientation): Orientation = { if (i >= get_size(t)) throwInternalError(s"get_flip: shouldn't be here - $i >= get_size($t)") t match { |
