diff options
| author | Adam Izraelevitz | 2018-02-22 17:25:55 -0800 |
|---|---|---|
| committer | GitHub | 2018-02-22 17:25:55 -0800 |
| commit | 46b78943a726e4c9bf85ffb25a2ccf926b10dda7 (patch) | |
| tree | 39f9363400fdd39e2e55f3dc8c5221461941edec /src/main/scala/firrtl/Utils.scala | |
| parent | 65bbf155003a86cd836f7ff4a2def6af91794780 (diff) | |
Add tests for #702. Adds Utility functions. Allows clock muxing in FIRRTL, but not Emitter. (#717)
Diffstat (limited to 'src/main/scala/firrtl/Utils.scala')
| -rw-r--r-- | src/main/scala/firrtl/Utils.scala | 123 |
1 files changed, 42 insertions, 81 deletions
diff --git a/src/main/scala/firrtl/Utils.scala b/src/main/scala/firrtl/Utils.scala index e5a7e6be..0c684c5d 100644 --- a/src/main/scala/firrtl/Utils.scala +++ b/src/main/scala/firrtl/Utils.scala @@ -226,6 +226,10 @@ object Utils extends LazyLogging { case SIntLiteral(value, _) => "_" + value } } + /** Maps node name to value */ + type NodeMap = mutable.HashMap[String, Expression] + + def isTemp(str: String): Boolean = str.head == '_' /** Indent the results of [[ir.FirrtlNode.serialize]] */ def indent(str: String) = str replaceAllLiterally ("\n", "\n ") @@ -306,88 +310,45 @@ object Utils extends LazyLogging { case _ => false } -//============== TYPES ================ -//<<<<<<< HEAD -// def mux_type (e1:Expression,e2:Expression) : Type = mux_type(tpe(e1),tpe(e2)) -// def mux_type (t1:Type,t2:Type) : Type = { -// if (wt(t1) == wt(t2)) { -// (t1,t2) match { -// case (t1:UIntType,t2:UIntType) => UIntType(UnknownWidth) -// case (t1:SIntType,t2:SIntType) => SIntType(UnknownWidth) -// case (t1:FixedType,t2:FixedType) => FixedType(UnknownWidth, UnknownWidth) -// case (t1:VectorType,t2:VectorType) => VectorType(mux_type(t1.tpe,t2.tpe),t1.size) -// case (t1:BundleType,t2:BundleType) => -// BundleType((t1.fields,t2.fields).zipped.map((f1,f2) => { -// Field(f1.name,f1.flip,mux_type(f1.tpe,f2.tpe)) -// })) -// } -// } else UnknownType -// } -// def mux_type_and_widths (e1:Expression,e2:Expression) : Type = mux_type_and_widths(tpe(e1),tpe(e2)) -// def PLUS (w1:Width,w2:Width) : Width = (w1, w2) match { -// case (IntWidth(i), IntWidth(j)) => IntWidth(i + j) -// case _ => PlusWidth(w1,w2) -// } -// def MAX (w1:Width,w2:Width) : Width = (w1, w2) match { -// case (IntWidth(i), IntWidth(j)) => IntWidth(max(i,j)) -// case _ => MaxWidth(Seq(w1,w2)) -// } -// def MINUS (w1:Width,w2:Width) : Width = (w1, w2) match { -// case (IntWidth(i), IntWidth(j)) => IntWidth(i - j) -// case _ => MinusWidth(w1,w2) -// } -// def POW (w1:Width) : Width = w1 match { -// case IntWidth(i) => IntWidth(pow_minus_one(BigInt(2), i)) -// case _ => ExpWidth(w1) -// } -// def MIN (w1:Width,w2:Width) : Width = (w1, w2) match { -// case (IntWidth(i), IntWidth(j)) => IntWidth(min(i,j)) -// case _ => MinWidth(Seq(w1,w2)) -// } -// def mux_type_and_widths (t1:Type,t2:Type) : Type = { -// def wmax (w1:Width,w2:Width) : Width = { -// (w1,w2) match { -// case (w1:IntWidth,w2:IntWidth) => IntWidth(w1.width.max(w2.width)) -// case (w1,w2) => MaxWidth(Seq(w1,w2)) -// } -// } -// val wt1 = new WrappedType(t1) -// val wt2 = new WrappedType(t2) -// if (wt1 == wt2) { -// (t1,t2) match { -// case (t1:UIntType,t2:UIntType) => UIntType(wmax(t1.width,t2.width)) -// case (t1:SIntType,t2:SIntType) => SIntType(wmax(t1.width,t2.width)) -// case (FixedType(w1, p1), FixedType(w2, p2)) => -// FixedType(PLUS(MAX(p1, p2),MAX(MINUS(w1, p1), MINUS(w2, p2))), MAX(p1, p2)) -// case (t1:VectorType,t2:VectorType) => VectorType(mux_type_and_widths(t1.tpe,t2.tpe),t1.size) -// case (t1:BundleType,t2:BundleType) => BundleType((t1.fields zip t2.fields).map{case (f1, f2) => Field(f1.name,f1.flip,mux_type_and_widths(f1.tpe,f2.tpe))}) -// } -// } else UnknownType -// } -// def module_type (m:DefModule) : Type = { -// BundleType(m.ports.map(p => p.toField)) -// } -// def sub_type (v:Type) : Type = { -// v match { -// case v:VectorType => v.tpe -// case v => UnknownType -// } -// } -// def field_type (v:Type,s:String) : Type = { -// v match { -// case v:BundleType => { -// val ft = v.fields.find(p => p.name == s) -// ft match { -// case ft:Some[Field] => ft.get.tpe -// case ft => UnknownType -// } -// } -// case v => UnknownType -// } -// } -//======= + /** Returns children Expressions of e */ + def getKids(e: Expression): Seq[Expression] = { + val kids = mutable.ArrayBuffer[Expression]() + def addKids(e: Expression): Expression = { + kids += e + e + } + e map addKids + kids + } + + /** Walks two expression trees and returns a sequence of tuples of where they differ */ + def diff(e1: Expression, e2: Expression): Seq[(Expression, Expression)] = { + if(weq(e1, e2)) Nil + else { + val (e1Kids, e2Kids) = (getKids(e1), getKids(e2)) + + if(e1Kids == Nil || e2Kids == Nil || e1Kids.size != e2Kids.size) Seq((e1, e2)) + else { + e1Kids.zip(e2Kids).flatMap { case (e1k, e2k) => diff(e1k, e2k) } + } + } + } + + /** Returns an inlined expression (replacing node references with values), + * stopping on a stopping condition or until the reference is not a node + */ + def inline(nodeMap: NodeMap, stop: String => Boolean = {x: String => false})(e: Expression): Expression = { + def onExp(e: Expression): Expression = e map onExp match { + case Reference(name, _) if nodeMap.contains(name) && !stop(name) => onExp(nodeMap(name)) + case WRef(name, _, _, _) if nodeMap.contains(name) && !stop(name) => onExp(nodeMap(name)) + case other => other + } + onExp(e) + } + def mux_type(e1: Expression, e2: Expression): Type = mux_type(e1.tpe, e2.tpe) def mux_type(t1: Type, t2: Type): Type = (t1, t2) match { + case (ClockType, ClockType) => ClockType case (t1: UIntType, t2: UIntType) => UIntType(UnknownWidth) case (t1: SIntType, t2: SIntType) => SIntType(UnknownWidth) case (t1: FixedType, t2: FixedType) => FixedType(UnknownWidth, UnknownWidth) @@ -405,6 +366,7 @@ object Utils extends LazyLogging { case (w1x, w2x) => MaxWidth(Seq(w1x, w2x)) } (t1, t2) match { + case (ClockType, ClockType) => ClockType case (t1x: UIntType, t2x: UIntType) => UIntType(wmax(t1x.width, t2x.width)) case (t1x: SIntType, t2x: SIntType) => SIntType(wmax(t1x.width, t2x.width)) case (FixedType(w1, p1), FixedType(w2, p2)) => @@ -432,7 +394,6 @@ object Utils extends LazyLogging { } case vx => UnknownType } -//>>>>>>> e54fb610c6bf0a7fe5c9c0f0e0b3acbb3728cfd0 // ================================= def error(str: String, cause: Throwable = null) = throw new FIRRTLException(str, cause) |
