aboutsummaryrefslogtreecommitdiff
path: root/src/main/scala/firrtl/Utils.scala
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/scala/firrtl/Utils.scala')
-rw-r--r--src/main/scala/firrtl/Utils.scala48
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 {