aboutsummaryrefslogtreecommitdiff
path: root/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'src/main')
-rw-r--r--src/main/scala/firrtl/passes/CheckTypes.scala33
1 files changed, 21 insertions, 12 deletions
diff --git a/src/main/scala/firrtl/passes/CheckTypes.scala b/src/main/scala/firrtl/passes/CheckTypes.scala
index f70db148..50fbfc2e 100644
--- a/src/main/scala/firrtl/passes/CheckTypes.scala
+++ b/src/main/scala/firrtl/passes/CheckTypes.scala
@@ -55,9 +55,9 @@ object CheckTypes extends Pass {
class RegReqClk(info: Info, mname: String, name: String)
extends PassException(s"$info: [module $mname] Register $name requires a clock typed signal.")
class EnNotUInt(info: Info, mname: String)
- extends PassException(s"$info: [module $mname] Enable must be a UIntType typed signal.")
+ extends PassException(s"$info: [module $mname] Enable must be a 1-bit UIntType typed signal.")
class PredNotUInt(info: Info, mname: String)
- extends PassException(s"$info: [module $mname] Predicate not a UIntType.")
+ extends PassException(s"$info: [module $mname] Predicate not a 1-bit UIntType.")
class OpNotGround(info: Info, mname: String, op: String)
extends PassException(s"$info: [module $mname] Primop $op cannot operate on non-ground types.")
class OpNotUInt(info: Info, mname: String, op: String, e: String)
@@ -81,7 +81,7 @@ object CheckTypes extends Pass {
class MuxPassiveTypes(info: Info, mname: String)
extends PassException(s"$info: [module $mname] Must mux between passive types.")
class MuxCondUInt(info: Info, mname: String)
- extends PassException(s"$info: [module $mname] A mux condition must be of type UInt.")
+ extends PassException(s"$info: [module $mname] A mux condition must be of type 1-bit UInt.")
class MuxClock(info: Info, mname: String)
extends PassException(s"$info: [module $mname] Firrtl does not support muxing clocks.")
class ValidIfPassiveTypes(info: Info, mname: String)
@@ -120,6 +120,15 @@ object CheckTypes extends Pass {
case _ => false
}
+ private def legalCondType(tpe: Type): Boolean = tpe match {
+ // If width is known, must be 1
+ case UIntType(IntWidth(w)) => w == 1
+ // Unknown width or variable widths (for width inference) are acceptable (checked in later run)
+ case UIntType(_) => true
+ // Any other type is not okay
+ case _ => false
+ }
+
private def bulk_equals(t1: Type, t2: Type, flip1: Orientation, flip2: Orientation): Boolean = {
(t1, t2) match {
case (ClockType, ClockType) => flip1 == flip2
@@ -165,7 +174,8 @@ object CheckTypes extends Pass {
bulk_equals(con.loc.tpe, con.expr.tpe, Default, Default)
//;---------------- Helper Functions --------------
- def ut: UIntType = UIntType(UnknownWidth)
+ private val UIntUnknown = UIntType(UnknownWidth)
+ def ut: UIntType = UIntUnknown
def st: SIntType = SIntType(UnknownWidth)
def run(c: Circuit): Circuit = {
@@ -332,9 +342,8 @@ object CheckTypes extends Pass {
errors.append(new MuxSameType(info, mname, e.tval.tpe.serialize, e.fval.tpe.serialize))
if (!passive(e.tpe))
errors.append(new MuxPassiveTypes(info, mname))
- e.cond.tpe match {
- case _: UIntType =>
- case _ => errors.append(new MuxCondUInt(info, mname))
+ if (!legalCondType(e.cond.tpe)) {
+ errors.append(new MuxCondUInt(info, mname))
}
case (e: ValidIf) =>
if (!passive(e.tpe))
@@ -375,7 +384,7 @@ object CheckTypes extends Pass {
if (sx.clock.tpe != ClockType) {
errors.append(new RegReqClk(info, mname, sx.name))
}
- case sx: Conditionally if wt(sx.pred.tpe) != wt(ut) =>
+ case sx: Conditionally if !legalCondType(sx.pred.tpe) =>
errors.append(new PredNotUInt(info, mname))
case sx: DefNode =>
sx.value.tpe match {
@@ -396,16 +405,16 @@ object CheckTypes extends Pass {
}
case sx: Stop =>
if (wt(sx.clk.tpe) != wt(ClockType)) errors.append(new ReqClk(info, mname))
- if (wt(sx.en.tpe) != wt(ut)) errors.append(new EnNotUInt(info, mname))
+ if (!legalCondType(sx.en.tpe)) errors.append(new EnNotUInt(info, mname))
case sx: Print =>
if (sx.args.exists(x => wt(x.tpe) != wt(ut) && wt(x.tpe) != wt(st)))
errors.append(new PrintfArgNotGround(info, mname))
if (wt(sx.clk.tpe) != wt(ClockType)) errors.append(new ReqClk(info, mname))
- if (wt(sx.en.tpe) != wt(ut)) errors.append(new EnNotUInt(info, mname))
+ if (!legalCondType(sx.en.tpe)) errors.append(new EnNotUInt(info, mname))
case sx: Verification =>
if (wt(sx.clk.tpe) != wt(ClockType)) errors.append(new ReqClk(info, mname))
- if (wt(sx.pred.tpe) != wt(ut)) errors.append(new PredNotUInt(info, mname))
- if (wt(sx.en.tpe) != wt(ut)) errors.append(new EnNotUInt(info, mname))
+ if (!legalCondType(sx.pred.tpe)) errors.append(new PredNotUInt(info, mname))
+ if (!legalCondType(sx.en.tpe)) errors.append(new EnNotUInt(info, mname))
case sx: DefMemory =>
sx.dataType match {
case AnalogType(w) => errors.append(new IllegalAnalogDeclaration(info, mname, sx.name))