aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile3
-rw-r--r--spec/spec.pdfbin424770 -> 247457 bytes
-rw-r--r--src/main/stanza/bigint2.stanza4
-rw-r--r--src/main/stanza/chirrtl.stanza34
-rw-r--r--src/main/stanza/compilers.stanza66
-rw-r--r--src/main/stanza/errors.stanza1148
-rw-r--r--src/main/stanza/ir-parser.stanza6
-rw-r--r--src/main/stanza/ir-utils.stanza13
-rw-r--r--src/main/stanza/passes.stanza79
-rw-r--r--src/main/stanza/primop.stanza19
-rw-r--r--test/errors/gender/ReadOutput.fir2
-rw-r--r--test/errors/high-form/Flip-Mem.fir1
-rw-r--r--test/errors/high-form/InvalidSubexp.fir4
-rw-r--r--test/errors/high-form/Printf.fir7
-rw-r--r--test/errors/parser/InstanceNotRef.fir2
-rw-r--r--test/features/InitAccessor.fir2
-rw-r--r--test/passes/jacktest/Counter.fir3
-rw-r--r--test/passes/jacktest/EnableShiftRegister.fir12
-rw-r--r--test/passes/jacktest/LFSR16.fir3
-rw-r--r--test/passes/jacktest/MemorySearch.fir5
-rw-r--r--test/passes/jacktest/Mul.fir2
-rw-r--r--test/passes/jacktest/RegisterVecShift.fir2
-rw-r--r--test/passes/jacktest/Rom.fir2
-rw-r--r--test/passes/jacktest/Stack.fir14
-rw-r--r--test/passes/jacktest/VendingMachine.fir3
-rw-r--r--test/passes/jacktest/gcd.fir4
-rw-r--r--test/passes/jacktest/risc.fir3
-rw-r--r--test/passes/lower-to-ground/bundle-vecs.fir24
-rw-r--r--test/passes/lower-to-ground/bundle.fir2
-rw-r--r--test/passes/split-exp/split-in-when.fir15
30 files changed, 753 insertions, 731 deletions
diff --git a/Makefile b/Makefile
index 5ddfcdd5..2c6353b4 100644
--- a/Makefile
+++ b/Makefile
@@ -58,6 +58,9 @@ check:
regress:
cd $(regress_dir) && firrtl -i rocket.fir -o rocket.v -X verilog
+jack:
+ cd $(test_dir)/passes/jacktest && lit -v . --path=$(root_dir)/utils/bin/
+
passes:
cd $(test_dir)/passes && lit -v . --path=$(root_dir)/utils/bin/
diff --git a/spec/spec.pdf b/spec/spec.pdf
index 8dac93d9..ffbfc056 100644
--- a/spec/spec.pdf
+++ b/spec/spec.pdf
Binary files differ
diff --git a/src/main/stanza/bigint2.stanza b/src/main/stanza/bigint2.stanza
index 91cd4558..deae1313 100644
--- a/src/main/stanza/bigint2.stanza
+++ b/src/main/stanza/bigint2.stanza
@@ -27,6 +27,10 @@ public defn to-int (x:Long) -> Int :
if x > to-long(2147483647) or x < to-long(-2147483648) : error("Long too big to convert to Int")
else : to-int(to-string(x))
+public defn to-int (x:BigInt) -> Int :
+ if length(d(x)) > 1 : error("BigInt too big to convert to Int")
+ else : d(x)[0]
+
public defn req-num-bits (i: Int) -> Int :
val i* =
if i < 0 : ((-1 * i) - 1)
diff --git a/src/main/stanza/chirrtl.stanza b/src/main/stanza/chirrtl.stanza
index 4f1c9cd5..06f1a61d 100644
--- a/src/main/stanza/chirrtl.stanza
+++ b/src/main/stanza/chirrtl.stanza
@@ -6,8 +6,8 @@ defpackage firrtl/chirrtl :
public defstruct ToIR <: Pass
public defmethod pass (b:ToIR) -> (Circuit -> Circuit) : to-ir
-public defmethod name (b:ToIR) -> String : "To IR"
-public defmethod short-name (b:ToIR) -> String : "to-ir"
+public defmethod name (b:ToIR) -> String : "To FIRRTL"
+public defmethod short-name (b:ToIR) -> String : "to-firrtl"
defstruct MPort :
name : Symbol
@@ -25,6 +25,16 @@ public definterface Gender
public val MALE = new Gender
public val FEMALE = new Gender
+defn create-exps (e:Expression) -> List<Expression> :
+ match(type(e)) :
+ (t:UIntType|SIntType|ClockType) : list(e)
+ (t:BundleType) :
+ for f in fields(t) map-append :
+ create-exps(SubField(e,name(f),type(f)))
+ (t:VectorType) :
+ for i in 0 to size(t) map-append :
+ create-exps(SubIndex(e,i,type(t)))
+
defn to-ir (c:Circuit) :
defn to-ir-m (m:InModule) -> InModule :
val hash = HashTable<Symbol,MPorts>(symbol-hash)
@@ -55,13 +65,27 @@ defn to-ir (c:Circuit) :
for r in vec do :
add(stmts,Connect(info(s),SubField(SubField(Ref(name(s),ut),name(r),ut),addr,t),Ref(n,t)))
add(stmts,Connect(info(s),SubField(SubField(Ref(name(s),ut),name(r),ut),`clk,t),clk(r)))
+ add(stmts,Connect(info(s),SubField(SubField(Ref(name(s),ut),name(r),ut),`en,t),zero))
+
+ defn set-write (vec:List<MPort>,data:Symbol,mask:Symbol) -> False :
+ val ndata = firrtl-gensym(`GEN,sh)
+ val tdata = type(s)
+ add(stmts,DefPoison(info(s),ndata,tdata))
+ val tmask = type(create-mask(`blah,type(s)))
+ for r in vec do :
+ add(stmts,Connect(info(s),SubField(SubField(Ref(name(s),ut),name(r),ut),data,tdata),Ref(ndata,tdata)))
+ for x in create-exps(SubField(SubField(Ref(name(s),ut),name(r),ut),mask,tmask)) do :
+ add(stmts,Connect(info(s),x,zero))
+
val rds = to-list $ readers $ get?(hash,name(s),EMPs())
set-poison(rds,`addr)
val wrs = to-list $ writers $ get?(hash,name(s),EMPs())
set-poison(wrs,`addr)
+ set-write(wrs,`data,`mask)
val rws = to-list $ readwriters $ get?(hash,name(s),EMPs())
set-poison(rws,`waddr)
set-poison(rws,`raddr)
+ set-write(rws,`wdata,`wmask)
val read-l =
if seq?(s) : 1
else : 0
@@ -100,10 +124,14 @@ defn to-ir (c:Circuit) :
(e) : e
defn to-ir-s (s:Stmt) -> Stmt :
match(s) :
- (s:Connect|BulkConnect) :
+ (s:Connect) :
val loc* = to-ir-e(loc(s),FEMALE)
val roc* = to-ir-e(exp(s),MALE)
Connect(info(s),loc*,roc*)
+ (s:BulkConnect) :
+ val loc* = to-ir-e(loc(s),FEMALE)
+ val roc* = to-ir-e(exp(s),MALE)
+ BulkConnect(info(s),loc*,roc*)
(s) : map(to-ir-e{_,MALE}, map(to-ir-s,s))
collect-mports(body(m))
val s* = collect-refs(body(m))
diff --git a/src/main/stanza/compilers.stanza b/src/main/stanza/compilers.stanza
index 6ede59ad..03819463 100644
--- a/src/main/stanza/compilers.stanza
+++ b/src/main/stanza/compilers.stanza
@@ -3,7 +3,7 @@ defpackage firrtl/compiler :
import verse
import firrtl/passes
import firrtl/chirrtl
- ;import firrtl/errors
+ import firrtl/errors
;import firrtl/flo
;import firrtl/verilog
import firrtl/ir2
@@ -46,45 +46,61 @@ public defmethod backend (c:StandardVerilog) -> List<Pass> :
to-list $ [ Verilog(with-output(c)) ]
public defmethod passes (c:StandardVerilog) -> List<Pass> :
to-list $ [
- ;RemoveSpecialChars() ;R
- ;CheckHighForm() ;R
- ;TempElimination() ;R ; Needs to check number of uses
- ToIR() ;R -> W
- ToWorkingIR() ;R -> W
- ResolveKinds() ;W
- InferTypes() ;R
- ResolveGenders() ;W
- InferWidths() ;R
+ ;RemoveSpecialChars()
+ ;TempElimination() ; Needs to check number of uses
+ ;===============
+ ToIR()
+ ;===============
+ CheckHighForm()
+ ;===============
+ ToWorkingIR()
+ ;===============
+ ResolveKinds()
+ InferTypes()
+ CheckTypes()
+ ResolveGenders()
+ CheckGenders()
+ InferWidths()
+ CheckWidths()
+ ;===============
Resolve()
- ;CheckGenders() ;W
- ;CheckKinds() ;W
- ;CheckTypes() ;R
- ;CheckGenders() ;W
+ ;===============
ExpandConnects()
+ ;===============
RemoveAccesses()
+ ;===============
ExpandWhens()
+ ;===============
+ CheckInitialization()
+ ;===============
ConstProp()
+ ;===============
SplitExp()
-
+ ;===============
ResolveKinds()
InferTypes()
+ CheckTypes()
ResolveGenders()
+ CheckGenders()
InferWidths()
-
+ CheckWidths()
+ ;===============
LowerTypes()
-
+ ;===============
ResolveKinds()
InferTypes()
+ CheckTypes()
ResolveGenders()
+ CheckGenders()
InferWidths()
- ;ToRealIR() ;W -> R
- ;CheckWidths() ;R
- ;Pad() ;R
- ;CheckWidths() ;R
- ;CheckHighForm() ;R
- ;CheckLowForm() ;R
- ;CheckInitialization() ;R
- Verilog(with-output(c)) ;R
+ CheckWidths()
+ ;===============
+ ;ToRealIR()
+ ;Pad()
+ ;CheckWidths()
+ ;CheckHighForm()
+ ;CheckLowForm()
+ Verilog(with-output(c))
]
public defstruct StandardFIRRTL <: Compiler :
diff --git a/src/main/stanza/errors.stanza b/src/main/stanza/errors.stanza
index 0aa036e9..f299d697 100644
--- a/src/main/stanza/errors.stanza
+++ b/src/main/stanza/errors.stanza
@@ -70,18 +70,10 @@ defn MemWithFlip (name:Symbol) :
PassException $ string-join $
[sinfo! ": [module " mname "] Memory " name " cannot be a bundle type with flips."]
-defn InvalidSubfield () :
- PassException $ string-join $
- [sinfo! ": [module " mname "] Invalid subfield access to non-reference."]
-
-defn InvalidIndex () :
- PassException $ string-join $
- [sinfo! ": [module " mname "] Invalid index access to non-reference."]
-
defn InvalidAccess () :
PassException $ string-join $
[sinfo! ": [module " mname "] Invalid access to non-reference."]
-
+
defn NoTopModule (name:Symbol) :
PassException $ string-join $
[sinfo! ": A single module must be named " name "."]
@@ -303,7 +295,7 @@ public defn check-high-form (c:Circuit) -> Circuit :
defn valid-subexp (e:Expression) -> Expression :
match(e) :
(e:Ref|SubField|SubIndex|SubAccess) : false
- (e) : add(errors,InvalidSubfield())
+ (e) : add(errors,InvalidAccess())
e
match(map(check-high-form-e,e)) :
(e:Ref) :
@@ -311,6 +303,9 @@ public defn check-high-form (c:Circuit) -> Circuit :
add(errors,UndeclaredReference(name(e)))
(e:DoPrim) : check-high-form-primop(e)
(e:UIntValue) : false
+ (e:SubAccess) :
+ valid-subexp(exp(e))
+ e
(e) : map(valid-subexp,e)
map(check-high-form-w,e)
map(check-high-form-t,e)
@@ -321,6 +316,7 @@ public defn check-high-form (c:Circuit) -> Circuit :
else : names[name] = true
name
sinfo! = info(s)
+ map(check-name,s)
map(check-high-form-t,s)
map(check-high-form-e,s)
match(s) :
@@ -339,7 +335,6 @@ public defn check-high-form (c:Circuit) -> Circuit :
(s:BulkConnect) : check-valid-loc(loc(s))
(s) : false
- map(check-name,s)
map(check-high-form-s,s)
mname = name(m)
@@ -364,618 +359,525 @@ public defn check-high-form (c:Circuit) -> Circuit :
throw(PassExceptions(errors)) when not empty?(errors)
c
-;;================= KIND CHECK ==========================
-;; o Cannot connect directly to a mem ever
-;; o onreset can only handle a register
-;; o Cannot use a mem in anything except an accessor, Readport, or Writeport
-;
-;public defstruct CheckKinds <: Pass
-;public defmethod pass (b:CheckKinds) -> (Circuit -> Circuit) : check-kinds
-;public defmethod name (b:CheckKinds) -> String : "Check Kinds"
-;public defmethod short-name (b:CheckKinds) -> String : "check-kinds"
-;
-;;----------------- Errors ---------------------
-;defn NotMem (info:FileInfo, name:Symbol) :
-; PassException $ string-join $
-; [info ": [module " mname "] Reference " name " must be a mem."]
-;
-;defn IsMem (info:FileInfo, name:Symbol) :
-; PassException $ string-join $
-; [info ": [module " mname "] Reference " name " cannot be a mem."]
-;
-;defn OnResetNotReg (info:FileInfo, name:Symbol) :
-; PassException $ string-join $
-; [info ": [module " mname "] Illegal on-reset to non-reg reference " name "."]
-;
-;defn AccessVecOrMem (info:FileInfo) :
-; PassException $ string-join $
-; [info ": [module " mname "] Accessors can only access vector-typed components or memories."]
-;
-;;----------------- Check Kinds Pass ---------------------
-;; I may have been overeager in looking for places where mems can't be, as mems are guaranteed to have a vector
-;; type, and this will get caught in the type check pass
-;public defn check-kinds (c:Circuit) -> Circuit :
-; val errors = Vector<PassException>()
-; defn get-kind (e:Expression) -> Kind :
-; match(e) :
-; (e:WRef) : kind(e)
-; (e:WSubfield) : get-kind(exp(e))
-; (e:WIndex) : get-kind(exp(e))
-; defn check-not-mem (info:FileInfo,e:Expression) -> False :
-; do(check-not-mem{info,_},e)
-; match(e) :
-; (e:WRef) : if kind(e) == MemKind() : add(errors,IsMem(info,name(e)))
-; (e:WSubfield) : check-not-mem(info,exp(e))
-; (e:WIndex) : check-not-mem(info,exp(e))
-; (e) : false
-; defn check-is-reg (info:FileInfo,e:Expression) -> False :
-; do(check-is-reg{info,_},e)
-; match(e) :
-; (e:WRef) : if kind(e) != RegKind() : add(errors,OnResetNotReg(info,name(e)))
-; (e:WSubfield) : check-is-reg(info,exp(e))
-; (e:WIndex) : check-is-reg(info,exp(e))
-; (e) : false
-; defn check-is-mem (info:FileInfo,e:Expression) -> False :
-; do(check-is-mem{info,_},e)
-; match(e) :
-; (e:WRef) : if kind(e) != MemKind() : add(errors,NotMem(info,name(e)))
-; (e:WSubfield) : check-is-mem(info,exp(e))
-; (e:WIndex) : check-is-mem(info,exp(e))
-; (e) : false
-;
-; defn check-kinds-s (s:Stmt) -> False :
-; match(s) :
-; (s:DefNode) : check-not-mem(info(s),value(s))
-; (s:DefAccessor) :
-; check-not-mem(info(s),index(s))
-; if (get-kind(source(s)) != MemKind()) and (not type(source(s)) typeof VectorType) :
-; println(get-kind(source(s)))
-; println(type(source(s)))
-; add(errors,AccessVecOrMem(info(s)))
-; (s:Conditionally) : check-not-mem(info(s),pred(s))
-; (s:Print) :
-; for x in args(s) do :
-; check-not-mem(info(s),x)
-; (s:Connect) :
-; check-not-mem(info(s),loc(s))
-; check-not-mem(info(s),exp(s))
-; (s:BulkConnect) :
-; check-not-mem(info(s),loc(s))
-; check-not-mem(info(s),exp(s))
-; (s:OnReset) :
-; check-is-reg(info(s),loc(s))
-; check-not-mem(info(s),exp(s))
-; (s) : false
-; do(check-kinds-s,s)
-;
-; for m in modules(c) do :
-; mname = name(m)
-; match(m) :
-; (m:ExModule) : false
-; (m:InModule) : check-kinds-s(body(m))
-; throw(PassExceptions(errors)) when not empty?(errors)
-; c
-;
-;;==================== CHECK TYPES =====================
-;; o Subfields are only on bundles, before type inference <- need to not error, just do unknown-type
-;; o Indexes are only on vectors
-;; o pred in conditionally must be of type UInt
-;; o enable/index in read/writeports must be UInt
-;; o node's value cannot be a bundle with a flip in it
-;; o := has same types
-;; o 2nd arg in dshr/l must be UInt, in general do primops
-;; o clock must be ClockType
-;; o reset must be UInt<1>
-;
-;public defstruct CheckTypes <: Pass
-;public defmethod pass (b:CheckTypes) -> (Circuit -> Circuit) : check-types
-;public defmethod name (b:CheckTypes) -> String : "Check Types"
-;public defmethod short-name (b:CheckTypes) -> String : "check-types"
-;
-;;----------------- Errors ---------------------
-;defn SubfieldNotInBundle (info:FileInfo, name:Symbol) :
-; PassException $ string-join $
-; [info ": [module " mname "] Subfield " name " is not in bundle."]
-;
-;defn SubfieldOnNonBundle (info:FileInfo, name:Symbol) :
-; PassException $ string-join $
-; [info ": [module " mname "] Subfield " name " is accessed on a non-bundle."]
-;
-;defn IndexTooLarge (info:FileInfo, value:Int) :
-; PassException $ string-join $
-; [info ": [module " mname "] Index with value " value " is too large."]
-;
-;defn IndexOnNonVector (info:FileInfo) :
-; PassException $ string-join $
-; [info ": [module " mname "] Index illegal on non-vector type."]
-;
-;defn IndexNotUInt (info:FileInfo) :
-; PassException $ string-join $
-; [info ": [module " mname "] Index is not of UIntType."]
-;
-;defn EnableNotUInt (info:FileInfo) :
-; PassException $ string-join $
-; [info ": [module " mname "] Enable is not of UIntType."]
-;
-;defn InvalidConnect (info:FileInfo) :
-; PassException $ string-join $
-; [info ": [module " mname "] Type mismatch."]
-;
-;defn PrintfArgNotGround (info:FileInfo) :
-; PassException $ string-join $
-; [info ": [module " mname "] Printf arguments must be either UIntType or SIntType."]
-;
-;defn PredNotUInt (info:FileInfo) :
-; PassException $ string-join $
-; [info ": [module " mname "] Predicate not a UIntType."]
-;
-;defn OpNotGround (info:FileInfo, op:Symbol) :
-; PassException $ string-join $
-; [info ": [module " mname "] Primop " op " cannot operate on non-ground types."]
-;
-;defn OpNotUInt (info:FileInfo, op:Symbol,e:Symbol) :
-; PassException $ string-join $
-; [info ": [module " mname "] Primop " op " requires argument " e " to be a UInt type."]
-;
-;defn OpNotAllUInt (info:FileInfo, op:Symbol) :
-; PassException $ string-join $
-; [info ": [module " mname "] Primop " op " requires all arguments to be UInt type."]
-;
-;defn OpNotAllSameType (info:FileInfo, op:Symbol) :
-; PassException $ string-join $
-; [info ": [module " mname "] Primop " op " requires all operands to have the same type."]
-;
-;defn NodeIllegalFlips (info:FileInfo) :
-; PassException $ string-join $
-; [info ": [module " mname "] Node cannot be a bundle type with flips."]
-;
-;defn OnResetIllegalFlips (info:FileInfo) :
-; PassException $ string-join $
-; [info ": [module " mname "] The register in onreset cannot be a bundle type with flips."]
-;
-;;---------------- Helper Functions --------------
-;defmethod equal? (t1:Type,t2:Type) -> True|False :
-; match(t1,t2) :
-; (t1:ClockType,t2:ClockType) : true
-; (t1:UIntType,t2:UIntType) : true
-; (t1:SIntType,t2:SIntType) : true
-; (t1:BundleType,t2:BundleType) :
-; var same? = true
-; for (f1 in fields(t1),f2 in fields(t2)) do :
-; if flip(f1) != flip(f2) : same? = false
-; if name(f1) != name(f2) : same? = false
-; if type(f1) != type(f2) : same? = false
-; same?
-; (t1:VectorType,t2:VectorType) :
-; if type(t1) == type(t2) and size(t1) == size(t2) : true
-; else : false
-; (t1,t2) : false
-;
-;defn ut () -> UIntType : UIntType(UnknownWidth())
-;defn st () -> SIntType : SIntType(UnknownWidth())
-;
-;defn check-types-primop (e:DoPrim, errors:Vector<PassException>,info:FileInfo) -> False :
-; defn all-same-type (ls:List<Expression>) -> False :
-; var error? = false
-; for x in ls do :
-; if type(head(ls)) != type(x) :
-; error? = true
-; if error? : add(errors,OpNotAllSameType(info,to-symbol $ op(e)))
-; defn all-ground (ls:List<Expression>) -> False :
-; var error? = false
-; for x in ls do :
-; if not (type(x) typeof UIntType or type(x) typeof SIntType) :
-; error? = true
-; if error? : add(errors,OpNotGround(info,to-symbol $ op(e)))
-; defn all-uint (ls:List<Expression>) -> False :
-; var error? = false
-; for x in ls do :
-; if not (type(x) typeof UIntType) :
-; error? = true
-; if error? : add(errors,OpNotAllUInt(info,to-symbol $ op(e)))
-; defn is-uint (x:Expression) -> False :
-; var error? = false
-; if not (type(x) typeof UIntType) :
-; error? = true
-; if error? : add(errors,OpNotUInt(info,to-symbol $ op(e),to-symbol(x)))
-;
-; all-ground(args(e))
-;
-; switch {op(e) == _} :
-; ADD-OP : false
-; SUB-OP : false
-; MUL-OP : false
-; DIV-OP : false
-; MOD-OP : false
-; QUO-OP : false
-; REM-OP : false
-; ADD-WRAP-OP : false
-; SUB-WRAP-OP : false
-; LESS-OP : false
-; LESS-EQ-OP : false
-; GREATER-OP : false
-; GREATER-EQ-OP : false
-; EQUAL-OP : false
-; NEQUAL-OP : false
-; EQUIV-OP : all-same-type(args(e))
-; NEQUIV-OP : all-same-type(args(e))
-; MUX-OP :
-; all-same-type(tail(args(e)))
-; is-uint(head(args(e)))
-; PAD-OP : false
-; AS-UINT-OP : false
-; AS-SINT-OP : false
-; DYN-SHIFT-LEFT-OP : is-uint(args(e)[1])
-; DYN-SHIFT-RIGHT-OP : is-uint(args(e)[1])
-; SHIFT-LEFT-OP : false
-; SHIFT-RIGHT-OP : false
-; CONVERT-OP : false
-; NEG-OP : false
-; BIT-NOT-OP : all-same-type(args(e))
-; BIT-AND-OP : all-same-type(args(e))
-; BIT-OR-OP : all-same-type(args(e))
-; BIT-XOR-OP : all-same-type(args(e))
-; BIT-SELECT-OP : false
-; BITS-SELECT-OP : false
-; BIT-AND-REDUCE-OP : all-uint(args(e))
-; BIT-OR-REDUCE-OP : all-uint(args(e))
-; BIT-XOR-REDUCE-OP : all-uint(args(e))
-; CONCAT-OP : all-uint(args(e))
-;
-;;----------------- Check Types Pass ---------------------
-;public defn check-types (c:Circuit) -> Circuit :
-; val errors = Vector<PassException>()
-; defn check-types-e (info:FileInfo,e:Expression) -> Expression :
-; match(map(check-types-e{info,_},e)) :
-; (e:WRef) : e
-; (e:WSubfield) :
-; match(type(exp(e))) :
-; (t:BundleType) :
-; val ft = for p in fields(t) find : name(p) == name(e)
-; if ft == false : add(errors,SubfieldNotInBundle(info,name(e)))
-; (t) : add(errors,SubfieldOnNonBundle(info,name(e)))
-; (e:WIndex) :
-; match(type(exp(e))) :
-; (t:VectorType) :
-; if value(e) >= size(t) : add(errors,IndexTooLarge(info,value(e)))
-; (t) : add(errors,IndexOnNonVector(info))
-; (e:DoPrim) : check-types-primop(e,errors,info)
-; (e:UIntValue|SIntValue) : false
-; e
-;
-; defn bulk-equals? (t1:Type,t2:Type) -> True|False :
-; match(t1,t2) :
-; (t1:BundleType,t2:BundleType) :
-; var same? = true
-; for (f1 in fields(t1),f2 in fields(t2)) do :
-; if name(f1) == name(f2) :
-; if flip(f1) != flip(f2) : same? = false
-; if not bulk-equals?(type(f1),type(f2)) : same? = false
-; same?
-; (t1:ClockType,t2:ClockType) : true
-; (t1:UIntType,t2:UIntType) : true
-; (t1:SIntType,t2:SIntType) : true
-; (t1:VectorType,t2:VectorType) :
-; if bulk-equals?(type(t1),type(t2)) : true
-; else : false
-; (t1,t2) : false
-;
-; defn check-types-s (s:Stmt) -> Stmt :
-; map{check-types-s,_} $ {
-; match(map(check-types-e{info(s),_},s)) :
-; (s:Connect) :
-; if type(loc(s)) != type(exp(s)) : add(errors,InvalidConnect(info(s)))
-; (s:BulkConnect) :
-; if not bulk-equals?(type(loc(s)),type(exp(s))) :
-; add(errors,InvalidConnect(info(s)))
-; (s:OnReset) :
-; if type(loc(s)) != type(exp(s)) : add(errors,InvalidConnect(info(s)))
-; if has-flip?(type(loc(s))) : add(errors,OnResetIllegalFlips(info(s)))
-; (s:Print) :
-; for x in args(s) do :
-; if type(x) != ut() and type(x) != st():
-; add(errors,PrintfArgNotGround(info(s)))
-; (s:Conditionally) :
-; if type(pred(s)) != ut() : add(errors,PredNotUInt(info(s)))
-; (s:DefNode) :
-; if has-flip?(type(value(s))) : add(errors,NodeIllegalFlips(info(s)))
-; (s) : false
-; s }()
-;
-; for m in modules(c) do :
-; mname = name(m)
-; match(m) :
-; (m:ExModule) : false
-; (m:InModule) : check-types-s(body(m))
-; throw(PassExceptions(errors)) when not empty?(errors)
-; c
-;
-;;================= GENDER CHECK ==========================
-;; o Nodes always male
-;; o Accessors only have one gender, unless rdwr
-;; o output/input only one gender
-;; o correctly check for the base bundle
-;
-;public defstruct CheckGenders <: Pass
-;public defmethod pass (b:CheckGenders) -> (Circuit -> Circuit) : check-genders
-;public defmethod name (b:CheckGenders) -> String : "Check Genders"
-;public defmethod short-name (b:CheckGenders) -> String : "check-genders"
-;
-;;----------------- Errors ---------------------
-;defn WrongGender (info:FileInfo,expr:Symbol,wrong:Symbol,right:Symbol) :
-; PassException $ string-join $
-; [info ": [module " mname "] Expression " expr " is used as a " wrong " but can only be used as a " right "."]
-;
-;defn InferDirection (info:FileInfo,name:Symbol) :
-; PassException $ string-join $
-; [info ": [module " mname "] Accessor " name " has a direction that requires inference."]
-;
-;;---------------- Helper Functions --------------
-;defn dir-to-gender (d:PortDirection) -> Gender :
-; switch {_ == d} :
-; INPUT : MALE
-; OUTPUT : FEMALE ;BI-GENDER
-;
-;defn gender (s:DefAccessor) -> Gender :
-; switch {_ == acc-dir(s)} :
-; READ : MALE
-; WRITE : FEMALE
-; INFER : UNKNOWN-GENDER
-; RDWR : BI-GENDER
-;
-;defn as-srcsnk (g:Gender) -> Symbol :
-; switch {_ == g} :
-; MALE : `source
-; FEMALE : `sink
-; UNKNOWN-GENDER : `unknown
-; BI-GENDER : `sourceOrSink
-;
-;;----------------- Check Genders Pass ---------------------
-;
-;public defn check-genders (c:Circuit) -> Circuit :
-; val errors = Vector<PassException>()
-; defn get-kind (e:Expression) -> Kind :
-; match(e) :
-; (e:WRef) : kind(e)
-; (e:WSubfield) : get-kind(exp(e))
-; (e:WIndex) : get-kind(exp(e))
-; (e) : NodeKind()
-;
-; defn check-gender (info:FileInfo,genders:HashTable<Symbol,Gender>,e:Expression,desired:Gender) -> False :
-; val gender = get-gender(e,genders)
-; val kind* = get-kind(e)
-; val flip? =
-; match(type(e)) :
-; (t:BundleType) :
-; for f in fields(t) any? : flip(f) == REVERSE
-; (t) : false
-;
-; ;println(e)
-; ;println(gender)
-; ;println(desired)
-; ;println(kind*)
-; ;println(desired == gender)
-; ;if gender != desired and gender != BI-GENDER:
-; switch fn ([x,y]) : gender == x and desired == y :
-; [MALE, FEMALE] :
-; add(errors,WrongGender(info,to-symbol(e),as-srcsnk(desired),as-srcsnk(gender)))
-; [FEMALE, MALE] :
-; if kind* != PortKind() and kind* != InstanceKind():
-; add(errors,WrongGender(info,to-symbol(e),as-srcsnk(desired),as-srcsnk(gender)))
-; else : false
-;
-; defn get-gender (e:Expression,genders:HashTable<Symbol,Gender>) -> Gender :
-; match(e) :
-; (e:WRef) : genders[name(e)]
-; (e:WSubfield) :
-; val f = {_ as Field} $ for f in fields(type(exp(e)) as BundleType) find : name(f) == name(e)
-; get-gender(exp(e),genders) * flip(f)
-; (e:WIndex) : get-gender(exp(e),genders)
-; (e:DoPrim) : MALE
-; (e:UIntValue) : MALE
-; (e:SIntValue) : MALE
-;
-; defn check-genders-e (info:FileInfo,e:Expression,genders:HashTable<Symbol,Gender>) -> False :
-; do(check-genders-e{info,_,genders},e)
-; match(e) :
-; (e:WRef) : false
-; (e:WSubfield) : false
-; (e:WIndex) : false
-; (e:DoPrim) :
-; for e in args(e) do :
-; check-gender(info,genders,e,MALE)
-; (e:UIntValue) : false
-; (e:SIntValue) : false
-;
-; defn check-genders-s (s:Stmt,genders:HashTable<Symbol,Gender>) -> False :
-; do(check-genders-e{info(s),_:Expression,genders},s)
-; do(check-genders-s{_:Stmt,genders},s)
-; match(s) :
-; (s:DefWire) : genders[name(s)] = BI-GENDER
-; (s:DefPoison) : genders[name(s)] = MALE
-; (s:DefRegister) : genders[name(s)] = BI-GENDER
-; (s:DefNode) :
-; check-gender(info(s),genders,value(s),MALE)
-; genders[name(s)] = MALE
-; (s:DefMemory) : genders[name(s)] = BI-GENDER
-; (s:DefInstance) : genders[name(s)] = MALE
-; (s:DefAccessor) :
-; if acc-dir(s) == INFER : add(errors,InferDirection(info(s),name(s)))
-; check-gender(info(s),genders,index(s),MALE)
-; check-gender(info(s),genders,source(s),gender(s))
-; genders[name(s)] = gender(s)
-; (s:Connect) :
-; check-gender(info(s),genders,loc(s),FEMALE)
-; check-gender(info(s),genders,exp(s),MALE)
-; (s:Print) :
-; for x in args(s) do :
-; check-gender(info(s),genders,x,MALE)
-; (s:BulkConnect) :
-; check-gender(info(s),genders,loc(s),FEMALE)
-; check-gender(info(s),genders,exp(s),MALE)
-; (s:OnReset) :
-; check-gender(info(s),genders,loc(s),FEMALE)
-; check-gender(info(s),genders,exp(s),MALE)
-; (s:Conditionally) :
-; check-gender(info(s),genders,pred(s),MALE)
-; (s:Empty) : false
-; (s:Stop) : false
-; (s:Begin) : false
-;
-;
-; for m in modules(c) do :
-; mname = name(m)
-; val genders = HashTable<Symbol,Gender>(symbol-hash)
-; for p in ports(m) do :
-; genders[name(p)] = dir-to-gender(direction(p))
-; match(m) :
-; (m:ExModule) : false
-; (m:InModule) : check-genders-s(body(m),genders)
-; throw(PassExceptions(errors)) when not empty?(errors)
-; c
-;
-;;;================ Initialization Check ==================
-;; Error on all componenents that are not connected to.
-;
-;public defstruct CheckInitialization <: Pass
-;public defmethod pass (b:CheckInitialization) -> (Circuit -> Circuit) : check-init
-;public defmethod name (b:CheckInitialization) -> String : "Check Initialization"
-;public defmethod short-name (b:CheckInitialization) -> String : "check-init"
-;
-;;----------------- Errors ------------------------
-;
-;defn RefNotInitialized (info:FileInfo, name:Symbol) :
-; PassException $ string-join $
-; [info ": [module " mname "] Reference " name " is not fully initialized."]
-;
-;;------------ Helper Functions -------------
-;
-;;------------ Pass ------------------
-;
-;public defn check-init (c:Circuit) :
-; val errors = Vector<PassException>()
-;
-; defn check-init-m (m:InModule) :
-; val init? = HashTable<Symbol,FileInfo|True>(symbol-hash)
-; defn get-name (e:Expression) -> Symbol :
-; match(e) :
-; (e:Ref) : name(e)
-; (e:Subfield) : symbol-join([get-name(exp(e)) `. name(e)])
-; (e) : error("Shouldn't be here")
-;
-; defn check-init-s (s:Stmt) :
-; do(check-init-s,s)
-; match(s) :
-; (s:DefWire|DefRegister) : init?[name(s)] = info(s)
-; (s:DefAccessor) :
-; if acc-dir(s) == WRITE : init?[name(s)] = info(s)
-; (s:DefInstance) :
-; for f in fields(type(module(s)) as BundleType) do :
-; if flip(f) == REVERSE :
-; init?[symbol-join([name(s) `. name(f)])] = info(s)
-; (s:Connect) :
-; init?[get-name(loc(s))] = true
-; (s) : false
-;
-; for p in ports(m) do :
-; if direction(p) == OUTPUT :
-; init?[name(p)] = info(p)
-;
-; check-init-s(body(m))
-;
-; for x in init? do :
-; match(value(x)) :
-; (v:FileInfo) : add(errors, RefNotInitialized(v,key(x)))
-; (v) : false
-;
-; for m in modules(c) do :
-; mname = name(m)
-; match(m) :
-; (m:InModule) : check-init-m(m)
-; (m) : false
-;
-; throw(PassExceptions(errors)) when not empty?(errors)
-; c
-;
-;;================= Width Check ==========================
-;;AFTER WIDTH INFERENCE
-;; * No names
-;; * No Unknowns
-;; * All widths are positive
-;; * widths are large enough to contain value
-;
-;
-;public defstruct CheckWidths <: Pass
-;public defmethod pass (b:CheckWidths) -> (Circuit -> Circuit) : check-width
-;public defmethod name (b:CheckWidths) -> String : "Width Check"
-;public defmethod short-name (b:CheckWidths) -> String : "width-check"
-;
-;;----------------- Errors ------------------------
-;
-;defn UninferredWidth (info:FileInfo) :
-; PassException $ string-join $
-; [info ": [module " mname "] Uninferred width."]
-;
-;defn WidthTooSmall (info:FileInfo,v:String) :
-; PassException $ string-join $
-; [info ": [module " mname "] Width too small for constant " v "."]
-;
-;;---------------- Helper Functions --------------
-;
-;;--------------- Check Width Pass -------------------
-;public defn check-width (c:Circuit) -> Circuit :
-; val errors = Vector<PassException>()
-;
-; defn check-width-m (m:Module) -> False :
-; defn check-width-w (info:FileInfo,w:Width) -> Width :
-; match(w) :
-; (w:IntWidth) :
-; if width(w) <= to-long(0) : add(errors,NegWidth(info))
-; (w) :
-; add(errors,UninferredWidth(info))
-; w
-;
-; defn check-width-e (info:FileInfo,e:Expression) -> Expression :
-; match(map(check-width-e{info,_},e)) :
-; (e:UIntValue) :
-; match(width(e)) :
-; (w:IntWidth) :
-; if max(to-long(1),to-long(req-num-bits(value(e)) - 1)) > width(w) :
-; add(errors,WidthTooSmall(info,to-string(value(e))))
-; (w) : add(errors,UninferredWidth(info))
-; check-width-w(info,width(e))
-; (e:SIntValue) :
-; match(width(e)) :
-; (w:IntWidth) :
-; if to-long(req-num-bits(value(e))) > width(w) :
-; add(errors,WidthTooSmall(info,to-string(value(e))))
-; (w) : add(errors,UninferredWidth(info))
-; check-width-w(info,width(e))
-; (e:DoPrim) : false
-; (e) : false
-;
-; ;mapr(check-width-w{info,_},type(map(check-width-e{info,_},e)))
-; e
-;
-; defn check-width-s (s:Stmt) -> Stmt :
-; map(check-width-e{info(s),_},map(check-width-s,s))
-; map(mapr{check-width-w{info(s),_},_:Type},s)
-;
-; for p in ports(m) do :
-; mapr(check-width-w{info(p),_},type(p))
-;
-; match(m) :
-; (m:ExModule) : false
-; (m:InModule) : check-width-s(body(m))
-; false
-;
-; for m in modules(c) do :
-; mname = name(m)
-; check-width-m(m)
-; throw(PassExceptions(errors)) when not empty?(errors)
-; c
-;
-;
+;==================== CHECK TYPES =====================
+; o Subfields are only on bundles, before type inference <- need to not error, just do unknown-type
+; o Indexes are only on vectors
+; o pred in conditionally must be of type UInt
+; o enable/index in read/writeports must be UInt
+; o node's value cannot be a bundle with a flip in it
+; o := has same types
+; o 2nd arg in dshr/l must be UInt, in general do primops
+; o clock must be ClockType
+; o reset must be UInt<1>
+
+public defstruct CheckTypes <: Pass
+public defmethod pass (b:CheckTypes) -> (Circuit -> Circuit) : check-types
+public defmethod name (b:CheckTypes) -> String : "Check Types"
+public defmethod short-name (b:CheckTypes) -> String : "check-types"
+
+;----------------- Errors ---------------------
+defn SubfieldNotInBundle (info:FileInfo, name:Symbol) :
+ PassException $ string-join $
+ [info ": [module " mname "] Subfield " name " is not in bundle."]
+
+defn SubfieldOnNonBundle (info:FileInfo, name:Symbol) :
+ PassException $ string-join $
+ [info ": [module " mname "] Subfield " name " is accessed on a non-bundle."]
+
+defn IndexTooLarge (info:FileInfo, value:Int) :
+ PassException $ string-join $
+ [info ": [module " mname "] Index with value " value " is too large."]
+
+defn IndexOnNonVector (info:FileInfo) :
+ PassException $ string-join $
+ [info ": [module " mname "] Index illegal on non-vector type."]
+
+defn IndexNotUInt (info:FileInfo) :
+ PassException $ string-join $
+ [info ": [module " mname "] Index is not of UIntType."]
+
+defn EnableNotUInt (info:FileInfo) :
+ PassException $ string-join $
+ [info ": [module " mname "] Enable is not of UIntType."]
+
+defn InvalidConnect (info:FileInfo) :
+ PassException $ string-join $
+ [info ": [module " mname "] Type mismatch."]
+
+defn PrintfArgNotGround (info:FileInfo) :
+ PassException $ string-join $
+ [info ": [module " mname "] Printf arguments must be either UIntType or SIntType."]
+
+defn ReqClk (info:FileInfo) :
+ PassException $ string-join $
+ [info ": [module " mname "] Requires a clock typed signal."]
+
+defn EnNotUInt (info:FileInfo) :
+ PassException $ string-join $
+ [info ": [module " mname "] Enable must be a UIntType typed signal."]
+
+defn PredNotUInt (info:FileInfo) :
+ PassException $ string-join $
+ [info ": [module " mname "] Predicate not a UIntType."]
+
+defn OpNotGround (info:FileInfo, op:Symbol) :
+ PassException $ string-join $
+ [info ": [module " mname "] Primop " op " cannot operate on non-ground types."]
+
+defn OpNotUInt (info:FileInfo, op:Symbol,e:Symbol) :
+ PassException $ string-join $
+ [info ": [module " mname "] Primop " op " requires argument " e " to be a UInt type."]
+
+defn OpNotAllUInt (info:FileInfo, op:Symbol) :
+ PassException $ string-join $
+ [info ": [module " mname "] Primop " op " requires all arguments to be UInt type."]
+
+defn OpNotAllSameType (info:FileInfo, op:Symbol) :
+ PassException $ string-join $
+ [info ": [module " mname "] Primop " op " requires all operands to have the same type."]
+
+defn NodeIllegalFlips (info:FileInfo) :
+ PassException $ string-join $
+ [info ": [module " mname "] Node cannot be a bundle type with flips."]
+
+defn OnResetIllegalFlips (info:FileInfo) :
+ PassException $ string-join $
+ [info ": [module " mname "] The register in onreset cannot be a bundle type with flips."]
+
+;---------------- Helper Functions --------------
+defmethod equal? (t1:Type,t2:Type) -> True|False :
+ match(t1,t2) :
+ (t1:ClockType,t2:ClockType) : true
+ (t1:UIntType,t2:UIntType) : true
+ (t1:SIntType,t2:SIntType) : true
+ (t1:BundleType,t2:BundleType) :
+ var same? = true
+ for (f1 in fields(t1),f2 in fields(t2)) do :
+ if flip(f1) != flip(f2) : same? = false
+ if name(f1) != name(f2) : same? = false
+ if type(f1) != type(f2) : same? = false
+ same?
+ (t1:VectorType,t2:VectorType) :
+ if type(t1) == type(t2) and size(t1) == size(t2) : true
+ else : false
+ (t1,t2) : false
+
+defn ut () -> UIntType : UIntType(UnknownWidth())
+defn st () -> SIntType : SIntType(UnknownWidth())
+
+defn check-types-primop (e:DoPrim, errors:Vector<PassException>,info:FileInfo) -> False :
+ defn all-same-type (ls:List<Expression>) -> False :
+ var error? = false
+ for x in ls do :
+ if type(head(ls)) != type(x) :
+ error? = true
+ if error? : add(errors,OpNotAllSameType(info,to-symbol $ op(e)))
+ defn all-ground (ls:List<Expression>) -> False :
+ var error? = false
+ for x in ls do :
+ if not (type(x) typeof UIntType or type(x) typeof SIntType) :
+ error? = true
+ if error? : add(errors,OpNotGround(info,to-symbol $ op(e)))
+ defn all-uint (ls:List<Expression>) -> False :
+ var error? = false
+ for x in ls do :
+ if not (type(x) typeof UIntType) :
+ error? = true
+ if error? : add(errors,OpNotAllUInt(info,to-symbol $ op(e)))
+ defn is-uint (x:Expression) -> False :
+ var error? = false
+ if not (type(x) typeof UIntType) :
+ error? = true
+ if error? : add(errors,OpNotUInt(info,to-symbol $ op(e),to-symbol(x)))
+
+ all-ground(args(e))
+
+ switch {op(e) == _} :
+ ADD-OP : false
+ SUB-OP : false
+ MUL-OP : false
+ DIV-OP : false
+ MOD-OP : false
+ QUO-OP : false
+ REM-OP : false
+ ADD-WRAP-OP : false
+ SUB-WRAP-OP : false
+ LESS-OP : false
+ LESS-EQ-OP : false
+ GREATER-OP : false
+ GREATER-EQ-OP : false
+ EQUAL-OP : false
+ NEQUAL-OP : false
+ EQUIV-OP : all-same-type(args(e))
+ NEQUIV-OP : all-same-type(args(e))
+ MUX-OP :
+ all-same-type(tail(args(e)))
+ is-uint(head(args(e)))
+ PAD-OP : false
+ AS-UINT-OP : false
+ AS-SINT-OP : false
+ DYN-SHIFT-LEFT-OP : is-uint(args(e)[1])
+ DYN-SHIFT-RIGHT-OP : is-uint(args(e)[1])
+ SHIFT-LEFT-OP : false
+ SHIFT-RIGHT-OP : false
+ CONVERT-OP : false
+ NEG-OP : false
+ BIT-NOT-OP : all-same-type(args(e))
+ BIT-AND-OP : all-same-type(args(e))
+ BIT-OR-OP : all-same-type(args(e))
+ BIT-XOR-OP : all-same-type(args(e))
+ BIT-SELECT-OP : false
+ BITS-SELECT-OP : false
+ BIT-AND-REDUCE-OP : all-uint(args(e))
+ BIT-OR-REDUCE-OP : all-uint(args(e))
+ BIT-XOR-REDUCE-OP : all-uint(args(e))
+ CONCAT-OP : all-uint(args(e))
+
+;----------------- Check Types Pass ---------------------
+public defn check-types (c:Circuit) -> Circuit :
+ val errors = Vector<PassException>()
+ defn check-types-e (info:FileInfo,e:Expression) -> Expression :
+ match(map(check-types-e{info,_},e)) :
+ (e:WRef) : e
+ (e:WSubField) :
+ match(type(exp(e))) :
+ (t:BundleType) :
+ val ft = for p in fields(t) find : name(p) == name(e)
+ if ft == false : add(errors,SubfieldNotInBundle(info,name(e)))
+ (t) : add(errors,SubfieldOnNonBundle(info,name(e)))
+ (e:WSubIndex) :
+ match(type(exp(e))) :
+ (t:VectorType) :
+ if value(e) >= size(t) : add(errors,IndexTooLarge(info,value(e)))
+ (t) : add(errors,IndexOnNonVector(info))
+ (e:WSubAccess) :
+ match(type(exp(e))) :
+ (t:VectorType) : false
+ (t) : add(errors,IndexOnNonVector(info))
+ (e:DoPrim) : check-types-primop(e,errors,info)
+ (e:UIntValue|SIntValue) : false
+ e
+
+ defn bulk-equals? (t1:Type,t2:Type) -> True|False :
+ match(t1,t2) :
+ (t1:BundleType,t2:BundleType) :
+ var same? = true
+ for (f1 in fields(t1),f2 in fields(t2)) do :
+ if name(f1) == name(f2) :
+ if flip(f1) != flip(f2) : same? = false
+ if not bulk-equals?(type(f1),type(f2)) : same? = false
+ same?
+ (t1:ClockType,t2:ClockType) : true
+ (t1:UIntType,t2:UIntType) : true
+ (t1:SIntType,t2:SIntType) : true
+ (t1:VectorType,t2:VectorType) :
+ if bulk-equals?(type(t1),type(t2)) : true
+ else : false
+ (t1,t2) : false
+
+ defn check-types-s (s:Stmt) -> Stmt :
+ map{check-types-s,_} $ {
+ match(map(check-types-e{info(s),_},s)) :
+ (s:Connect) :
+ if type(loc(s)) != type(exp(s)) : add(errors,InvalidConnect(info(s)))
+ (s:BulkConnect) :
+ if not bulk-equals?(type(loc(s)),type(exp(s))) :
+ add(errors,InvalidConnect(info(s)))
+ (s:Stop) :
+ if type(clk(s)) != ClockType() : add(errors,ReqClk(info(s)))
+ if type(en(s)) != ut() : add(errors,EnNotUInt(info(s)))
+ (s:Print) :
+ for x in args(s) do :
+ if type(x) != ut() and type(x) != st():
+ add(errors,PrintfArgNotGround(info(s)))
+ if type(clk(s)) != ClockType() : add(errors,ReqClk(info(s)))
+ if type(en(s)) != ut() : add(errors,EnNotUInt(info(s)))
+ (s:Conditionally) :
+ if type(pred(s)) != ut() : add(errors,PredNotUInt(info(s)))
+ (s:DefNode) :
+ if has-flip?(type(value(s))) : add(errors,NodeIllegalFlips(info(s)))
+ (s) : false
+ s }()
+
+ for m in modules(c) do :
+ mname = name(m)
+ match(m) :
+ (m:ExModule) : false
+ (m:InModule) : check-types-s(body(m))
+ throw(PassExceptions(errors)) when not empty?(errors)
+ c
+
+;================= GENDER CHECK ==========================
+; o Nodes always male
+; o Accessors only have one gender, unless rdwr
+; o output/input only one gender
+; o correctly check for the base bundle
+
+public defstruct CheckGenders <: Pass
+public defmethod pass (b:CheckGenders) -> (Circuit -> Circuit) : check-genders
+public defmethod name (b:CheckGenders) -> String : "Check Genders"
+public defmethod short-name (b:CheckGenders) -> String : "check-genders"
+
+;----------------- Errors ---------------------
+defn WrongGender (info:FileInfo,expr:Symbol,wrong:Symbol,right:Symbol) :
+ PassException $ string-join $
+ [info ": [module " mname "] Expression " expr " is used as a " wrong " but can only be used as a " right "."]
+
+;---------------- Helper Functions --------------
+defn dir-to-gender (d:Direction) -> Gender :
+ switch {_ == d} :
+ INPUT : MALE
+ OUTPUT : FEMALE ;BI-GENDER
+
+defn as-srcsnk (g:Gender) -> Symbol :
+ switch {_ == g} :
+ MALE : `source
+ FEMALE : `sink
+ UNKNOWN-GENDER : `unknown
+ BI-GENDER : `sourceOrSink
+
+;----------------- Check Genders Pass ---------------------
+
+public defn check-genders (c:Circuit) -> Circuit :
+ val errors = Vector<PassException>()
+ defn get-kind (e:Expression) -> Kind :
+ match(e) :
+ (e:WRef) : kind(e)
+ (e:WSubField) : get-kind(exp(e))
+ (e:WSubIndex) : get-kind(exp(e))
+ (e:WSubAccess) : get-kind(exp(e))
+ (e) : NodeKind()
+
+ defn check-gender (info:FileInfo,genders:HashTable<Symbol,Gender>,e:Expression,desired:Gender) -> False :
+ val gender = get-gender(e,genders)
+ val kind* = get-kind(e)
+ val flip? =
+ match(type(e)) :
+ (t:BundleType) :
+ for f in fields(t) any? : flip(f) == REVERSE
+ (t) : false
+
+ ;println(e)
+ ;println(gender)
+ ;println(desired)
+ ;println(kind*)
+ ;println(desired == gender)
+ ;if gender != desired and gender != BI-GENDER:
+ switch fn ([x,y]) : gender == x and desired == y :
+ [MALE, FEMALE] :
+ add(errors,WrongGender(info,to-symbol(e),as-srcsnk(desired),as-srcsnk(gender)))
+ [FEMALE, MALE] :
+ if (kind* == PortKind() or kind* == InstanceKind()) and flip? == false :
+ ; OK!
+ false
+ else :
+ ; Not Ok!
+ add(errors,WrongGender(info,to-symbol(e),as-srcsnk(desired),as-srcsnk(gender)))
+ else : false
+
+ defn get-gender (e:Expression,genders:HashTable<Symbol,Gender>) -> Gender :
+ match(e) :
+ (e:WRef) : genders[name(e)]
+ (e:WSubField) :
+ val f = {_ as Field} $ for f in fields(type(exp(e)) as BundleType) find : name(f) == name(e)
+ get-gender(exp(e),genders) * flip(f)
+ (e:WSubIndex) : get-gender(exp(e),genders)
+ (e:WSubAccess) : get-gender(exp(e),genders)
+ (e:DoPrim) : MALE
+ (e:UIntValue) : MALE
+ (e:SIntValue) : MALE
+
+ defn check-genders-e (info:FileInfo,e:Expression,genders:HashTable<Symbol,Gender>) -> False :
+ do(check-genders-e{info,_,genders},e)
+ match(e) :
+ (e:WRef) : false
+ (e:WSubField) : false
+ (e:WSubIndex) : false
+ (e:WSubAccess) : false
+ (e:DoPrim) :
+ for e in args(e) do :
+ check-gender(info,genders,e,MALE)
+ (e:UIntValue) : false
+ (e:SIntValue) : false
+
+ defn check-genders-s (s:Stmt,genders:HashTable<Symbol,Gender>) -> False :
+ do(check-genders-e{info(s),_:Expression,genders},s)
+ do(check-genders-s{_:Stmt,genders},s)
+ match(s) :
+ (s:DefWire) : genders[name(s)] = BI-GENDER
+ (s:DefPoison) : genders[name(s)] = MALE
+ (s:DefRegister) : genders[name(s)] = BI-GENDER
+ (s:DefNode) :
+ check-gender(info(s),genders,value(s),MALE)
+ genders[name(s)] = MALE
+ (s:DefMemory) : genders[name(s)] = FEMALE
+ (s:WDefInstance) : genders[name(s)] = MALE
+ (s:Connect) :
+ check-gender(info(s),genders,loc(s),FEMALE)
+ check-gender(info(s),genders,exp(s),MALE)
+ (s:Print) :
+ for x in args(s) do :
+ check-gender(info(s),genders,x,MALE)
+ check-gender(info(s),genders,en(s),MALE)
+ check-gender(info(s),genders,clk(s),MALE)
+ (s:BulkConnect) :
+ check-gender(info(s),genders,loc(s),FEMALE)
+ check-gender(info(s),genders,exp(s),MALE)
+ (s:Conditionally) :
+ check-gender(info(s),genders,pred(s),MALE)
+ (s:Empty) : false
+ (s:Stop) :
+ check-gender(info(s),genders,en(s),MALE)
+ check-gender(info(s),genders,clk(s),MALE)
+ (s:Begin) : false
+
+
+ for m in modules(c) do :
+ mname = name(m)
+ val genders = HashTable<Symbol,Gender>(symbol-hash)
+ for p in ports(m) do :
+ genders[name(p)] = dir-to-gender(direction(p))
+ match(m) :
+ (m:ExModule) : false
+ (m:InModule) : check-genders-s(body(m),genders)
+ throw(PassExceptions(errors)) when not empty?(errors)
+ c
+
+;================= Width Check ==========================
+;AFTER WIDTH INFERENCE
+; * No names
+; * No Unknowns
+; * All widths are positive
+; * widths are large enough to contain value
+
+
+public defstruct CheckWidths <: Pass
+public defmethod pass (b:CheckWidths) -> (Circuit -> Circuit) : check-width
+public defmethod name (b:CheckWidths) -> String : "Width Check"
+public defmethod short-name (b:CheckWidths) -> String : "width-check"
+
+;----------------- Errors ------------------------
+
+defn UninferredWidth (info:FileInfo) :
+ PassException $ string-join $
+ [info ": [module " mname "] Uninferred width."]
+
+defn WidthTooSmall (info:FileInfo,v:String) :
+ PassException $ string-join $
+ [info ": [module " mname "] Width too small for constant " v "."]
+
+;---------------- Helper Functions --------------
+
+;--------------- Check Width Pass -------------------
+public defn check-width (c:Circuit) -> Circuit :
+ val errors = Vector<PassException>()
+
+ defn check-width-m (m:Module) -> False :
+ defn check-width-w (info:FileInfo,w:Width) -> Width :
+ match(w) :
+ (w:IntWidth) :
+ if width(w) <= to-long(0) : add(errors,NegWidth())
+ (w) :
+ add(errors,UninferredWidth(info))
+ w
+
+ defn check-width-e (info:FileInfo,e:Expression) -> Expression :
+ match(map(check-width-e{info,_},e)) :
+ (e:UIntValue) :
+ match(width(e)) :
+ (w:IntWidth) :
+ if max(to-long(1),to-long(req-num-bits(value(e)) - 1)) > width(w) :
+ add(errors,WidthTooSmall(info,to-string(value(e))))
+ (w) : add(errors,UninferredWidth(info))
+ check-width-w(info,width(e))
+ (e:SIntValue) :
+ match(width(e)) :
+ (w:IntWidth) :
+ if to-long(req-num-bits(value(e))) > width(w) :
+ add(errors,WidthTooSmall(info,to-string(value(e))))
+ (w) : add(errors,UninferredWidth(info))
+ check-width-w(info,width(e))
+ (e:DoPrim) : false
+ (e) : false
+
+ ;mapr(check-width-w{info,_},type(map(check-width-e{info,_},e)))
+ e
+
+ defn check-width-s (s:Stmt) -> Stmt :
+ sinfo! = info(s)
+ map(check-width-e{info(s),_},map(check-width-s,s))
+ map(mapr{check-width-w{info(s),_},_:Type},s)
+
+ for p in ports(m) do :
+ mapr(check-width-w{info(p),_},type(p))
+
+ match(m) :
+ (m:ExModule) : false
+ (m:InModule) : check-width-s(body(m))
+ false
+
+ for m in modules(c) do :
+ mname = name(m)
+ check-width-m(m)
+ throw(PassExceptions(errors)) when not empty?(errors)
+ c
+
+
+;================ Initialization Check ==================
+; Error on all componenents that are not connected to.
+
+public defstruct CheckInitialization <: Pass
+public defmethod pass (b:CheckInitialization) -> (Circuit -> Circuit) : check-init
+public defmethod name (b:CheckInitialization) -> String : "Check Initialization"
+public defmethod short-name (b:CheckInitialization) -> String : "check-init"
+
+;----------------- Errors ------------------------
+
+defn RefNotInitialized (info:FileInfo, name:Symbol) :
+ PassException $ string-join $
+ [info ": [module " mname "] Reference " name " is not fully initialized."]
+
+;------------ Helper Functions -------------
+
+;------------ Pass ------------------
+
+public defn check-init (c:Circuit) :
+ val errors = Vector<PassException>()
+
+ defn check-init-m (m:InModule) :
+ defn get-name (e:Expression) -> Symbol :
+ match(e) :
+ (e:WRef) : name(e)
+ (e:WSubField) : symbol-join([get-name(exp(e)) `. name(e)])
+ (e) : error("Shouldn't be here")
+ defn has-void? (e:Expression) -> True|False :
+ var void? = false
+ defn has-void (e:Expression) -> Expression :
+ match(e) :
+ (e:WVoid) :
+ void? = true
+ e
+ (e) : map(has-void,e)
+ has-void(e)
+ void?
+ defn check-init-s (s:Stmt) -> Stmt :
+ match(s) :
+ (s:Connect) :
+ if has-void?(exp(s)) : add(errors,RefNotInitialized(info(s),get-name(loc(s))))
+ s
+ (s) : map(check-init-s,s)
+
+ check-init-s(body(m))
+
+ for m in modules(c) do :
+ mname = name(m)
+ match(m) :
+ (m:InModule) : check-init-m(m)
+ (m) : false
+
+ throw(PassExceptions(errors)) when not empty?(errors)
+ c
+
;;================= Low Form Check ==========================
;;AFTER LOWERING
;; o All things connect to once
diff --git a/src/main/stanza/ir-parser.stanza b/src/main/stanza/ir-parser.stanza
index bd006ea6..d891227f 100644
--- a/src/main/stanza/ir-parser.stanza
+++ b/src/main/stanza/ir-parser.stanza
@@ -264,11 +264,11 @@ defsyntax firrtl :
stmt = (smem ?name:#id! #:! ?t:#vectype! ) : CDefMemory(first-info(form),name,type(t),size(t),true)
stmt = (read mport ?name:#id! #=! ?mem:#id! (@get ?index:#exp!) ?clk:#exp!) :
- CDefMPort(first-info(form),name,mem,index,clk,MRead)
+ CDefMPort(first-info(form),name,mem,list(index,clk),MRead)
stmt = (write mport ?name:#id! #=! ?mem:#id! (@get ?index:#exp!) ?clk:#exp!) :
- CDefMPort(first-info(form),name,mem,index,clk,MWrite)
+ CDefMPort(first-info(form),name,mem,list(index,clk),MWrite)
stmt = (rdwr mport ?name:#id! #=! ?mem:#id! (@get ?index:#exp!) ?clk:#exp!) :
- CDefMPort(first-info(form),name,mem,index,clk,MReadWrite)
+ CDefMPort(first-info(form),name,mem,list(index,clk),MReadWrite)
stmt = (mem ?name:#id! #:! (?ms:#mstat ...)) :
defn grab (f:MStat -> True|False) :
diff --git a/src/main/stanza/ir-utils.stanza b/src/main/stanza/ir-utils.stanza
index 4581fe30..a2af082b 100644
--- a/src/main/stanza/ir-utils.stanza
+++ b/src/main/stanza/ir-utils.stanza
@@ -136,6 +136,17 @@ public defn exp-hash (e:Expression) -> Int :
val i = symbol-hash(to-symbol(to-string(e)))
turn-on-debug(false)
i
+
+;============= Useful functions ==============
+public defn create-mask (n:Symbol,dt:Type) -> Field :
+ Field{n,DEFAULT,_} $ match(dt) :
+ (t:VectorType) : VectorType(BoolType(),size(t))
+ (t:BundleType) :
+ val fields* = for f in fields(t) map :
+ Field(name(f),flip(f),BoolType())
+ BundleType(fields*)
+ (t:UIntType|SIntType) : BoolType()
+
;============== Exceptions =====================
public definterface PassException <: Exception
@@ -334,7 +345,7 @@ defmethod print (o:OutputStream, c:Stmt) :
else :
print-all(o, ["cmem " name(c) " : " type(c) "[" size(c) "]"])
(c:CDefMPort) :
- print-all(o, [direction(c) " mport " name(c) " = " mem(c) "[" index(c) "], " clk(c)])
+ print-all(o, [direction(c) " mport " name(c) " = " mem(c) "[" exps(c)[0] "], " exps(c)[1]])
if not c typeof Conditionally|Begin|Empty: print-debug(o,c)
diff --git a/src/main/stanza/passes.stanza b/src/main/stanza/passes.stanza
index 217dcecd..49158dd7 100644
--- a/src/main/stanza/passes.stanza
+++ b/src/main/stanza/passes.stanza
@@ -75,8 +75,8 @@ defstruct WIndexer <: Expression :
index: Expression
type: Type with: (as-method => true)
gender : Gender with: (as-method => true)
-defstruct WVoid <: Expression
-defstruct WDefInstance <: Stmt :
+public defstruct WVoid <: Expression
+public defstruct WDefInstance <: Stmt :
info: FileInfo with: (as-method => true)
name: Symbol
module: Symbol
@@ -97,7 +97,7 @@ defn get-gender (s:Stmt|Port) -> Gender :
INPUT : MALE
OUTPUT : FEMALE
-defmulti kind (e:Expression) -> Kind
+public defmulti kind (e:Expression) -> Kind
defmethod kind (e:Expression) :
match(e) :
(e:WRef) : kind(e)
@@ -121,14 +121,6 @@ defn get-type (s:Stmt) -> Type :
(s:DefWire|DefPoison|DefRegister|WDefInstance) : type(s)
(s:DefNode) : type(value(s))
(s:DefMemory) :
- defn create-mask (n:Symbol) -> Field :
- Field{n,DEFAULT,_} $ match(data-type(s)) :
- (t:VectorType) : VectorType(BoolType(),size(t))
- (t:BundleType) :
- val fields* = for f in fields(t) map :
- Field(name(f),flip(f),BoolType())
- BundleType(fields*)
- (t:UIntType|SIntType) : BoolType()
val depth = depth(s)
; Fields
val addr = Field(`addr,DEFAULT,UIntType(IntWidth(ceil-log2(depth))))
@@ -138,8 +130,8 @@ defn get-type (s:Stmt) -> Type :
val rev-data = Field(`data,REVERSE,data-type(s))
val rdata = Field(`rdata,REVERSE,data-type(s))
val wdata = Field(`wdata,DEFAULT,data-type(s))
- val mask = create-mask(`mask)
- val wmask = create-mask(`wmask)
+ val mask = create-mask(`mask,data-type(s))
+ val wmask = create-mask(`wmask,data-type(s))
val ren = Field(`ren,DEFAULT,UIntType(IntWidth(1)))
val wen = Field(`wen,DEFAULT,UIntType(IntWidth(1)))
val raddr = Field(`raddr,DEFAULT,UIntType(IntWidth(ceil-log2(depth))))
@@ -1534,9 +1526,11 @@ defn infer-widths (c:Circuit) -> Circuit :
;constrain(width!(loc(s)),width!(exp(s)))
;s
val n = get-size(loc(s))
+ val ce-loc = create-exps(loc(s))
+ val ce-exp = create-exps(exp(s))
for i in 0 to n do :
- val loc* = create-exps(loc(s))[i]
- val exp* = create-exps(exp(s))[i]
+ val loc* = ce-loc[i]
+ val exp* = ce-exp[i]
switch { _ == get-flip(type(loc(s)),i,DEFAULT) } :
DEFAULT : constrain(width!(loc*),width!(exp*))
REVERSE : constrain(width!(exp*),width!(loc*))
@@ -1667,7 +1661,7 @@ defn split-exp (m:InModule) -> InModule :
(s:DefRegister) : name(s)
(s) : `F
defn split (e:Expression) -> Expression :
- val n = firrtl-gensym(base,sh)
+ val n = firrtl-gensym(`GEN,sh)
add(v,DefNode(info(s),n,e))
WRef(n,type(e),kind(e),gender(e))
defn split-exp-e (e:Expression,i:Int) -> Expression :
@@ -1847,6 +1841,47 @@ defn split-exp (c:Circuit) -> Circuit :
; (m:InModule) : InModule(info(m),name(m),ports(m),pad-widths-s(body(m)))
;
;
+
+;============== Common Subexpression Elimination ===========
+;NOT DONE
+
+;public defstruct CSE <: Pass
+;public defmethod pass (b:CSE) -> (Circuit -> Circuit) : const-prop
+;public defmethod name (b:CSE) -> String : "Common Subexpression Elimination"
+;public defmethod short-name (b:ConstProp) -> String : "cse"
+;
+;defn cse-m (m:InModule) -> InModule :
+; val cse-hash = HashTable<Expression,Int>(exp-hash)
+; val placed? = HashTable<Expression,True|False>(exp-hash)
+;
+; defn cse-s (s:Stmt) -> Stmt :
+; val stmts = Vector<Stmt>()
+; defn cse-e (e:Expression) -> Expression
+; match(s) :
+;
+; defn build-e (e:Expression) -> Expression :
+; match(e) :
+; (e:DoPrim) :
+; if key?(cse-hash,e) :
+; cse-hash[e] = cse-hash[e] + 1
+; else :
+; cse-hash[e] = 1
+; placed?[e] = false
+; (e) : e
+; defn build-s (s:Stmt) -> Stmt : map{build-s,_} $ map(build-e,s)
+;
+; build-s(body(m))
+; InModule(info(m),name(m),ports(m),cse-s(body(m)))
+;
+;public defn cse (c:Circuit) -> Circuit :
+; Circuit{info(c),_,main(c)} $
+; for m in modules(c) map :
+; match(m) :
+; (m:ExModule) : m
+; (m:InModule) : cse-m(m)
+
+
+
;;============= Constant Propagation ================
;
public defstruct ConstProp <: Pass
@@ -1858,6 +1893,16 @@ defn const-prop-e (e:Expression) -> Expression :
match(map(const-prop-e,e)) :
(e:DoPrim) :
switch {op(e) == _} :
+ DYN-SHIFT-RIGHT-OP :
+ match(args(e)[1]) :
+ (x:UIntValue|SIntValue) :
+ DoPrim(SHIFT-RIGHT-OP,list(args(e)[0]),list(to-int(value(x))),UnknownType())
+ (x) : e
+ DYN-SHIFT-LEFT-OP :
+ match(args(e)[1]) :
+ (x:UIntValue|SIntValue) :
+ DoPrim(SHIFT-LEFT-OP,list(args(e)[0]),list(to-int(value(x))),UnknownType())
+ (x) : e
SHIFT-RIGHT-OP :
match(args(e)[0]) :
(x:UIntValue) :
@@ -2582,3 +2627,5 @@ defn emit-verilog (with-output:(() -> False) -> False, c:Circuit) :
(m:InModule) : emit-verilog(m)
(m:ExModule) : false
c
+
+
diff --git a/src/main/stanza/primop.stanza b/src/main/stanza/primop.stanza
index 8cbae193..6c43c494 100644
--- a/src/main/stanza/primop.stanza
+++ b/src/main/stanza/primop.stanza
@@ -30,54 +30,63 @@ public defn set-primop-type (e:DoPrim) -> DoPrim :
(t1:UIntType, t2:SIntType) : SIntType(PLUS(MAX(w1(),w2()),ONE))
(t1:SIntType, t2:UIntType) : SIntType(PLUS(MAX(w1(),w2()),ONE))
(t1:SIntType, t2:SIntType) : SIntType(PLUS(MAX(w1(),w2()),ONE))
+ (t1, t2) : UnknownType()
SUB-OP : DoPrim{o,a,c,_} $
match(t1(),t2()) :
(t1:UIntType, t2:UIntType) : SIntType(PLUS(MAX(w1(),w2()),ONE))
(t1:UIntType, t2:SIntType) : SIntType(PLUS(MAX(w1(),w2()),ONE))
(t1:SIntType, t2:UIntType) : SIntType(PLUS(MAX(w1(),w2()),ONE))
(t1:SIntType, t2:SIntType) : SIntType(PLUS(MAX(w1(),w2()),ONE))
+ (t1, t2) : UnknownType()
ADD-WRAP-OP : DoPrim{o,a,c,_} $
match(t1(),t2()) :
(t1:UIntType, t2:UIntType) : UIntType(MAX(w1(),w2()))
(t1:UIntType, t2:SIntType) : SIntType(MAX(w1(),w2()))
(t1:SIntType, t2:UIntType) : SIntType(MAX(w1(),w2()))
(t1:SIntType, t2:SIntType) : SIntType(MAX(w1(),w2()))
+ (t1, t2) : UnknownType()
SUB-WRAP-OP : DoPrim{o,a,c,_} $
match(t1(),t2()) :
(t1:UIntType, t2:UIntType) : UIntType(MAX(w1(),w2()))
(t1:UIntType, t2:SIntType) : SIntType(MAX(w1(),w2()))
(t1:SIntType, t2:UIntType) : SIntType(MAX(w1(),w2()))
(t1:SIntType, t2:SIntType) : SIntType(MAX(w1(),w2()))
+ (t1, t2) : UnknownType()
MUL-OP : DoPrim{o,a,c,_} $
match(t1(),t2()) :
(t1:UIntType, t2:UIntType) : UIntType(PLUS(w1(),w2()))
(t1:UIntType, t2:SIntType) : SIntType(PLUS(w1(),w2()))
(t1:SIntType, t2:UIntType) : SIntType(PLUS(w1(),w2()))
(t1:SIntType, t2:SIntType) : SIntType(PLUS(w1(),w2()))
+ (t1, t2) : UnknownType()
DIV-OP : DoPrim{o,a,c,_} $
match(t1(),t2()) :
(t1:UIntType, t2:UIntType) : UIntType(w1())
(t1:UIntType, t2:SIntType) : SIntType(PLUS(w1(),w2()))
(t1:SIntType, t2:UIntType) : SIntType(w1())
(t1:SIntType, t2:SIntType) : SIntType(PLUS(w1(),w2()))
+ (t1, t2) : UnknownType()
MOD-OP : DoPrim{o,a,c,_} $
match(t1(),t2()) :
(t1:UIntType, t2:UIntType) : UIntType(w2())
(t1:UIntType, t2:SIntType) : UIntType(w2())
(t1:SIntType, t2:UIntType) : SIntType(PLUS(w2(),ONE))
(t1:SIntType, t2:SIntType) : SIntType(w2())
+ (t1, t2) : UnknownType()
QUO-OP : DoPrim{o,a,c,_} $
match(t1(),t2()) :
(t1:UIntType, t2:UIntType) : UIntType(PLUS(w1(),ONE))
(t1:UIntType, t2:SIntType) : SIntType(w1())
(t1:SIntType, t2:UIntType) : SIntType(PLUS(w1(),ONE))
(t1:SIntType, t2:SIntType) : SIntType(w1())
+ (t1, t2) : UnknownType()
REM-OP : DoPrim{o,a,c,_} $
match(t1(),t2()) :
(t1:UIntType, t2:UIntType) : UIntType(w2())
(t1:UIntType, t2:SIntType) : SIntType(w2())
(t1:SIntType, t2:UIntType) : UIntType(PLUS(w2(),ONE))
(t1:SIntType, t2:SIntType) : SIntType(w2())
+ (t1, t2) : UnknownType()
LESS-OP : DoPrim(o,a,c,BoolType())
LESS-EQ-OP : DoPrim(o,a,c,BoolType())
GREATER-OP : DoPrim(o,a,c,BoolType())
@@ -90,42 +99,52 @@ public defn set-primop-type (e:DoPrim) -> DoPrim :
match(t2(),t3()) :
(t2:UIntType, t3:UIntType) : UIntType(MAX(w2(),w3()))
(t2:SIntType, t3:SIntType) : SIntType(MAX(w2(),w3()))
+ (t2, t3) : UnknownType()
PAD-OP : DoPrim{o,a,c,_} $
match(t1()) :
(t1:UIntType) : UIntType(c1())
(t1:SIntType) : SIntType(c1())
+ (t1) : UnknownType()
AS-UINT-OP : DoPrim{o,a,c,_} $
match(t1()) :
(t1:UIntType) : UIntType(w1())
(t1:SIntType) : UIntType(w1())
+ (t1) : UnknownType()
AS-SINT-OP : DoPrim{o,a,c,_} $
match(t1()) :
(t1:UIntType) : SIntType(w1())
(t1:SIntType) : SIntType(w1())
+ (t1) : UnknownType()
SHIFT-LEFT-OP : DoPrim{o,a,c,_} $
match(t1()) :
(t1:UIntType) : UIntType(PLUS(w1(),c1()))
(t1:SIntType) : SIntType(PLUS(w1(),c1()))
+ (t1) : UnknownType()
SHIFT-RIGHT-OP : DoPrim{o,a,c,_} $
match(t1()) :
(t1:UIntType) : UIntType(MINUS(w1(),c1()))
(t1:SIntType) : SIntType(MINUS(w1(),c1()))
+ (t1) : UnknownType()
DYN-SHIFT-LEFT-OP : DoPrim{o,a,c,_} $
match(t1()) :
(t1:UIntType) : UIntType(PLUS(w1(),POW(w2())))
(t1:SIntType) : SIntType(PLUS(w1(),POW(w2())))
+ (t1) : UnknownType()
DYN-SHIFT-RIGHT-OP : DoPrim{o,a,c,_} $
match(t1()) :
(t1:UIntType) : UIntType(w1())
(t1:SIntType) : SIntType(w1())
+ (t1) : UnknownType()
CONVERT-OP : DoPrim{o,a,c,_} $
match(t1()) :
(t1:UIntType) : SIntType(PLUS(w1(),ONE))
(t1:SIntType) : SIntType(w1())
+ (t1) : UnknownType()
NEG-OP : DoPrim{o,a,c,_} $
match(t1()) :
(t1:UIntType) : SIntType(PLUS(w1(),ONE))
(t1:SIntType) : SIntType(w1())
+ (t1) : UnknownType()
BIT-NOT-OP : DoPrim(o,a,c,t1())
BIT-AND-OP : DoPrim(o,a,c,UIntType(MAX(w1(),w2())))
BIT-OR-OP : DoPrim(o,a,c,UIntType(MAX(w1(),w2())))
diff --git a/test/errors/gender/ReadOutput.fir b/test/errors/gender/ReadOutput.fir
index fd3607d0..f9e8f7b4 100644
--- a/test/errors/gender/ReadOutput.fir
+++ b/test/errors/gender/ReadOutput.fir
@@ -1,5 +1,5 @@
; RUN: firrtl -i %s -o %s.v -X verilog -p c 2>&1 | tee %s.out | FileCheck %s
-; CHECK: Expression out$y is used as a sink but can only be used as a source.
+; CHECK: Expression out is used as a source but can only be used as a sink.
circuit BTB :
module BTB :
diff --git a/test/errors/high-form/Flip-Mem.fir b/test/errors/high-form/Flip-Mem.fir
index ebc3ddbf..a8cb67ca 100644
--- a/test/errors/high-form/Flip-Mem.fir
+++ b/test/errors/high-form/Flip-Mem.fir
@@ -1,6 +1,5 @@
; RUN: firrtl -i %s -o %s.v -X verilog -p c 2>&1 | tee %s.out | FileCheck %s
; CHECK: Memory mc cannot be a bundle type with flips.
-; CHECK: Memory ms cannot be a bundle type with flips.
circuit Flip-Mem :
module Flip-Mem :
diff --git a/test/errors/high-form/InvalidSubexp.fir b/test/errors/high-form/InvalidSubexp.fir
index 23c155e2..d0ad34c0 100644
--- a/test/errors/high-form/InvalidSubexp.fir
+++ b/test/errors/high-form/InvalidSubexp.fir
@@ -1,6 +1,6 @@
; RUN: firrtl -i %s -o %s.v -X verilog -p c 2>&1 | tee %s.out | FileCheck %s
-; CHECK: Invalid index access to non-reference.
-; CHECK: Invalid subfield access to non-reference.
+; CHECK: Invalid access to non-reference.
+; CHECK: Invalid access to non-reference.
circuit Top :
module Top :
diff --git a/test/errors/high-form/Printf.fir b/test/errors/high-form/Printf.fir
index 7f285d3e..5580182b 100644
--- a/test/errors/high-form/Printf.fir
+++ b/test/errors/high-form/Printf.fir
@@ -4,9 +4,10 @@ circuit Top :
module Top :
input x : {y : UInt<1>}
input p : UInt<1>
- printf("Hello World%!\n",x)
- printf("Hello World%")
- printf("Hello World%d %s %h %x",x,x,x)
+ input clk : Clock
+ printf(clk,p,"Hello World%!\n",x)
+ printf(clk,p,"Hello World%")
+ printf(clk,p,"Hello World%d %s %h %x",x,x,x)
;CHECK: Bad printf format: "%!"
;CHECK: Bad printf format: trailing "%"
diff --git a/test/errors/parser/InstanceNotRef.fir b/test/errors/parser/InstanceNotRef.fir
index a6996fee..0760f168 100644
--- a/test/errors/parser/InstanceNotRef.fir
+++ b/test/errors/parser/InstanceNotRef.fir
@@ -1,5 +1,5 @@
; RUN: firrtl -i %s -o %s.flo -x X -p c | tee %s.out | FileCheck %s
-; CHECK: FIRRTL Parsing Error: Expected a reference expression here.
+; CHECK: FIRRTL Parsing Error: Expected a statement here.
circuit Top :
module Top :
diff --git a/test/features/InitAccessor.fir b/test/features/InitAccessor.fir
index 6261ec01..5a81a62e 100644
--- a/test/features/InitAccessor.fir
+++ b/test/features/InitAccessor.fir
@@ -1,4 +1,4 @@
-; RUN: firrtl -i %s -o %s.v -X verilog -p cT 2>&1 | tee %s.out | FileCheck %s
+; RUN: firrtl -i %s -o %s.v -X verilog -p c 2>&1 | tee %s.out | FileCheck %s
;CHECK: Done!
circuit Top :
diff --git a/test/passes/jacktest/Counter.fir b/test/passes/jacktest/Counter.fir
index db2b5d62..4e23ba26 100644
--- a/test/passes/jacktest/Counter.fir
+++ b/test/passes/jacktest/Counter.fir
@@ -8,8 +8,7 @@ circuit Counter :
output tot : UInt<8>
input amt : UInt<4>
- reg T_13 : UInt<8>,clk,reset
- onreset T_13 <= UInt<8>(0)
+ reg T_13 : UInt<8>,clk,reset,UInt<8>(0)
when inc :
node T_14 = addw(T_13, amt)
node T_15 = gt(T_14, UInt<8>(255))
diff --git a/test/passes/jacktest/EnableShiftRegister.fir b/test/passes/jacktest/EnableShiftRegister.fir
index 7937d37f..d7e91665 100644
--- a/test/passes/jacktest/EnableShiftRegister.fir
+++ b/test/passes/jacktest/EnableShiftRegister.fir
@@ -8,14 +8,10 @@ circuit EnableShiftRegister :
output out : UInt<4>
input shift : UInt<1>
- reg r0 : UInt<4>,clk,reset
- onreset r0 <= UInt<4>(0)
- reg r1 : UInt<4>,clk,reset
- onreset r1 <= UInt<4>(0)
- reg r2 : UInt<4>,clk,reset
- onreset r2 <= UInt<4>(0)
- reg r3 : UInt<4>,clk,reset
- onreset r3 <= UInt<4>(0)
+ reg r0 : UInt<4>,clk,reset,UInt<4>(0)
+ reg r1 : UInt<4>,clk,reset,UInt<4>(0)
+ reg r2 : UInt<4>,clk,reset,UInt<4>(0)
+ reg r3 : UInt<4>,clk,reset,UInt<4>(0)
when shift :
r0 <= in
r1 <= r0
diff --git a/test/passes/jacktest/LFSR16.fir b/test/passes/jacktest/LFSR16.fir
index 770ac3e6..a4052623 100644
--- a/test/passes/jacktest/LFSR16.fir
+++ b/test/passes/jacktest/LFSR16.fir
@@ -7,8 +7,7 @@ circuit LFSR16 :
input clk : Clock
input reset : UInt<1>
- reg res : UInt<16>,clk,reset
- onreset res <= UInt<16>(1)
+ reg res : UInt<16>,clk,reset,UInt<16>(1)
when inc :
node T_16 = bit(res, 0)
node T_17 = bit(res, 2)
diff --git a/test/passes/jacktest/MemorySearch.fir b/test/passes/jacktest/MemorySearch.fir
index 1e07596c..1abc50a2 100644
--- a/test/passes/jacktest/MemorySearch.fir
+++ b/test/passes/jacktest/MemorySearch.fir
@@ -9,8 +9,7 @@ circuit MemorySearch :
input reset : UInt<1>
output done : UInt<1>
- reg index : UInt<3>,clk,reset
- onreset index <= UInt<3>(0)
+ reg index : UInt<3>,clk,reset,UInt<3>(0)
wire elts : UInt<4>[7]
elts[0] <= UInt<4>(0)
elts[1] <= UInt<4>(4)
@@ -19,7 +18,7 @@ circuit MemorySearch :
elts[4] <= UInt<4>(2)
elts[5] <= UInt<4>(5)
elts[6] <= UInt<4>(13)
- infer accessor elt = elts[index]
+ node elt = elts[index]
node T_35 = not(en)
node T_36 = eq(elt, target)
node T_37 = eq(index, UInt<3>(7))
diff --git a/test/passes/jacktest/Mul.fir b/test/passes/jacktest/Mul.fir
index 8a3223e7..370c84a7 100644
--- a/test/passes/jacktest/Mul.fir
+++ b/test/passes/jacktest/Mul.fir
@@ -25,5 +25,5 @@ circuit Mul :
tbl[15] <= UInt<4>(9)
node T_42 = shl(x, 2)
node T_43 = or(T_42, y)
- infer accessor T_44 = tbl[T_43]
+ node T_44 = tbl[T_43]
z <= T_44
diff --git a/test/passes/jacktest/RegisterVecShift.fir b/test/passes/jacktest/RegisterVecShift.fir
index eb2a0f34..61376a62 100644
--- a/test/passes/jacktest/RegisterVecShift.fir
+++ b/test/passes/jacktest/RegisterVecShift.fir
@@ -9,7 +9,7 @@ circuit RegisterVecShift :
input shift : UInt<1>
input ins : UInt<4>[4]
- reg delays : UInt<4>[4],clk,reset
+ reg delays : UInt<4>[4],clk,reset,delays
when reset :
wire T_33 : UInt<4>[4]
T_33[0] <= UInt<4>(0)
diff --git a/test/passes/jacktest/Rom.fir b/test/passes/jacktest/Rom.fir
index 6e4b3cc7..db76b9c7 100644
--- a/test/passes/jacktest/Rom.fir
+++ b/test/passes/jacktest/Rom.fir
@@ -22,5 +22,5 @@ circuit Rom :
r[13] <= UInt<5>(26)
r[14] <= UInt<5>(28)
r[15] <= UInt<5>(30)
- infer accessor T_39 = r[addr]
+ node T_39 = r[addr]
out <= T_39
diff --git a/test/passes/jacktest/Stack.fir b/test/passes/jacktest/Stack.fir
index ed718331..9b35c3f4 100644
--- a/test/passes/jacktest/Stack.fir
+++ b/test/passes/jacktest/Stack.fir
@@ -1,4 +1,6 @@
; RUN: firrtl -i %s -o %s.v -X verilog -p c 2>&1 | tee %s.out | FileCheck %s
+;CHECK: Finished Low Form Check
+;CHECK-NOT: stack_mem.T_32.mask <= UInt("h0")
;CHECK: Done!
circuit Stack :
module Stack :
@@ -10,16 +12,14 @@ circuit Stack :
output dataOut : UInt<32>
input dataIn : UInt<32>
- cmem stack_mem : UInt<32>[16],clk
- reg sp : UInt<5>,clk,reset
- onreset sp <= UInt<5>(0)
- reg out : UInt<32>,clk,reset
- onreset out <= UInt<32>(0)
+ cmem stack_mem : UInt<32>[16]
+ reg sp : UInt<5>,clk,reset,UInt<5>(0)
+ reg out : UInt<32>,clk,reset,UInt<32>(0)
when en :
node T_30 = lt(sp, UInt<5>(16))
node T_31 = and(push, T_30)
when T_31 :
- infer accessor T_32 = stack_mem[sp]
+ write mport T_32 = stack_mem[sp],clk
T_32 <= dataIn
node T_33 = addw(sp, UInt<1>(1))
sp <= T_33
@@ -32,6 +32,6 @@ circuit Stack :
node T_37 = gt(sp, UInt<1>(0))
when T_37 :
node T_38 = subw(sp, UInt<1>(1))
- infer accessor T_39 = stack_mem[T_38]
+ read mport T_39 = stack_mem[T_38],clk
out <= T_39
dataOut <= out
diff --git a/test/passes/jacktest/VendingMachine.fir b/test/passes/jacktest/VendingMachine.fir
index 5ecfe522..79cebbe1 100644
--- a/test/passes/jacktest/VendingMachine.fir
+++ b/test/passes/jacktest/VendingMachine.fir
@@ -8,8 +8,7 @@ circuit VendingMachine :
input clk : Clock
input reset : UInt<1>
- reg state : UInt<3>,clk,reset
- onreset state <= UInt<3>(0)
+ reg state : UInt<3>,clk,reset,UInt<3>(0)
node T_22 = eq(state, UInt<3>(0))
when T_22 :
when nickel : state <= UInt<3>(1)
diff --git a/test/passes/jacktest/gcd.fir b/test/passes/jacktest/gcd.fir
index 99667b3b..dd3443f1 100644
--- a/test/passes/jacktest/gcd.fir
+++ b/test/passes/jacktest/gcd.fir
@@ -10,8 +10,8 @@ circuit GCD :
input a : UInt<16>
input b : UInt<16>
- reg x : UInt<16>,clk,reset
- reg y : UInt<16>,clk,reset
+ reg x : UInt<16>,clk,reset,x
+ reg y : UInt<16>,clk,reset,y
node T_17 = gt(x, y)
when T_17 :
node T_18 = subw(x, y)
diff --git a/test/passes/jacktest/risc.fir b/test/passes/jacktest/risc.fir
index fdc80ee1..e4516db4 100644
--- a/test/passes/jacktest/risc.fir
+++ b/test/passes/jacktest/risc.fir
@@ -13,8 +13,7 @@ circuit Risc :
cmem file : UInt<32>[256],clk
cmem code : UInt<32>[256],clk
- reg pc : UInt<8>,clk,reset
- onreset pc <= UInt<8>(0)
+ reg pc : UInt<8>,clk,reset,UInt<8>(0)
infer accessor inst = code[pc]
node op = bits(inst, 31, 24)
node rci = bits(inst, 23, 16)
diff --git a/test/passes/lower-to-ground/bundle-vecs.fir b/test/passes/lower-to-ground/bundle-vecs.fir
index 719033cb..9821f69b 100644
--- a/test/passes/lower-to-ground/bundle-vecs.fir
+++ b/test/passes/lower-to-ground/bundle-vecs.fir
@@ -25,20 +25,20 @@ circuit top :
;CHECK: wire GEN_3 : UInt<32>
;CHECK: j_x <= GEN
;CHECK: j_y <= GEN_3
-;CHECK: node a_0_x = eqv(UInt("h0"), i)
-;CHECK: a_0_x <= mux(a_0_x, GEN_2, UInt("h0"))
-;CHECK: node a_0_y = eqv(UInt("h0"), i)
-;CHECK: a_0_y <= mux(a_0_y, GEN_1, UInt("h0"))
-;CHECK: node a_1_x = eqv(UInt("h1"), i)
-;CHECK: a_1_x <= mux(a_1_x, GEN_2, UInt("h0"))
-;CHECK: node a_1_y = eqv(UInt("h1"), i)
-;CHECK: a_1_y <= mux(a_1_y, GEN_1, UInt("h0"))
-;CHECK: node GEN_4 = eqv(UInt("h1"), i)
-;CHECK: GEN <= mux(GEN_4, a_1_x, a_0_x)
+;CHECK: node GEN_4 = eqv(UInt("h0"), i)
+;CHECK: a_0_x <= mux(GEN_4, GEN_2, UInt("h0"))
+;CHECK: node GEN_5 = eqv(UInt("h0"), i)
+;CHECK: a_0_y <= mux(GEN_5, GEN_1, UInt("h0"))
+;CHECK: node GEN_6 = eqv(UInt("h1"), i)
+;CHECK: a_1_x <= mux(GEN_6, GEN_2, UInt("h0"))
+;CHECK: node GEN_7 = eqv(UInt("h1"), i)
+;CHECK: a_1_y <= mux(GEN_7, GEN_1, UInt("h0"))
+;CHECK: node GEN_8 = eqv(UInt("h1"), i)
+;CHECK: GEN <= mux(GEN_8, a_1_x, a_0_x)
;CHECK: GEN_1 <= j_y
;CHECK: GEN_2 <= j_x
-;CHECK: node GEN_5 = eqv(UInt("h1"), i)
-;CHECK: GEN_3 <= mux(GEN_5, a_1_y, a_0_y)
+;CHECK: node GEN_9 = eqv(UInt("h1"), i)
+;CHECK: GEN_3 <= mux(GEN_9, a_1_y, a_0_y)
; CHECK: Finished Lower Types
diff --git a/test/passes/lower-to-ground/bundle.fir b/test/passes/lower-to-ground/bundle.fir
index b2ea2d63..a8f8ad78 100644
--- a/test/passes/lower-to-ground/bundle.fir
+++ b/test/passes/lower-to-ground/bundle.fir
@@ -4,7 +4,7 @@ circuit top :
module m :
input a : { x : UInt<5>, flip y: SInt<5>}
output b : { x : UInt<5>, flip y: SInt<5>}
- a.y <= UInt(0)
+ a.y <= SInt(0)
b.x <= UInt(0)
module top :
input c : { x : UInt<5>[5], flip y : { x : UInt<5>[3], flip y : SInt<5> } }
diff --git a/test/passes/split-exp/split-in-when.fir b/test/passes/split-exp/split-in-when.fir
index a6d0a2c5..06a3cc53 100644
--- a/test/passes/split-exp/split-in-when.fir
+++ b/test/passes/split-exp/split-in-when.fir
@@ -13,12 +13,13 @@ circuit Top :
when bit(subw(a,c),3) : out <= mux(eqv(bits(UInt(32),4,0),UInt(13)),addw(a,addw(b,c)),subw(c,b))
-;CHECK: node out_1 = subw(a, c)
-;CHECK: node out_2 = bit(out_1, 3)
-;CHECK: node out_3 = eqv(UInt("h0"), UInt("hd"))
-;CHECK: node out_4 = addw(b, c)
-;CHECK: node out_5 = addw(a, out_4)
-;CHECK: node out_6 = subw(c, b)
-;CHECK: node out_7 = mux(out_3, out_5, out_6)
+;CHECK: node GEN = subw(a, c)
+;CHECK: node GEN_1 = bit(GEN, 3)
+;CHECK: node GEN_2 = eqv(UInt("h0"), UInt("hd"))
+;CHECK: node GEN_3 = addw(b, c)
+;CHECK: node GEN_4 = addw(a, GEN_3)
+;CHECK: node GEN_5 = subw(c, b)
+;CHECK: node GEN_6 = mux(GEN_2, GEN_4, GEN_5)
+;CHECK: out <= mux(GEN_1, GEN_6, out)
;CHECK: Finished Split Expressions