aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAdam Izraelevitz2016-07-27 13:53:30 -0700
committerGitHub2016-07-27 13:53:30 -0700
commit486cdb5ea4a3450c81231f09488b5b166c363133 (patch)
tree0df3abbd5ee94a1d221b5d798e2722dfe9844028 /src
parent42d38081f19b25ccb78f81f451b58e77b3e96d53 (diff)
parenta6c8493e907dedcbb289f6d4f6323cc26fb1edc0 (diff)
Merge pull request #198 from ucb-bar/add-chirrtl-check
Added a Chirrtl check for undeclared wires, etc.
Diffstat (limited to 'src')
-rw-r--r--src/main/scala/firrtl/LoweringCompilers.scala6
-rw-r--r--src/main/scala/firrtl/PrimOps.scala549
-rw-r--r--src/main/scala/firrtl/Utils.scala22
-rw-r--r--src/main/scala/firrtl/passes/CheckChirrtl.scala166
-rw-r--r--src/main/scala/firrtl/passes/Checks.scala18
-rw-r--r--src/test/scala/firrtlTests/ChirrtlSpec.scala59
6 files changed, 507 insertions, 313 deletions
diff --git a/src/main/scala/firrtl/LoweringCompilers.scala b/src/main/scala/firrtl/LoweringCompilers.scala
index 9a2bc11f..036156dc 100644
--- a/src/main/scala/firrtl/LoweringCompilers.scala
+++ b/src/main/scala/firrtl/LoweringCompilers.scala
@@ -61,6 +61,7 @@ trait SimpleRun extends LazyLogging {
// TODO(izraelevitz): Create RenameMap from RemoveCHIRRTL
class Chisel3ToHighFirrtl () extends Transform with SimpleRun {
val passSeq = Seq(
+ passes.CheckChirrtl,
passes.CInferTypes,
passes.CInferMDir,
passes.RemoveCHIRRTL)
@@ -108,8 +109,9 @@ class HighFirrtlToMiddleFirrtl () extends Transform with SimpleRun {
passes.CheckInitialization,
passes.ResolveKinds,
passes.InferTypes,
- passes.ResolveGenders,
- passes.InferWidths)
+ passes.ResolveGenders)
+ //passes.InferWidths,
+ //passes.CheckWidths)
def execute (circuit: Circuit, annotations: Seq[CircuitAnnotation]): TransformResult =
run(circuit, passSeq)
}
diff --git a/src/main/scala/firrtl/PrimOps.scala b/src/main/scala/firrtl/PrimOps.scala
index 7e8d77db..7d7524f6 100644
--- a/src/main/scala/firrtl/PrimOps.scala
+++ b/src/main/scala/firrtl/PrimOps.scala
@@ -127,279 +127,282 @@ object PrimOps extends LazyLogging {
def w3 () = Utils.widthBANG(a(2).tpe)
def c1 () = IntWidth(c(0))
def c2 () = IntWidth(c(1))
- o match {
- case Add => {
- val t = (t1(),t2()) match {
- case (t1:UIntType, t2:UIntType) => UIntType(PLUS(MAX(w1(),w2()),Utils.ONE))
- case (t1:UIntType, t2:SIntType) => SIntType(PLUS(MAX(w1(),w2()),Utils.ONE))
- case (t1:SIntType, t2:UIntType) => SIntType(PLUS(MAX(w1(),w2()),Utils.ONE))
- case (t1:SIntType, t2:SIntType) => SIntType(PLUS(MAX(w1(),w2()),Utils.ONE))
- case (t1, t2) => UnknownType
- }
- DoPrim(o,a,c,t)
- }
- case Sub => {
- val t = (t1(),t2()) match {
- case (t1:UIntType, t2:UIntType) => SIntType(PLUS(MAX(w1(),w2()),Utils.ONE))
- case (t1:UIntType, t2:SIntType) => SIntType(PLUS(MAX(w1(),w2()),Utils.ONE))
- case (t1:SIntType, t2:UIntType) => SIntType(PLUS(MAX(w1(),w2()),Utils.ONE))
- case (t1:SIntType, t2:SIntType) => SIntType(PLUS(MAX(w1(),w2()),Utils.ONE))
- case (t1, t2) => UnknownType
- }
- DoPrim(o,a,c,t)
- }
- case Mul => {
- val t = (t1(),t2()) match {
- case (t1:UIntType, t2:UIntType) => UIntType(PLUS(w1(),w2()))
- case (t1:UIntType, t2:SIntType) => SIntType(PLUS(w1(),w2()))
- case (t1:SIntType, t2:UIntType) => SIntType(PLUS(w1(),w2()))
- case (t1:SIntType, t2:SIntType) => SIntType(PLUS(w1(),w2()))
- case (t1, t2) => UnknownType
- }
- DoPrim(o,a,c,t)
- }
- case Div => {
- val t = (t1(),t2()) match {
- case (t1:UIntType, t2:UIntType) => UIntType(w1())
- case (t1:UIntType, t2:SIntType) => SIntType(PLUS(w1(),Utils.ONE))
- case (t1:SIntType, t2:UIntType) => SIntType(w1())
- case (t1:SIntType, t2:SIntType) => SIntType(PLUS(w1(),Utils.ONE))
- case (t1, t2) => UnknownType
- }
- DoPrim(o,a,c,t)
- }
- case Rem => {
- val t = (t1(),t2()) match {
- case (t1:UIntType, t2:UIntType) => UIntType(MIN(w1(),w2()))
- case (t1:UIntType, t2:SIntType) => UIntType(MIN(w1(),w2()))
- case (t1:SIntType, t2:UIntType) => SIntType(MIN(w1(),PLUS(w2(),Utils.ONE)))
- case (t1:SIntType, t2:SIntType) => SIntType(MIN(w1(),w2()))
- case (t1, t2) => UnknownType
- }
- DoPrim(o,a,c,t)
- }
- case Lt => {
- val t = (t1(),t2()) match {
- case (t1:UIntType, t2:UIntType) => Utils.BoolType
- case (t1:SIntType, t2:UIntType) => Utils.BoolType
- case (t1:UIntType, t2:SIntType) => Utils.BoolType
- case (t1:SIntType, t2:SIntType) => Utils.BoolType
- case (t1, t2) => UnknownType
- }
- DoPrim(o,a,c,t)
- }
- case Leq => {
- val t = (t1(),t2()) match {
- case (t1:UIntType, t2:UIntType) => Utils.BoolType
- case (t1:SIntType, t2:UIntType) => Utils.BoolType
- case (t1:UIntType, t2:SIntType) => Utils.BoolType
- case (t1:SIntType, t2:SIntType) => Utils.BoolType
- case (t1, t2) => UnknownType
- }
- DoPrim(o,a,c,t)
- }
- case Gt => {
- val t = (t1(),t2()) match {
- case (t1:UIntType, t2:UIntType) => Utils.BoolType
- case (t1:SIntType, t2:UIntType) => Utils.BoolType
- case (t1:UIntType, t2:SIntType) => Utils.BoolType
- case (t1:SIntType, t2:SIntType) => Utils.BoolType
- case (t1, t2) => UnknownType
- }
- DoPrim(o,a,c,t)
- }
- case Geq => {
- val t = (t1(),t2()) match {
- case (t1:UIntType, t2:UIntType) => Utils.BoolType
- case (t1:SIntType, t2:UIntType) => Utils.BoolType
- case (t1:UIntType, t2:SIntType) => Utils.BoolType
- case (t1:SIntType, t2:SIntType) => Utils.BoolType
- case (t1, t2) => UnknownType
- }
- DoPrim(o,a,c,t)
- }
- case Eq => {
- val t = (t1(),t2()) match {
- case (t1:UIntType, t2:UIntType) => Utils.BoolType
- case (t1:SIntType, t2:UIntType) => Utils.BoolType
- case (t1:UIntType, t2:SIntType) => Utils.BoolType
- case (t1:SIntType, t2:SIntType) => Utils.BoolType
- case (t1, t2) => UnknownType
- }
- DoPrim(o,a,c,t)
- }
- case Neq => {
- val t = (t1(),t2()) match {
- case (t1:UIntType, t2:UIntType) => Utils.BoolType
- case (t1:SIntType, t2:UIntType) => Utils.BoolType
- case (t1:UIntType, t2:SIntType) => Utils.BoolType
- case (t1:SIntType, t2:SIntType) => Utils.BoolType
- case (t1, t2) => UnknownType
- }
- DoPrim(o,a,c,t)
- }
- case Pad => {
- val t = (t1()) match {
- case (t1:UIntType) => UIntType(MAX(w1(),c1()))
- case (t1:SIntType) => SIntType(MAX(w1(),c1()))
- case (t1) => UnknownType
- }
- DoPrim(o,a,c,t)
- }
- case AsUInt => {
- val t = (t1()) match {
- case (t1:UIntType) => UIntType(w1())
- case (t1:SIntType) => UIntType(w1())
- case ClockType => UIntType(Utils.ONE)
- case (t1) => UnknownType
- }
- DoPrim(o,a,c,t)
- }
- case AsSInt => {
- val t = (t1()) match {
- case (t1:UIntType) => SIntType(w1())
- case (t1:SIntType) => SIntType(w1())
- case ClockType => SIntType(Utils.ONE)
- case (t1) => UnknownType
- }
- DoPrim(o,a,c,t)
- }
- case AsClock => {
- val t = (t1()) match {
- case (t1:UIntType) => ClockType
- case (t1:SIntType) => ClockType
- case ClockType => ClockType
- case (t1) => UnknownType
- }
- DoPrim(o,a,c,t)
- }
- case Shl => {
- val t = (t1()) match {
- case (t1:UIntType) => UIntType(PLUS(w1(),c1()))
- case (t1:SIntType) => SIntType(PLUS(w1(),c1()))
- case (t1) => UnknownType
- }
- DoPrim(o,a,c,t)
- }
- case Shr => {
- val t = (t1()) match {
- case (t1:UIntType) => UIntType(MAX(MINUS(w1(),c1()),Utils.ONE))
- case (t1:SIntType) => SIntType(MAX(MINUS(w1(),c1()),Utils.ONE))
- case (t1) => UnknownType
- }
- DoPrim(o,a,c,t)
- }
- case Dshl => {
- val t = (t1()) match {
- case (t1:UIntType) => UIntType(PLUS(w1(),POW(w2())))
- case (t1:SIntType) => SIntType(PLUS(w1(),POW(w2())))
- case (t1) => UnknownType
- }
- DoPrim(o,a,c,t)
- }
- case Dshr => {
- val t = (t1()) match {
- case (t1:UIntType) => UIntType(w1())
- case (t1:SIntType) => SIntType(w1())
- case (t1) => UnknownType
- }
- DoPrim(o,a,c,t)
- }
- case Cvt => {
- val t = (t1()) match {
- case (t1:UIntType) => SIntType(PLUS(w1(),Utils.ONE))
- case (t1:SIntType) => SIntType(w1())
- case (t1) => UnknownType
- }
- DoPrim(o,a,c,t)
- }
- case Neg => {
- val t = (t1()) match {
- case (t1:UIntType) => SIntType(PLUS(w1(),Utils.ONE))
- case (t1:SIntType) => SIntType(PLUS(w1(),Utils.ONE))
- case (t1) => UnknownType
- }
- DoPrim(o,a,c,t)
- }
- case Not => {
- val t = (t1()) match {
- case (t1:UIntType) => UIntType(w1())
- case (t1:SIntType) => UIntType(w1())
- case (t1) => UnknownType
- }
- DoPrim(o,a,c,t)
- }
- case And => {
- val t = (t1(),t2()) match {
- case (_:SIntType|_:UIntType, _:SIntType|_:UIntType) => UIntType(MAX(w1(),w2()))
- case (t1,t2) => UnknownType
- }
- DoPrim(o,a,c,t)
- }
- case Or => {
- val t = (t1(),t2()) match {
- case (_:SIntType|_:UIntType, _:SIntType|_:UIntType) => UIntType(MAX(w1(),w2()))
- case (t1,t2) => UnknownType
- }
- DoPrim(o,a,c,t)
- }
- case Xor => {
- val t = (t1(),t2()) match {
- case (_:SIntType|_:UIntType, _:SIntType|_:UIntType) => UIntType(MAX(w1(),w2()))
- case (t1,t2) => UnknownType
- }
- DoPrim(o,a,c,t)
- }
- case Andr => {
- val t = (t1()) match {
- case (_:UIntType|_:SIntType) => Utils.BoolType
- case (t1) => UnknownType
- }
- DoPrim(o,a,c,t)
- }
- case Orr => {
- val t = (t1()) match {
- case (_:UIntType|_:SIntType) => Utils.BoolType
- case (t1) => UnknownType
- }
- DoPrim(o,a,c,t)
- }
- case Xorr => {
- val t = (t1()) match {
- case (_:UIntType|_:SIntType) => Utils.BoolType
- case (t1) => UnknownType
- }
- DoPrim(o,a,c,t)
- }
- case Cat => {
- val t = (t1(),t2()) match {
- case (_:UIntType|_:SIntType,_:UIntType|_:SIntType) => UIntType(PLUS(w1(),w2()))
- case (t1, t2) => UnknownType
- }
- DoPrim(o,a,c,t)
- }
- case Bits => {
- val t = (t1()) match {
- case (_:UIntType|_:SIntType) => UIntType(PLUS(MINUS(c1(),c2()),Utils.ONE))
- case (t1) => UnknownType
- }
- DoPrim(o,a,c,t)
- }
- case Head => {
- val t = (t1()) match {
- case (_:UIntType|_:SIntType) => UIntType(c1())
- case (t1) => UnknownType
- }
- DoPrim(o,a,c,t)
- }
- case Tail => {
- val t = (t1()) match {
- case (_:UIntType|_:SIntType) => UIntType(MINUS(w1(),c1()))
- case (t1) => UnknownType
- }
- DoPrim(o,a,c,t)
- }
-
+ e.tpe match {
+ case UIntType(IntWidth(w)) => e
+ case SIntType(IntWidth(w)) => e
+ case _ => o match {
+ case Add => {
+ val t = (t1(),t2()) match {
+ case (t1:UIntType, t2:UIntType) => UIntType(PLUS(MAX(w1(),w2()),Utils.ONE))
+ case (t1:UIntType, t2:SIntType) => SIntType(PLUS(MAX(w1(),w2()),Utils.ONE))
+ case (t1:SIntType, t2:UIntType) => SIntType(PLUS(MAX(w1(),w2()),Utils.ONE))
+ case (t1:SIntType, t2:SIntType) => SIntType(PLUS(MAX(w1(),w2()),Utils.ONE))
+ case (t1, t2) => UnknownType
+ }
+ DoPrim(o,a,c,t)
+ }
+ case Sub => {
+ val t = (t1(),t2()) match {
+ case (t1:UIntType, t2:UIntType) => SIntType(PLUS(MAX(w1(),w2()),Utils.ONE))
+ case (t1:UIntType, t2:SIntType) => SIntType(PLUS(MAX(w1(),w2()),Utils.ONE))
+ case (t1:SIntType, t2:UIntType) => SIntType(PLUS(MAX(w1(),w2()),Utils.ONE))
+ case (t1:SIntType, t2:SIntType) => SIntType(PLUS(MAX(w1(),w2()),Utils.ONE))
+ case (t1, t2) => UnknownType
+ }
+ DoPrim(o,a,c,t)
+ }
+ case Mul => {
+ val t = (t1(),t2()) match {
+ case (t1:UIntType, t2:UIntType) => UIntType(PLUS(w1(),w2()))
+ case (t1:UIntType, t2:SIntType) => SIntType(PLUS(w1(),w2()))
+ case (t1:SIntType, t2:UIntType) => SIntType(PLUS(w1(),w2()))
+ case (t1:SIntType, t2:SIntType) => SIntType(PLUS(w1(),w2()))
+ case (t1, t2) => UnknownType
+ }
+ DoPrim(o,a,c,t)
+ }
+ case Div => {
+ val t = (t1(),t2()) match {
+ case (t1:UIntType, t2:UIntType) => UIntType(w1())
+ case (t1:UIntType, t2:SIntType) => SIntType(PLUS(w1(),Utils.ONE))
+ case (t1:SIntType, t2:UIntType) => SIntType(w1())
+ case (t1:SIntType, t2:SIntType) => SIntType(PLUS(w1(),Utils.ONE))
+ case (t1, t2) => UnknownType
+ }
+ DoPrim(o,a,c,t)
+ }
+ case Rem => {
+ val t = (t1(),t2()) match {
+ case (t1:UIntType, t2:UIntType) => UIntType(MIN(w1(),w2()))
+ case (t1:UIntType, t2:SIntType) => UIntType(MIN(w1(),w2()))
+ case (t1:SIntType, t2:UIntType) => SIntType(MIN(w1(),PLUS(w2(),Utils.ONE)))
+ case (t1:SIntType, t2:SIntType) => SIntType(MIN(w1(),w2()))
+ case (t1, t2) => UnknownType
+ }
+ DoPrim(o,a,c,t)
+ }
+ case Lt => {
+ val t = (t1(),t2()) match {
+ case (t1:UIntType, t2:UIntType) => Utils.BoolType
+ case (t1:SIntType, t2:UIntType) => Utils.BoolType
+ case (t1:UIntType, t2:SIntType) => Utils.BoolType
+ case (t1:SIntType, t2:SIntType) => Utils.BoolType
+ case (t1, t2) => UnknownType
+ }
+ DoPrim(o,a,c,t)
+ }
+ case Leq => {
+ val t = (t1(),t2()) match {
+ case (t1:UIntType, t2:UIntType) => Utils.BoolType
+ case (t1:SIntType, t2:UIntType) => Utils.BoolType
+ case (t1:UIntType, t2:SIntType) => Utils.BoolType
+ case (t1:SIntType, t2:SIntType) => Utils.BoolType
+ case (t1, t2) => UnknownType
+ }
+ DoPrim(o,a,c,t)
+ }
+ case Gt => {
+ val t = (t1(),t2()) match {
+ case (t1:UIntType, t2:UIntType) => Utils.BoolType
+ case (t1:SIntType, t2:UIntType) => Utils.BoolType
+ case (t1:UIntType, t2:SIntType) => Utils.BoolType
+ case (t1:SIntType, t2:SIntType) => Utils.BoolType
+ case (t1, t2) => UnknownType
+ }
+ DoPrim(o,a,c,t)
+ }
+ case Geq => {
+ val t = (t1(),t2()) match {
+ case (t1:UIntType, t2:UIntType) => Utils.BoolType
+ case (t1:SIntType, t2:UIntType) => Utils.BoolType
+ case (t1:UIntType, t2:SIntType) => Utils.BoolType
+ case (t1:SIntType, t2:SIntType) => Utils.BoolType
+ case (t1, t2) => UnknownType
+ }
+ DoPrim(o,a,c,t)
+ }
+ case Eq => {
+ val t = (t1(),t2()) match {
+ case (t1:UIntType, t2:UIntType) => Utils.BoolType
+ case (t1:SIntType, t2:UIntType) => Utils.BoolType
+ case (t1:UIntType, t2:SIntType) => Utils.BoolType
+ case (t1:SIntType, t2:SIntType) => Utils.BoolType
+ case (t1, t2) => UnknownType
+ }
+ DoPrim(o,a,c,t)
+ }
+ case Neq => {
+ val t = (t1(),t2()) match {
+ case (t1:UIntType, t2:UIntType) => Utils.BoolType
+ case (t1:SIntType, t2:UIntType) => Utils.BoolType
+ case (t1:UIntType, t2:SIntType) => Utils.BoolType
+ case (t1:SIntType, t2:SIntType) => Utils.BoolType
+ case (t1, t2) => UnknownType
+ }
+ DoPrim(o,a,c,t)
+ }
+ case Pad => {
+ val t = (t1()) match {
+ case (t1:UIntType) => UIntType(MAX(w1(),c1()))
+ case (t1:SIntType) => SIntType(MAX(w1(),c1()))
+ case (t1) => UnknownType
+ }
+ DoPrim(o,a,c,t)
+ }
+ case AsUInt => {
+ val t = (t1()) match {
+ case (t1:UIntType) => UIntType(w1())
+ case (t1:SIntType) => UIntType(w1())
+ case ClockType => UIntType(Utils.ONE)
+ case (t1) => UnknownType
+ }
+ DoPrim(o,a,c,t)
+ }
+ case AsSInt => {
+ val t = (t1()) match {
+ case (t1:UIntType) => SIntType(w1())
+ case (t1:SIntType) => SIntType(w1())
+ case ClockType => SIntType(Utils.ONE)
+ case (t1) => UnknownType
+ }
+ DoPrim(o,a,c,t)
+ }
+ case AsClock => {
+ val t = (t1()) match {
+ case (t1:UIntType) => ClockType
+ case (t1:SIntType) => ClockType
+ case ClockType => ClockType
+ case (t1) => UnknownType
+ }
+ DoPrim(o,a,c,t)
+ }
+ case Shl => {
+ val t = (t1()) match {
+ case (t1:UIntType) => UIntType(PLUS(w1(),c1()))
+ case (t1:SIntType) => SIntType(PLUS(w1(),c1()))
+ case (t1) => UnknownType
+ }
+ DoPrim(o,a,c,t)
+ }
+ case Shr => {
+ val t = (t1()) match {
+ case (t1:UIntType) => UIntType(MAX(MINUS(w1(),c1()),Utils.ONE))
+ case (t1:SIntType) => SIntType(MAX(MINUS(w1(),c1()),Utils.ONE))
+ case (t1) => UnknownType
+ }
+ DoPrim(o,a,c,t)
+ }
+ case Dshl => {
+ val t = (t1()) match {
+ case (t1:UIntType) => UIntType(PLUS(w1(),POW(w2())))
+ case (t1:SIntType) => SIntType(PLUS(w1(),POW(w2())))
+ case (t1) => UnknownType
+ }
+ DoPrim(o,a,c,t)
+ }
+ case Dshr => {
+ val t = (t1()) match {
+ case (t1:UIntType) => UIntType(w1())
+ case (t1:SIntType) => SIntType(w1())
+ case (t1) => UnknownType
+ }
+ DoPrim(o,a,c,t)
+ }
+ case Cvt => {
+ val t = (t1()) match {
+ case (t1:UIntType) => SIntType(PLUS(w1(),Utils.ONE))
+ case (t1:SIntType) => SIntType(w1())
+ case (t1) => UnknownType
+ }
+ DoPrim(o,a,c,t)
+ }
+ case Neg => {
+ val t = (t1()) match {
+ case (t1:UIntType) => SIntType(PLUS(w1(),Utils.ONE))
+ case (t1:SIntType) => SIntType(PLUS(w1(),Utils.ONE))
+ case (t1) => UnknownType
+ }
+ DoPrim(o,a,c,t)
+ }
+ case Not => {
+ val t = (t1()) match {
+ case (t1:UIntType) => UIntType(w1())
+ case (t1:SIntType) => UIntType(w1())
+ case (t1) => UnknownType
+ }
+ DoPrim(o,a,c,t)
+ }
+ case And => {
+ val t = (t1(),t2()) match {
+ case (_:SIntType|_:UIntType, _:SIntType|_:UIntType) => UIntType(MAX(w1(),w2()))
+ case (t1,t2) => UnknownType
+ }
+ DoPrim(o,a,c,t)
+ }
+ case Or => {
+ val t = (t1(),t2()) match {
+ case (_:SIntType|_:UIntType, _:SIntType|_:UIntType) => UIntType(MAX(w1(),w2()))
+ case (t1,t2) => UnknownType
+ }
+ DoPrim(o,a,c,t)
+ }
+ case Xor => {
+ val t = (t1(),t2()) match {
+ case (_:SIntType|_:UIntType, _:SIntType|_:UIntType) => UIntType(MAX(w1(),w2()))
+ case (t1,t2) => UnknownType
+ }
+ DoPrim(o,a,c,t)
+ }
+ case Andr => {
+ val t = (t1()) match {
+ case (_:UIntType|_:SIntType) => Utils.BoolType
+ case (t1) => UnknownType
+ }
+ DoPrim(o,a,c,t)
+ }
+ case Orr => {
+ val t = (t1()) match {
+ case (_:UIntType|_:SIntType) => Utils.BoolType
+ case (t1) => UnknownType
+ }
+ DoPrim(o,a,c,t)
+ }
+ case Xorr => {
+ val t = (t1()) match {
+ case (_:UIntType|_:SIntType) => Utils.BoolType
+ case (t1) => UnknownType
+ }
+ DoPrim(o,a,c,t)
+ }
+ case Cat => {
+ val t = (t1(),t2()) match {
+ case (_:UIntType|_:SIntType,_:UIntType|_:SIntType) => UIntType(PLUS(w1(),w2()))
+ case (t1, t2) => UnknownType
+ }
+ DoPrim(o,a,c,t)
+ }
+ case Bits => {
+ val t = (t1()) match {
+ case (_:UIntType|_:SIntType) => UIntType(PLUS(MINUS(c1(),c2()),Utils.ONE))
+ case (t1) => UnknownType
+ }
+ DoPrim(o,a,c,t)
+ }
+ case Head => {
+ val t = (t1()) match {
+ case (_:UIntType|_:SIntType) => UIntType(c1())
+ case (t1) => UnknownType
+ }
+ DoPrim(o,a,c,t)
+ }
+ case Tail => {
+ val t = (t1()) match {
+ case (_:UIntType|_:SIntType) => UIntType(MINUS(w1(),c1()))
+ case (t1) => UnknownType
+ }
+ DoPrim(o,a,c,t)
+ }
+ }
}
}
diff --git a/src/main/scala/firrtl/Utils.scala b/src/main/scala/firrtl/Utils.scala
index 2053a70d..76c8e61e 100644
--- a/src/main/scala/firrtl/Utils.scala
+++ b/src/main/scala/firrtl/Utils.scala
@@ -203,6 +203,22 @@ object Utils extends LazyLogging {
}
}
+ /** Returns true if t, or any subtype, contains a flipped field
+ * @param t [[firrtl.ir.Type]]
+ * @return if t contains [[firrtl.ir.Flip]]
+ */
+ def hasFlip(t: Type): Boolean = {
+ var has = false
+ def findFlip(t: Type): Type = t map (findFlip) match {
+ case t: BundleType =>
+ for (f <- t.fields) { if (f.flip == Flip) has = true }
+ t
+ case t: Type => t
+ }
+ findFlip(t)
+ has
+ }
+
//============== TYPES ================
def mux_type (e1:Expression,e2:Expression) : Type = mux_type(tpe(e1),tpe(e2))
def mux_type (t1:Type,t2:Type) : Type = {
@@ -268,7 +284,11 @@ object Utils extends LazyLogging {
}
def long_BANG (t:Type) : Long = {
(t) match {
- case g: GroundType => g.width.as[IntWidth].get.width.toLong
+ case g: GroundType =>
+ g.width match {
+ case IntWidth(x) => x.toLong
+ case _ => throw new FIRRTLException(s"Expecting IntWidth, got: ${g.width}")
+ }
case (t:BundleType) => {
var w = 0
for (f <- t.fields) { w = w + long_BANG(f.tpe).toInt }
diff --git a/src/main/scala/firrtl/passes/CheckChirrtl.scala b/src/main/scala/firrtl/passes/CheckChirrtl.scala
new file mode 100644
index 00000000..42f5bba2
--- /dev/null
+++ b/src/main/scala/firrtl/passes/CheckChirrtl.scala
@@ -0,0 +1,166 @@
+/*
+Copyright (c) 2014 - 2016 The Regents of the University of
+California (Regents). All Rights Reserved. Redistribution and use in
+source and binary forms, with or without modification, are permitted
+provided that the following conditions are met:
+ * Redistributions of source code must retain the above
+ copyright notice, this list of conditions and the following
+ two paragraphs of disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ two paragraphs of disclaimer in the documentation and/or other materials
+ provided with the distribution.
+ * Neither the name of the Regents nor the names of its contributors
+ may be used to endorse or promote products derived from this
+ software without specific prior written permission.
+IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
+SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS,
+ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
+REGENTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF
+ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION
+TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
+MODIFICATIONS.
+*/
+
+package firrtl.passes
+
+import com.typesafe.scalalogging.LazyLogging
+
+// Datastructures
+import scala.collection.mutable.HashMap
+import scala.collection.mutable.ArrayBuffer
+
+import firrtl._
+import firrtl.ir._
+import firrtl.Utils._
+import firrtl.Mappers._
+import firrtl.Serialize._
+import firrtl.PrimOps._
+import firrtl.WrappedType._
+
+
+object CheckChirrtl extends Pass with LazyLogging {
+ def name = "Chirrtl Check"
+
+ // TODO FIXME
+ // - Do we need to check for uniquness on port names?
+ def run (c: Circuit): Circuit = {
+ var mname: String = ""
+ var sinfo: Info = NoInfo
+
+ class NotUniqueException(name: String) extends PassException(s"${sinfo}: [module ${mname}] Reference ${name} does not have a unique name.")
+ class InvalidLOCException extends PassException(s"${sinfo}: [module ${mname}] Invalid connect to an expression that is not a reference or a WritePort.")
+ class UndeclaredReferenceException(name: String) extends PassException(s"${sinfo}: [module ${mname}] Reference ${name} is not declared.")
+ class MemWithFlipException(name: String) extends PassException(s"${sinfo}: [module ${mname}] Memory ${name} cannot be a bundle type with flips.")
+ class InvalidAccessException extends PassException(s"${sinfo}: [module ${mname}] Invalid access to non-reference.")
+ class NoTopModuleException(name: String) extends PassException(s"${sinfo}: A single module must be named ${name}.")
+ class ModuleNotDefinedException(name: String) extends PassException(s"${sinfo}: Module ${name} is not defined.")
+ class NegWidthException extends PassException(s"${sinfo}: [module ${mname}] Width cannot be negative or zero.")
+ class NegVecSizeException extends PassException(s"${sinfo}: [module ${mname}] Vector type size cannot be negative.")
+ class NegMemSizeException extends PassException(s"${sinfo}: [module ${mname}] Memory size cannot be negative or zero.")
+
+ val errors = new Errors()
+ def checkValidLoc(e: Expression) = e match {
+ case e @ (_: UIntLiteral | _: SIntLiteral | _: DoPrim ) => errors.append(new InvalidLOCException)
+ case _ => // Do Nothing
+ }
+ def checkChirrtlW(w: Width): Width = w match {
+ case w: IntWidth if (w.width <= BigInt(0)) =>
+ errors.append(new NegWidthException)
+ w
+ case _ => w
+ }
+ def checkChirrtlT(t: Type): Type = {
+ t map (checkChirrtlT) match {
+ case t: VectorType if (t.size < 0) => errors.append(new NegVecSizeException)
+ case _ => // Do nothing
+ }
+ t map (checkChirrtlW)
+ }
+
+ def checkChirrtlM(m: DefModule): DefModule = {
+ val names = HashMap[String, Boolean]()
+ val mnames = HashMap[String, Boolean]()
+ def checkChirrtlE(e: Expression): Expression = {
+ def validSubexp(e: Expression): Expression = e match {
+ case (_:Reference|_:SubField|_:SubIndex|_:SubAccess|_:Mux|_:ValidIf) => e // No error
+ case _ =>
+ errors.append(new InvalidAccessException)
+ e
+ }
+ e map (checkChirrtlE) match {
+ case e: Reference if (!names.contains(e.name)) => errors.append(new UndeclaredReferenceException(e.name))
+ case e: DoPrim => {}
+ case (_:Mux|_:ValidIf) => {}
+ case e: SubAccess =>
+ validSubexp(e.expr)
+ e
+ case e: UIntLiteral => {}
+ case e => e map (validSubexp)
+ }
+ e map (checkChirrtlW)
+ e map (checkChirrtlT)
+ e
+ }
+ def checkChirrtlS(s: Statement): Statement = {
+ sinfo = s.getInfo
+ def checkName(name: String): String = {
+ if (names.contains(name)) errors.append(new NotUniqueException(name))
+ else names(name) = true
+ name
+ }
+
+ s map (checkName)
+ s map (checkChirrtlT)
+ s map (checkChirrtlE)
+ s match {
+ case s: DefMemory =>
+ if (hasFlip(s.dataType)) errors.append(new MemWithFlipException(s.name))
+ if (s.depth <= 0) errors.append(new NegMemSizeException)
+ case s: DefInstance =>
+ if (!c.modules.map(_.name).contains(s.module))
+ errors.append(new ModuleNotDefinedException(s.module))
+ case s: Connect => checkValidLoc(s.loc)
+ case s: PartialConnect => checkValidLoc(s.loc)
+ case s: Print => {}
+ case _ => // Do Nothing
+ }
+
+ s map (checkChirrtlS)
+ }
+
+ mname = m.name
+ for (m <- c.modules) {
+ mnames(m.name) = true
+ }
+ for (p <- m.ports) {
+ sinfo = p.info
+ names(p.name) = true
+ val tpe = p.getType
+ tpe map (checkChirrtlT)
+ tpe map (checkChirrtlW)
+ }
+
+ m match {
+ case m: Module => checkChirrtlS(m.body)
+ case m: ExtModule => // Do Nothing
+ }
+ m
+ }
+
+ var numTopM = 0
+ for (m <- c.modules) {
+ if (m.name == c.main) numTopM = numTopM + 1
+ checkChirrtlM(m)
+ }
+ sinfo = c.info
+ if (numTopM != 1) errors.append(new NoTopModuleException(c.main))
+ errors.trigger
+ c
+ }
+}
+
+// vim: set ts=4 sw=4 et:
diff --git a/src/main/scala/firrtl/passes/Checks.scala b/src/main/scala/firrtl/passes/Checks.scala
index 5c0bb251..9bbf7fa8 100644
--- a/src/main/scala/firrtl/passes/Checks.scala
+++ b/src/main/scala/firrtl/passes/Checks.scala
@@ -117,24 +117,6 @@ object CheckHighForm extends Pass with LazyLogging {
}
}
- // Utility functions
- def hasFlip(t: Type): Boolean = {
- var has = false
- def findFlip(t: Type): Type = {
- t map (findFlip) match {
- case t: BundleType => {
- for (f <- t.fields) {
- if (f.flip == Flip) has = true
- }
- t
- }
- case t: Type => t
- }
- }
- findFlip(t)
- has
- }
-
// TODO FIXME
// - Do we need to check for uniquness on port names?
// Global Variables
diff --git a/src/test/scala/firrtlTests/ChirrtlSpec.scala b/src/test/scala/firrtlTests/ChirrtlSpec.scala
index d3e02ff1..a24cd9fa 100644
--- a/src/test/scala/firrtlTests/ChirrtlSpec.scala
+++ b/src/test/scala/firrtlTests/ChirrtlSpec.scala
@@ -35,27 +35,28 @@ import firrtl.ir.Circuit
import firrtl.passes._
class ChirrtlSpec extends FirrtlFlatSpec {
+ def passes = Seq(
+ CheckChirrtl,
+ CInferTypes,
+ CInferMDir,
+ RemoveCHIRRTL,
+ ToWorkingIR,
+ CheckHighForm,
+ ResolveKinds,
+ InferTypes,
+ CheckTypes,
+ ResolveGenders,
+ CheckGenders,
+ InferWidths,
+ CheckWidths,
+ PullMuxes,
+ ExpandConnects,
+ RemoveAccesses,
+ ExpandWhens,
+ CheckInitialization
+ )
"Chirrtl memories" should "allow ports with clocks defined after the memory" in {
- val passes = Seq(
- CInferTypes,
- CInferMDir,
- RemoveCHIRRTL,
- ToWorkingIR,
- CheckHighForm,
- ResolveKinds,
- InferTypes,
- CheckTypes,
- ResolveGenders,
- CheckGenders,
- InferWidths,
- CheckWidths,
- PullMuxes,
- ExpandConnects,
- RemoveAccesses,
- ExpandWhens,
- CheckInitialization
- )
val input =
"""circuit Unit :
| module Unit :
@@ -73,6 +74,26 @@ class ChirrtlSpec extends FirrtlFlatSpec {
}
}
+ "Chirrtl" should "catch undeclared wires" in {
+ val input =
+ """circuit Unit :
+ | module Unit :
+ | input clk : Clock
+ | smem ram : UInt<32>[128]
+ | node newClock = clk
+ | infer mport x = ram[UInt(2)], newClock
+ | x <= UInt(3)
+ | when UInt(1) :
+ | infer mport y = ram[UInt(4)], newClock
+ | y <= z
+ """.stripMargin
+ intercept[PassException] {
+ passes.foldLeft(Parser.parse(input.split("\n").toIterator)) {
+ (c: Circuit, p: Pass) => p.run(c)
+ }
+ }
+ }
+
it should "compile and run" in {
runFirrtlTest("ChirrtlMems", "/features")
}