diff options
| author | Adam Izraelevitz | 2016-06-09 12:53:48 -0700 |
|---|---|---|
| committer | GitHub | 2016-06-09 12:53:48 -0700 |
| commit | 71e1bc9b96507a3346c96f8ea17b00aa42ea1775 (patch) | |
| tree | 8e985e37534ad30a5d01629d2225ff886bea5855 /src/main/scala/firrtl/passes | |
| parent | 4562e2cb8468d7021320754aeaff395de1a22206 (diff) | |
| parent | cc4e7e39ebad106ff72f7ac97dcdc99048ee5347 (diff) | |
Merge branch 'master' into fix-warning
Diffstat (limited to 'src/main/scala/firrtl/passes')
| -rw-r--r-- | src/main/scala/firrtl/passes/Checks.scala | 41 | ||||
| -rw-r--r-- | src/main/scala/firrtl/passes/Passes.scala | 74 |
2 files changed, 42 insertions, 73 deletions
diff --git a/src/main/scala/firrtl/passes/Checks.scala b/src/main/scala/firrtl/passes/Checks.scala index 083a18fd..23613e65 100644 --- a/src/main/scala/firrtl/passes/Checks.scala +++ b/src/main/scala/firrtl/passes/Checks.scala @@ -45,7 +45,6 @@ object CheckHighForm extends Pass with LazyLogging { // Custom Exceptions class NotUniqueException(name: String) extends PassException(s"${sinfo}: [module ${mname}] Reference ${name} does not have a unique name.") - class IsPrefixException(prefix: String) extends PassException(s"${sinfo}: [module ${mname}] Symbol ${prefix} is a prefix.") class InvalidLOCException extends PassException(s"${sinfo}: [module ${mname}] Invalid connect to an expression that is not a reference or a WritePort.") class NegUIntException extends PassException(s"${sinfo}: [module ${mname}] UIntValue cannot be negative.") class UndeclaredReferenceException(name: String) extends PassException(s"${sinfo}: [module ${mname}] Reference ${name} is not declared.") @@ -63,35 +62,6 @@ object CheckHighForm extends Pass with LazyLogging { class BadPrintfTrailingException extends PassException(s"${sinfo}: [module ${mname}] Bad printf format: trailing " + "\"%\"") class BadPrintfIncorrectNumException extends PassException(s"${sinfo}: [module ${mname}] Bad printf format: incorrect number of arguments") - // Trie Datastructure for prefix checking - case class Trie(var children: HashMap[String, Trie], var end: Boolean) { - def empty: Boolean = children.isEmpty - def add(ls: Seq[String]): Boolean = { - var t: Trie = this - var sawEnd = false - for (x <- ls) { - if (t.end) sawEnd = true - if (t.contains(x)) t = t.children(x) - else { - val temp = new Trie(HashMap[String,Trie](),false) - t.children(x) = temp - t = temp - } - } - t.end = true - sawEnd | !t.empty - } - def contains(s: String): Boolean = children.contains(s) - def contains(ls: Seq[String]): Boolean = { - var t: Trie = this - for (x <- ls) { - if (t.contains(x)) t = t.children(x) - else return false - } - t.end - } - } - // Utility functions def hasFlip(t: Type): Boolean = { var has = false @@ -202,7 +172,6 @@ object CheckHighForm extends Pass with LazyLogging { def checkHighFormM(m: Module): Module = { val names = HashMap[String, Boolean]() val mnames = HashMap[String, Boolean]() - val tries = Trie(HashMap[String, Trie](),false) def checkHighFormE(e: Expression): Expression = { def validSubexp(e: Expression): Expression = { e match { @@ -232,8 +201,6 @@ object CheckHighForm extends Pass with LazyLogging { def checkName(name: String): String = { if (names.contains(name)) errors.append(new NotUniqueException(name)) else names(name) = true - val ls: Seq[String] = name.split('$') - if (tries.add(ls)) errors.append(new IsPrefixException(name)) name } sinfo = s.getInfo @@ -681,7 +648,9 @@ object CheckWidths extends Pass { def name = "Width Check" var mname = "" class UninferredWidth (info:Info) extends PassException(s"${info} : [module ${mname}] Uninferred width.") - class WidthTooSmall (info:Info,v:String) extends PassException(s"${info} : [module ${mname} Width too small for constant ${v}.") + class WidthTooSmall(info: Info, b: BigInt) extends PassException( + s"$info : [module $mname] Width too small for constant " + + Serialize().serialize(b) + ".") class NegWidthException(info:Info) extends PassException(s"${info}: [module ${mname}] Width cannot be negative or zero.") def run (c:Circuit): Circuit = { val errors = new Errors() @@ -699,7 +668,7 @@ object CheckWidths extends Pass { (e.width) match { case (w:IntWidth) => if (scala.math.max(1,e.value.bitLength) > w.width) { - errors.append(new WidthTooSmall(info, serialize(e.value))) + errors.append(new WidthTooSmall(info, e.value)) } case (w) => errors.append(new UninferredWidth(info)) } @@ -708,7 +677,7 @@ object CheckWidths extends Pass { case (e:SIntValue) => { (e.width) match { case (w:IntWidth) => - if (e.value.bitLength + 1 > w.width) errors.append(new WidthTooSmall(info, serialize(e.value))) + if (e.value.bitLength + 1 > w.width) errors.append(new WidthTooSmall(info, e.value)) case (w) => errors.append(new UninferredWidth(info)) } check_width_w(info)(e.width) diff --git a/src/main/scala/firrtl/passes/Passes.scala b/src/main/scala/firrtl/passes/Passes.scala index c0d5327f..abd758bf 100644 --- a/src/main/scala/firrtl/passes/Passes.scala +++ b/src/main/scala/firrtl/passes/Passes.scala @@ -482,47 +482,47 @@ object InferWidths extends Pass { case (t:ClockType) => IntWidth(1) case (t) => error("No width!"); IntWidth(-1) } } def width_BANG (e:Expression) : Width = width_BANG(tpe(e)) - def reduce_var_widths (c:Circuit,h:LinkedHashMap[String,Width]) : Circuit = { - def evaluate (w:Width) : Width = { - def apply_2 (a:Option[BigInt],b:Option[BigInt], f: (BigInt,BigInt) => BigInt) : Option[BigInt] = { - (a,b) match { - case (a:Some[BigInt],b:Some[BigInt]) => Some(f(a.get,b.get)) - case (a,b) => None } } - def apply_1 (a:Option[BigInt], f: (BigInt) => BigInt) : Option[BigInt] = { - (a) match { - case (a:Some[BigInt]) => Some(f(a.get)) - case (a) => None } } - def apply_l (l:Seq[Option[BigInt]],f:(BigInt,BigInt) => BigInt) : Option[BigInt] = { - if (l.size == 0) Some(BigInt(0)) else apply_2(l.head,apply_l(l.tail,f),f) - } - def max (a:BigInt,b:BigInt) : BigInt = if (a >= b) a else b - def min (a:BigInt,b:BigInt) : BigInt = if (a >= b) b else a - def pow (a:BigInt,b:BigInt) : BigInt = BigInt((scala.math.pow(a.toDouble,b.toDouble) - 1).toLong) - def solve (w:Width) : Option[BigInt] = { - (w) match { - case (w:VarWidth) => { - val wx = h.get(w.name) - (wx) match { - case (wx:Some[Width]) => { - wx.get match { - case (v:VarWidth) => None - case (v) => solve(v) }} - case (None) => None }} - case (w:MaxWidth) => apply_l(w.args.map(solve _),max) - case (w:MinWidth) => apply_l(w.args.map(solve _),min) - case (w:PlusWidth) => apply_2(solve(w.arg1),solve(w.arg2),{_ + _}) - case (w:MinusWidth) => apply_2(solve(w.arg1),solve(w.arg2),{_ - _}) - case (w:ExpWidth) => apply_2(Some(BigInt(2)),solve(w.arg1),pow) - case (w:IntWidth) => Some(w.width) - case (w) => println(w); error("Shouldn't be here"); None; - } + + def reduce_var_widths(c: Circuit, h: LinkedHashMap[String,Width]): Circuit = { + def evaluate(w: Width): Width = { + def map2(a: Option[BigInt], b: Option[BigInt], f: (BigInt,BigInt) => BigInt): Option[BigInt] = + for (a_num <- a; b_num <- b) yield f(a_num, b_num) + def reduceOptions(l: Seq[Option[BigInt]], f: (BigInt,BigInt) => BigInt): Option[BigInt] = + l.reduce(map2(_, _, f)) + + // This function shouldn't be necessary + // Added as protection in case a constraint accidentally uses MinWidth/MaxWidth + // without any actual Widths. This should be elevated to an earlier error + def forceNonEmpty(in: Seq[Option[BigInt]], default: Option[BigInt]): Seq[Option[BigInt]] = + if(in.isEmpty) Seq(default) + else in + + def max(a: BigInt, b: BigInt): BigInt = if (a >= b) a else b + def min(a: BigInt, b: BigInt): BigInt = if (a >= b) b else a + def pow_minus_one(a: BigInt, b: BigInt): BigInt = a.pow(b.toInt) - 1 + + def solve(w: Width): Option[BigInt] = w match { + case (w: VarWidth) => + for{ + v <- h.get(w.name) if !v.isInstanceOf[VarWidth] + result <- solve(v) + } yield result + case (w: MaxWidth) => reduceOptions(forceNonEmpty(w.args.map(solve _), Some(BigInt(0))), max) + case (w: MinWidth) => reduceOptions(forceNonEmpty(w.args.map(solve _), None), min) + case (w: PlusWidth) => map2(solve(w.arg1), solve(w.arg2), {_ + _}) + case (w: MinusWidth) => map2(solve(w.arg1), solve(w.arg2), {_ - _}) + case (w: ExpWidth) => map2(Some(BigInt(2)), solve(w.arg1), pow_minus_one) + case (w: IntWidth) => Some(w.width) + case (w) => println(w); error("Shouldn't be here"); None; } + val s = solve(w) (s) match { - case (s:Some[BigInt]) => IntWidth(s.get) - case (s) => w } + case Some(s) => IntWidth(s) + case (s) => w + } } - + def reduce_var_widths_w (w:Width) : Width = { //println-all-debug(["REPLACE: " w]) val wx = evaluate(w) |
