diff options
Diffstat (limited to 'src/main/scala/firrtl/passes/Checks.scala')
| -rw-r--r-- | src/main/scala/firrtl/passes/Checks.scala | 49 |
1 files changed, 37 insertions, 12 deletions
diff --git a/src/main/scala/firrtl/passes/Checks.scala b/src/main/scala/firrtl/passes/Checks.scala index c1415b19..471fe216 100644 --- a/src/main/scala/firrtl/passes/Checks.scala +++ b/src/main/scala/firrtl/passes/Checks.scala @@ -9,7 +9,7 @@ import firrtl.Utils._ import firrtl.traversals.Foreachers._ import firrtl.WrappedType._ -object CheckHighForm extends Pass { +trait CheckHighFormLike { type NameSet = collection.mutable.HashSet[String] // Custom Exceptions @@ -23,6 +23,8 @@ object CheckHighForm extends Pass { s"$info: [module $mname] Reference $name is not declared.") class PoisonWithFlipException(info: Info, mname: String, name: String) extends PassException( s"$info: [module $mname] Poison $name cannot be a bundle type with flips.") + class IllegalChirrtlMemException(info: Info, mname: String, name: String) extends PassException( + s"$info: [module $mname] Memory $name has not been properly lowered from Chirrtl IR.") class MemWithFlipException(info: Info, mname: String, name: String) extends PassException( s"$info: [module $mname] Memory $name cannot be a bundle type with flips.") class RegWithFlipException(info: Info, mname: String, name: String) extends PassException( @@ -58,6 +60,9 @@ object CheckHighForm extends Pass { class NonLiteralAsyncResetValueException(info: Info, mname: String, reg: String, init: String) extends PassException( s"$info: [module $mname] AsyncReset Reg '$reg' reset to non-literal '$init'") + // Is Chirrtl allowed for this check? If not, return an error + def errorOnChirrtl(info: Info, mname: String, s: Statement): Option[PassException] + def run(c: Circuit): Circuit = { val errors = new Errors() val moduleGraph = new ModuleGraph @@ -84,9 +89,8 @@ object CheckHighForm extends Pass { correctNum(Option(1), 1) case Shl | Shr => correctNum(Option(1), 1) - val amount = e.consts.head.toInt - if (amount < 0) { - errors.append(new NegArgException(info, mname, e.op.toString, amount)) + val amount = e.consts.map(_.toInt).filter(_ < 0).foreach { + c => errors.append(new NegArgException(info, mname, e.op.toString, c)) } case Bits => correctNum(Option(1), 2) @@ -137,6 +141,7 @@ object CheckHighForm extends Pass { def validSubexp(info: Info, mname: String)(e: Expression): Unit = { e match { + case _: Reference | _: SubField | _: SubIndex | _: SubAccess => // No error case _: WRef | _: WSubField | _: WSubIndex | _: WSubAccess | _: Mux | _: ValidIf => // No error case _ => errors.append(new InvalidAccessException(info, mname)) } @@ -144,12 +149,15 @@ object CheckHighForm extends Pass { def checkHighFormE(info: Info, mname: String, names: NameSet)(e: Expression): Unit = { e match { + case ex: Reference if !names(ex.name) => + errors.append(new UndeclaredReferenceException(info, mname, ex.name)) case ex: WRef if !names(ex.name) => errors.append(new UndeclaredReferenceException(info, mname, ex.name)) case ex: UIntLiteral if ex.value < 0 => errors.append(new NegUIntException(info, mname)) case ex: DoPrim => checkHighFormPrimop(info, mname, ex) - case _: WRef | _: UIntLiteral | _: Mux | _: ValidIf => + case _: Reference | _: WRef | _: UIntLiteral | _: Mux | _: ValidIf => + case ex: SubAccess => validSubexp(info, mname)(ex.expr) case ex: WSubAccess => validSubexp(info, mname)(ex.expr) case ex => ex foreach validSubexp(info, mname) } @@ -164,6 +172,15 @@ object CheckHighForm extends Pass { names += name } + def checkInstance(info: Info, child: String, parent: String): Unit = { + if (!moduleNames(child)) + errors.append(new ModuleNotDefinedException(info, parent, child)) + // Check to see if a recursive module instantiation has occured + val childToParent = moduleGraph add (parent, child) + if (childToParent.nonEmpty) + errors.append(new InstanceLoop(info, parent, childToParent mkString "->")) + } + def checkHighFormS(minfo: Info, mname: String, names: NameSet)(s: Statement): Unit = { val info = get_info(s) match {case NoInfo => minfo case x => x} s foreach checkName(info, mname, names) @@ -178,16 +195,12 @@ object CheckHighForm extends Pass { errors.append(new MemWithFlipException(info, mname, sx.name)) if (sx.depth <= 0) errors.append(new NegMemSizeException(info, mname)) - case sx: WDefInstance => - if (!moduleNames(sx.module)) - errors.append(new ModuleNotDefinedException(info, mname, sx.module)) - // Check to see if a recursive module instantiation has occured - val childToParent = moduleGraph add (mname, sx.module) - if (childToParent.nonEmpty) - errors.append(new InstanceLoop(info, mname, childToParent mkString "->")) + case sx: DefInstance => checkInstance(info, mname, sx.module) + case sx: WDefInstance => checkInstance(info, mname, sx.module) case sx: Connect => checkValidLoc(info, mname, sx.loc) case sx: PartialConnect => checkValidLoc(info, mname, sx.loc) case sx: Print => checkFstring(info, mname, sx.string, sx.args.length) + case _: CDefMemory | _: CDefMPort => errorOnChirrtl(info, mname, s).foreach { e => errors.append(e) } case sx => // Do Nothing } s foreach checkHighFormT(info, mname) @@ -219,6 +232,18 @@ object CheckHighForm extends Pass { } } +object CheckHighForm extends Pass with CheckHighFormLike { + class IllegalChirrtlMemException(info: Info, mname: String, name: String) extends PassException( + s"$info: [module $mname] Memory $name has not been properly lowered from Chirrtl IR.") + + def errorOnChirrtl(info: Info, mname: String, s: Statement): Option[PassException] = { + val memName = s match { + case cm: CDefMemory => cm.name + case cp: CDefMPort => cp.mem + } + Some(new IllegalChirrtlMemException(info, mname, memName)) + } +} object CheckTypes extends Pass { // Custom Exceptions |
