diff options
| author | azidar | 2016-01-07 17:15:31 -0800 |
|---|---|---|
| committer | azidar | 2016-01-16 14:28:18 -0800 |
| commit | 4569194392122ae4715549b2f0b9fffff051b278 (patch) | |
| tree | ecd079cefa6fb69d1f8c75bc0e75e38599bc0da4 | |
| parent | 2d583abda146dad8e0260928dcb19ad7136216b6 (diff) | |
Fixed a bunch of tests, and minor bugs
30 files changed, 753 insertions, 731 deletions
@@ -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 Binary files differindex 8dac93d9..ffbfc056 100644 --- a/spec/spec.pdf +++ b/spec/spec.pdf 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 |
