aboutsummaryrefslogtreecommitdiff
path: root/src/main/scala/firrtl/passes/Checks.scala
diff options
context:
space:
mode:
authorJack Koenig2019-02-14 15:08:35 -0800
committerGitHub2019-02-14 15:08:35 -0800
commit2272044c6ab46b5148c39c124e66e1a8e9073a24 (patch)
tree83ad2141b1a3c54707dd9b33073f9217b0ae16c8 /src/main/scala/firrtl/passes/Checks.scala
parentd487b4cb6726e7e8d1a18f894021652594125221 (diff)
Asynchronous Reset (#1011)
Fixes #219 * Adds AsyncResetType (similar to ClockType) * Registers with reset signal of type AsyncResetType are async reset registers * Registers with async reset can only be reset to literal values * Add initialization logic for async reset registers
Diffstat (limited to 'src/main/scala/firrtl/passes/Checks.scala')
-rw-r--r--src/main/scala/firrtl/passes/Checks.scala54
1 files changed, 33 insertions, 21 deletions
diff --git a/src/main/scala/firrtl/passes/Checks.scala b/src/main/scala/firrtl/passes/Checks.scala
index 4b996f5d..b6855d75 100644
--- a/src/main/scala/firrtl/passes/Checks.scala
+++ b/src/main/scala/firrtl/passes/Checks.scala
@@ -53,6 +53,8 @@ object CheckHighForm extends Pass {
s"$info: [module $mname] Primop $op argument $value < 0.")
class LsbLargerThanMsbException(info: Info, mname: String, op: String, lsb: Int, msb: Int) extends PassException(
s"$info: [module $mname] Primop $op lsb $lsb > $msb.")
+ class NonLiteralAsyncResetValueException(info: Info, mname: String, reg: String, init: String) extends PassException(
+ s"$info: [module $mname] AsyncReset Reg '$reg' reset to non-literal '$init'")
def run(c: Circuit): Circuit = {
val errors = new Errors()
@@ -74,7 +76,7 @@ object CheckHighForm extends Pass {
case Add | Sub | Mul | Div | Rem | Lt | Leq | Gt | Geq |
Eq | Neq | Dshl | Dshr | And | Or | Xor | Cat =>
correctNum(Option(2), 0)
- case AsUInt | AsSInt | AsClock | Cvt | Neq | Not =>
+ case AsUInt | AsSInt | AsClock | AsAsyncReset | Cvt | Neq | Not =>
correctNum(Option(1), 0)
case AsFixedPoint | Pad | Head | Tail | BPShl | BPShr | BPSet =>
correctNum(Option(1), 1)
@@ -164,6 +166,13 @@ object CheckHighForm extends Pass {
val info = get_info(s) match {case NoInfo => minfo case x => x}
s foreach checkName(info, mname, names)
s match {
+ case DefRegister(info, name, _,_, reset, init) if reset.tpe == AsyncResetType =>
+ init match {
+ case _: Literal => // okay
+ case nonlit =>
+ val e = new NonLiteralAsyncResetValueException(info, mname, name, nonlit.serialize)
+ errors.append(e)
+ }
case sx: DefMemory =>
if (hasFlip(sx.dataType))
errors.append(new MemWithFlipException(info, mname, sx.name))
@@ -291,41 +300,43 @@ object CheckTypes extends Pass {
case tx => true
}
def check_types_primop(info: Info, mname: String, e: DoPrim): Unit = {
- def checkAllTypes(exprs: Seq[Expression], okUInt: Boolean, okSInt: Boolean, okClock: Boolean, okFix: Boolean): Unit = {
- exprs.foldLeft((false, false, false, false)) {
- case ((isUInt, isSInt, isClock, isFix), expr) => expr.tpe match {
- case u: UIntType => (true, isSInt, isClock, isFix)
- case s: SIntType => (isUInt, true, isClock, isFix)
- case ClockType => (isUInt, isSInt, true, isFix)
- case f: FixedType => (isUInt, isSInt, isClock, true)
- case UnknownType =>
+ def checkAllTypes(exprs: Seq[Expression], okUInt: Boolean, okSInt: Boolean, okClock: Boolean, okFix: Boolean, okAsync: Boolean): Unit = {
+ exprs.foldLeft((false, false, false, false, false)) {
+ case ((isUInt, isSInt, isClock, isFix, isAsync), expr) => expr.tpe match {
+ case u: UIntType => (true, isSInt, isClock, isFix, isAsync)
+ case s: SIntType => (isUInt, true, isClock, isFix, isAsync)
+ case ClockType => (isUInt, isSInt, true, isFix, isAsync)
+ case f: FixedType => (isUInt, isSInt, isClock, true, isAsync)
+ case AsyncResetType => (isUInt, isSInt, isClock, isFix, true)
+ case UnknownType =>
errors.append(new IllegalUnknownType(info, mname, e.serialize))
- (isUInt, isSInt, isClock, isFix)
+ (isUInt, isSInt, isClock, isFix, isAsync)
case other => throwInternalError(s"Illegal Type: ${other.serialize}")
}
} match {
// (UInt, SInt, Clock, Fixed)
- case (isAll, false, false, false) if isAll == okUInt =>
- case (false, isAll, false, false) if isAll == okSInt =>
- case (false, false, isAll, false) if isAll == okClock =>
- case (false, false, false, isAll) if isAll == okFix =>
+ case (isAll, false, false, false, false) if isAll == okUInt =>
+ case (false, isAll, false, false, false) if isAll == okSInt =>
+ case (false, false, isAll, false, false) if isAll == okClock =>
+ case (false, false, false, isAll, false) if isAll == okFix =>
+ case (false, false, false, false, isAll) if isAll == okAsync =>
case x => errors.append(new OpNotCorrectType(info, mname, e.op.serialize, exprs.map(_.tpe.serialize)))
}
}
e.op match {
- case AsUInt | AsSInt | AsClock | AsFixedPoint =>
+ case AsUInt | AsSInt | AsClock | AsFixedPoint | AsAsyncReset =>
// All types are ok
case Dshl | Dshr =>
- checkAllTypes(Seq(e.args.head), okUInt=true, okSInt=true, okClock=false, okFix=true)
- checkAllTypes(Seq(e.args(1)), okUInt=true, okSInt=false, okClock=false, okFix=false)
+ checkAllTypes(Seq(e.args.head), okUInt=true, okSInt=true, okClock=false, okFix=true, okAsync=false)
+ checkAllTypes(Seq(e.args(1)), okUInt=true, okSInt=false, okClock=false, okFix=false, okAsync=false)
case Add | Sub | Mul | Lt | Leq | Gt | Geq | Eq | Neq =>
- checkAllTypes(e.args, okUInt=true, okSInt=true, okClock=false, okFix=true)
+ checkAllTypes(e.args, okUInt=true, okSInt=true, okClock=false, okFix=true, okAsync=false)
case Pad | Shl | Shr | Cat | Bits | Head | Tail =>
- checkAllTypes(e.args, okUInt=true, okSInt=true, okClock=false, okFix=true)
+ checkAllTypes(e.args, okUInt=true, okSInt=true, okClock=false, okFix=true, okAsync=false)
case BPShl | BPShr | BPSet =>
- checkAllTypes(e.args, okUInt=false, okSInt=false, okClock=false, okFix=true)
+ checkAllTypes(e.args, okUInt=false, okSInt=false, okClock=false, okFix=true, okAsync=false)
case _ =>
- checkAllTypes(e.args, okUInt=true, okSInt=true, okClock=false, okFix=false)
+ checkAllTypes(e.args, okUInt=true, okSInt=true, okClock=false, okFix=false, okAsync=false)
}
}
@@ -415,6 +426,7 @@ object CheckTypes extends Pass {
}
sx.reset.tpe match {
case UIntType(IntWidth(w)) if w == 1 =>
+ case AsyncResetType =>
case UIntType(UnknownWidth) => // cannot catch here, though width may ultimately be wrong
case _ => errors.append(new IllegalResetType(info, mname, sx.name))
}