diff options
| author | azidar | 2015-05-05 17:37:27 -0700 |
|---|---|---|
| committer | azidar | 2015-05-05 17:37:27 -0700 |
| commit | 791334cced721789fad180b6479cfa783963032f (patch) | |
| tree | 057c3bf7bbd4e2a37daa5cdaec77a17d479108d9 | |
| parent | 5b23a9a645db190cea69f30aa1cd370c257fe774 (diff) | |
Added a bunch of tests. In the middle of implementing check kinds and check types. Does not compile
| -rw-r--r-- | TODO | 1 | ||||
| -rw-r--r-- | notes/architecture.05.05.15.txt | 4 | ||||
| -rw-r--r-- | notes/chisel.05.04.15.txt | 28 | ||||
| -rw-r--r-- | src/main/stanza/errors.stanza | 359 | ||||
| -rw-r--r-- | src/main/stanza/firrtl-ir.stanza | 6 | ||||
| -rw-r--r-- | src/main/stanza/passes.stanza | 41 | ||||
| -rw-r--r-- | test/errors/high-form/InstanceNotModule.fir | 8 | ||||
| -rw-r--r-- | test/errors/high-form/InvalidLOC.fir | 18 | ||||
| -rw-r--r-- | test/errors/high-form/InvalidSubexp.fir | 9 | ||||
| -rw-r--r-- | test/errors/high-form/NegUInt.fir | 7 | ||||
| -rw-r--r-- | test/errors/high-form/Prefix.fir | 9 | ||||
| -rw-r--r-- | test/errors/high-form/Unique.fir | 16 | ||||
| -rw-r--r-- | test/errors/high-form/WrongReset.fir | 15 | ||||
| -rw-r--r-- | test/errors/parser/InstanceNotRef.fir | 8 |
14 files changed, 420 insertions, 109 deletions
@@ -108,6 +108,7 @@ Verilog backend - put stuff in posedge clock, not assign statements, for speedup Annotate mems with location stuff Coverage tests, such as statespace or specific instances (like asserts, sort of) check all predicates of whens +Generate a ROM, and index with cycle counter, and dynamically check any wire on a given cycle ======== FIRRTL++ ========= Variable size FIFOs diff --git a/notes/architecture.05.05.15.txt b/notes/architecture.05.05.15.txt new file mode 100644 index 00000000..b66d663d --- /dev/null +++ b/notes/architecture.05.05.15.txt @@ -0,0 +1,4 @@ +Omar/Ofar? wrote genesis and is Dave's boss +Big problem is how to integrate different verilog, and put them all together to make it work + Can chisel help? +Different clock domains? L2 should be in a different domain diff --git a/notes/chisel.05.04.15.txt b/notes/chisel.05.04.15.txt new file mode 100644 index 00000000..34ac637f --- /dev/null +++ b/notes/chisel.05.04.15.txt @@ -0,0 +1,28 @@ +=========== FIRRTL PASSES ============== + +Parser : Parses text file and provides some error checking. + i: Parses the text file into an in-memory representation of the FIRRTL graph (tree). + +: Incorrect syntax correctly crashes the parser with an error message. + -: Error messages could be improved +High Form Check : Ensures file has correct high firrtl form. + i: Ensures that initial file upholds various non-syntactic invariants + +: Some have been implemented. Current invariants not checked will likely crash the compiler in a later stage. + -: More to implemented (grunt work). +Temp Elimination : Inline poorly-named single-assignment values. + ;Allows betterTo make the Chisel frontend simpler, we emit no nested expressions, and generate a lot of temps with non-intuitive names. +Working IR : Replaces some IR nodes with working IR nodes with useful fields +Make Explicit Reset : If not declared, reset is added to every module +Resolve Kinds : Populates WRefs with the 'kind of reference' +Infer Types : All type fields are inferred +Type Check : All types are checked + -: Not implemented +Resolve Genders : Genders of WRef and WAccessor is filled in +Expand Accessors : Accessors to non-memory vectors are expanded to ConnectFromIndexed and ConnectToIndexed +Lower To Ground : All types are lowered to ground types by expanding all Indexes and Subfields that are not instances +Expand Indexed Connects : All ConnectFromIndexed and ConnectToIndexed are expanded to whens +Expand Whens : Basic interpreter to calculate single assignment with muxes. +Infer Widths : Width inferences +Inline Instances +Split Expressions : All nested expressions are expanded to single-assignment nodes with a relative name +Real IR : All working IR nodes are removed +To Flo : Flo is emitted diff --git a/src/main/stanza/errors.stanza b/src/main/stanza/errors.stanza index b0dbca68..fb537083 100644 --- a/src/main/stanza/errors.stanza +++ b/src/main/stanza/errors.stanza @@ -7,100 +7,95 @@ defpackage firrtl/errors : import firrtl/passes import firrtl-main +; TODO +; make sure it compiles, write tests, look over code to make sure its right ;========== ALL CHECKS ================= -;CAUGHT IN PARSER -; No nested modules <- parser -; Only modules in circuit (no statements or expressions) <- parser - -;CAUGHT in HIGH FORM CHECK -; Unique names per module -; No name can be a prefix of any other name. -; Can only connect to a Ref or Subfield or Index -; UInt only has positive ints -; all references are declared -; mems cannot be a bundle with flips -; cannot connect to Register or ReadPort - -;AFTER KIND RESOLUTION -; Cannot connect directly to a mem ever -; onreset can only handle a register - -;AFTER TYPE INFERENCE -; expression in pad must be a ground type -; Subfields are only on bundles, before type inference <- need to not error, just do unknown-type -; node's value cannot be a bundle with a flip in it -; 2nd arg in dshr/l must be UInt -; pred in conditionally must be of type UInt -; Type checking +;PARSER CHECK +; * No nested modules <- parser +; * Only modules in circuit (no statements or expressions) <- parser +; * Module must be a reference in inst declaration + +;AFTER GENDER INFERENCE +; 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 ;AFTER WIDTH INFERENCE -; No names -; No Unknowns -; All widths are positive -; Pad's width is greater than value's width -; pad's width is greater than value's width +; o No names +; o No Unknowns +; o All widths are positive +; o Pad's width is greater than value's width +; o pad's width is greater than value's width +; o widths are large enough to contain value ;AFTER LOWERING -; All things connect to once - -; ?? -; No combinational loops -; cannot connect to a pad, or a register. only connct to a reference +; o All things connect to once +; o no reg +; o no accessors -definterface HighFormException <: Exception -defn HighFormException (s:String) : - new HighFormException : - defmethod print (o:OutputStream, this) : - print(o, s) +;AFTER ?????? +; o No combinational loops +; o cannot connect to a pad, or a register. only connct to a reference -defn HighFormExceptions (xs:Streamable<HighFormException>) : - HighFormException(string-join(xs, "\n")) +;================= High Form Check ========================== +; * Subexps of Subfield and Index can only be subfields, index, or refs +; * Can only connect to a Ref or Subfield or Index or WritePort +; * A module has the same name as main of circuit +; * mems cannot be a bundle with flips +; * instance module must have the same name as a defined module +; * reset must be UInt<1> +; * Unique names per module +; * No name can be a prefix of any other name. +; * all references are declared +; * UInt only has positive ints -defn NotUnique (info:FileInfo|False, name:Symbol) : - HighFormException $ string-join $ +;----------------- Errors ------------------------ +defn NotUnique (info:FileInfo, name:Symbol) : + PassException $ string-join $ [info ": Reference " name " does not have a unique name."] -defn IsPrefix (info:FileInfo|False, name1:Symbol, name2:Symbol) : - HighFormException $ string-join $ +defn IsPrefix (info:FileInfo, name1:Symbol, name2:Symbol) : + PassException $ string-join $ [info ": Reference " name1 " and " name2 " share a prefix."] -defn InvalidLOC (info:FileInfo|False) : - HighFormException $ string-join $ +defn InvalidLOC (info:FileInfo) : + PassException $ string-join $ [info ": Invalid connect to an expression that is not a reference or a WritePort."] -defn NegUInt (info:FileInfo|False) : - HighFormException $ string-join $ - [info ": UInt has a negative value."] +defn NegUInt (info:FileInfo) : + PassException $ string-join $ + [info ": UIntValue cannot be negative."] -defn UndeclaredReference (info:FileInfo|False, name:Symbol) : - HighFormException $ string-join $ +defn UndeclaredReference (info:FileInfo, name:Symbol) : + PassException $ string-join $ [info ": Reference " name " is not declared."] -defn MemWithFlip (info:FileInfo|False, name:Symbol) : - HighFormException $ string-join $ +defn MemWithFlip (info:FileInfo, name:Symbol) : + PassException $ string-join $ [info ": Memory " name " cannot be a bundle type with flips."] -defn InvalidSubfield (info:FileInfo|False, name:Symbol) : - HighFormException $ string-join $ +defn InvalidSubfield (info:FileInfo) : + PassException $ string-join $ [info ": Invalid subfield access to non-reference."] -defn InvalidIndex (info:FileInfo|False, name:Symbol) : - HighFormException $ string-join $ +defn InvalidIndex (info:FileInfo) : + PassException $ string-join $ [info ": Invalid index access to non-reference."] -defn NoTopModule (info:FileInfo|False, name:Symbol) : - HighFormException $ string-join $ +defn NoTopModule (info:FileInfo, name:Symbol) : + PassException $ string-join $ [info ": A single module must be named " name "."] -defn InstNotModule (info:FileInfo|False, name:Symbol) : - HighFormException $ string-join $ - [info ": The referenced module in the instance declaration, " name ", is not a reference."] +defn ModuleNotDefined (info:FileInfo, name:Symbol) : + PassException $ string-join $ + [info ": Module " name " is not defined."] -defn ModuleNotDefined (info:FileInfo|False, name:Symbol) : - HighFormException $ string-join $ - [info ": The referenced module in the instance declaration, " name ", is not defined."] +defn WrongReset (info:FileInfo, name:Symbol) : + PassException $ string-join $ + [info ": Module " name " has a reset that is not of type UInt<1>."] -;================ Check Helper Functions ============== +;---------------- Helper Functions -------------- defn has-flip? (t:Type) -> True|False : var has? = false defn find-flip (t:Type) -> Type : @@ -136,46 +131,80 @@ defn is-prefix? (s1:Symbol,s2:Symbol) -> True|False : if s1*[length(s2*)] != '$' : is? = false if length(s1*) < length(s2*) : if s2*[length(s1*)] != '$' : is? = false + if length(s1*) == length(s2*) : + is? = false is? -;================= High Form Check ========================== -;CAUGHT in HIGH FORM CHECK -; o Unique names per module -; o No name can be a prefix of any other name. -; o Can only connect to a Ref or Subfield or Index -; o UInt only has positive ints -; o all references are declared -; o cannot connect to Register or ReadPort -; * A module has the same name as main of circuit -; * mems cannot be a bundle with flips -; o instance module must be a reference with same name as defined module -; o reset must be UInt<1> - +;--------------- Check High Form Pass ------------------- public defn check-high-form (c:Circuit) -> Circuit : - val errors = Vector<HighFormException>() + val errors = Vector<PassException>() + + defn check-valid-loc (info:FileInfo,e:Expression) -> False : + match(e) : + (e:UIntValue|SIntValue|DoPrim|ReadPort|Register|Pad) : + add(errors,InvalidLOC(info)) + (e) : false + + defn check-high-form-e (info:FileInfo,e:Expression,names:Vector<Symbol>) -> Expression : + match(map(check-high-form-e{info,_,names},e)) : + (e:Ref) : + if not contains?(name(e),names) : + add(errors,UndeclaredReference(info,name(e))) + (e:Subfield) : + match(exp(e)) : + (e:Ref|Subfield|Index) : false + (e) : add(errors,InvalidSubfield(info)) + (e:Index) : + match(exp(e)) : + (e:Ref|Subfield|Index) : false + (e) : add(errors,InvalidIndex(info)) + (e:UIntValue) : + if value(e) < 0 : + add(errors,NegUInt(info)) + (e) : false + e defn check-high-form-s (s:Stmt,names:Vector<Symbol>) -> Stmt : - defn check-name (info:FileInfo|False,name:Symbol) -> False : + defn check-name (info:FileInfo,name:Symbol) -> False : if contains?(name,names) : add(errors,NotUnique(info,name)) val prefix = is-prefix?(name,names) if prefix typeof Symbol : add(errors,IsPrefix(info,name,prefix as Symbol)) map{check-high-form-s{_,names},_} $ { - match(s) : - (s:DefWire|DefRegister) : check-name(info!(s),name(s)) + match(map(check-high-form-e{info!(s),_,names},s)) : + (s:DefWire|DefRegister) : + check-name(info!(s),name(s)) + add(names,name(s)) (s:DefMemory) : check-name(info!(s),name(s)) + add(names,name(s)) if has-flip?(type(s)) : add(errors, MemWithFlip(info!(s), name(s))) (s:DefInstance) : - if not (module(s) typeof Ref) : add(errors, InstNotModule(info!(s),name(s))) - else : - if not contains?(name(module(s) as Ref),map(name,modules(c))) : - add(errors, ModuleNotDefined(info!(s),name(s))) + if not contains?(name(module(s) as Ref),map(name,modules(c))) : + add(errors, ModuleNotDefined(info!(s),name(module(s) as Ref))) + add(names,name(s)) + (s:DefNode) : + add(names,name(s)) + (s:DefAccessor) : + add(names,name(s)) + (s:Connect) : + check-valid-loc(info!(s),loc(s)) (s) : false s }() defn check-high-form-m (m:Module) -> False : val names = Vector<Symbol>() + for p in ports(m) do : + if name(p) == `reset : + if direction(p) == OUTPUT : + add(errors,WrongReset(info!(m),name(m))) + else : + if type(p) typeof UIntType : + if width(type(p) as UIntType) != IntWidth(1) : + add(errors,WrongReset(info!(m),name(m))) + else : + add(errors,WrongReset(info!(m),name(m))) + check-high-form-s(body(m),names) false @@ -184,7 +213,159 @@ public defn check-high-form (c:Circuit) -> Circuit : if name(m) == main(c) : number-top-m = number-top-m + 1 check-high-form-m(m) if number-top-m != 1 : add(errors,NoTopModule(info!(c),main(c))) - throw(HighFormExceptions(errors)) when not empty?(errors) + 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 + +;----------------- Errors --------------------- +defn NotMem (info:FileInfo, name:Symbol) : + PassException $ string-join $ + [info ": Reference " name " must be a mem."] + +defn IsMem (info:FileInfo, name:Symbol) : + PassException $ string-join $ + [info ": Reference " name " cannot be a mem."] + +defn OnResetNotReg (info:FileInfo, name:Symbol) : + PassException $ string-join $ + [info ": Illegal on-reset to non-reg reference " name "."] + +;----------------- 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<PassExceptioPassException>() + defn check-not-mem (info:FileInfo,e:Expression) -> False : + match(map(check-not-mem{info,_},e)) : + (e:WRef) : if kind(e) == MemKind() : add(errors,IsMem(info,name(e))) + (e:WSubfield) : check-not-mem(exp(e)) + (e:WIndex) : check-not-mem(exp(e)) + (e) : false + defn check-is-reg (info:FileInfo,e:Expression) -> False : + match(map(check-is-reg{info,_},e)) : + (e:WRef) : if kind(e) != RegKind() : add(errors,OnResetNotReg(info,name(e))) + (e:WSubfield) : check-is-reg(exp(e)) + (e:WIndex) : check-is-reg(exp(e)) + (e) : false + defn check-is-mem (info:FileInfo,e:Expression) -> False : + match(map(check-is-mem{info,_},e)) : + (e:WRef) : if kind(e) != MemKind() : add(errors,NotMem(info,name(e))) + (e:WSubfield) : check-is-mem(exp(e)) + (e:WIndex) : check-is-mem(exp(e)) + (e) : false + + defn check-kinds-e (info:FileInfo,e:Expression) -> False : + match(map(check-kinds-e{info,_},e)) : + (e:ReadPort) : + check-is-mem(info,mem(e)) + check-not-mem(info,index(e)) + check-not-mem(info,enable(e)) + (e:WritePort) : + check-is-mem(info,mem(e)) + check-not-mem(info,index(e)) + check-not-mem(info,enable(e)) + (e:Pad) : + check-not-mem(info,value(e)) + (e) : map(check-not-mem{info,_},e) + defn check-kinds-s (s:Stmt) -> Stmt : + map{check-kinds-s,_} $ { + match(map(check-kinds-e{info!(s),_},s)) : + (s:DefNode) : check-not-mem(info!(s),value(s)) + (s:DefAccessor) : check-not-mem(info!(s),index(s)) + (s:Conditionally) : check-not-mem(info!(s),pred(s)) + (s:Connect) : + 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 + s }() + + for m in modules(c) do : + check-kinds-s(body(m)) + throw(PassExceptions(errors)) when not empty?(errors) c +;==================== CHECK TYPES ===================== +; o expression in pad must be a ground type +; 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 + +;----------------- Errors --------------------- +defn SubfieldNotInBundle (info:FileInfo, name:Symbol) : + PassException $ string-join $ + [info ": Subfield " name " is not in bundle."] + +;---------------- Helper Functions -------------- +defn equal? (t1:Type,t2:Type) -> True|False : + match(t1,t2) : + (t1:UIntType,t2:UIntType) : true + (t1:SIntType,t2:SIntType) : true + (t1:BundleType,t2:BundleType) : + val 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 u() -> UIntType : UIntType(UnknownWidth()) +defn s() -> SIntType : SIntType(UnknownWidth()) + +;----------------- Check Types Pass --------------------- +public defn check-types (c:Circuit) -> Circuit : + val errors = Vector<PassExceptioPassException>() + defn check-types-e (info:FileInfo,e:Expression) -> Expression + match(map(check-types-e{info,_},s)) : + (e:WRef) : e + (e:WSubfield) : + match(type(exp(e))) : + (t:BundleType) : + val ft = for p in fields(v) find : name(p) == s + 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) + (e:ReadPort|WritePort) : + if type(index(e)) != u() : add(errors,IndexNotUInt(info)) + if type(enable(e)) != u() : add(errors,EnableNotUInt(info)) + (e:Register) : + if type(enable(e)) != u() : add(errors,EnableNotUInt(info)) + (e:Pad) : + val t = type(value(e)) + if not (t == u() or t == s()) : add(errors,PadNotGround(info)) + (e:UIntValue|SIntValue) : false + e + defn check-types-s (s:Stmt) -> Stmt : + map{check-types-s,_} $ + match(map(check-types-e,s)) : + (s:Connect|OnReset) : + if type(loc(s)) == type(exp(s)) : add(errors,InvalidConnect(info!(s))) + (s:Conditionally) : + if type(pred(s)) != u() : add(errors,PredNotUInt(info)) + (s) : false + s + + for m in modules(c) do : + check-types-s(body(m)) + throw(PassExceptions(errors)) when not empty?(errors) + c diff --git a/src/main/stanza/firrtl-ir.stanza b/src/main/stanza/firrtl-ir.stanza index 67d2c2d9..f8f4abdb 100644 --- a/src/main/stanza/firrtl-ir.stanza +++ b/src/main/stanza/firrtl-ir.stanza @@ -2,8 +2,8 @@ defpackage firrtl/ir2 : import core import verse -public defmulti info! (x:?) -> False -public defmethod info! (x:?) : false +public defmulti info! (x:?) -> FileInfo +public defmethod info! (x:?) : FileInfo() public definterface Direction public val INPUT = new Direction @@ -239,5 +239,3 @@ public defstruct Module : public defstruct Circuit : modules: List<Module> main: Symbol - - diff --git a/src/main/stanza/passes.stanza b/src/main/stanza/passes.stanza index c8a4e15c..8e15f0e6 100644 --- a/src/main/stanza/passes.stanza +++ b/src/main/stanza/passes.stanza @@ -7,12 +7,15 @@ defpackage firrtl/passes : import firrtl-main import firrtl/errors -;============== EXCEPTIONS ================================= -defclass PassException <: Exception -defn PassException (msg:String) : - new PassException : - defmethod print (o:OutputStream, this) : - print(o, msg) +;============== Exceptions ===================== +public definterface PassException <: Exception +public defn PassException (s:String) : + new PassException : + defmethod print (o:OutputStream, this) : + print(o, s) + +public defn PassExceptions (xs:Streamable<PassException>) : + PassException(string-join(xs, "\n")) ;=============== WORKING IR ================================ definterface Kind @@ -26,7 +29,6 @@ defstruct NodeKind <: Kind ; All elems except structural memory, wires defstruct MemKind <: Kind defstruct ModuleKind <: Kind -defstruct StructuralMemKind <: Kind ; Separate kind because need special treatment defstruct AccessorKind <: Kind public definterface Gender @@ -183,7 +185,6 @@ defmethod print (o:OutputStream, k:Kind) : (k:NodeKind) : "n" (k:ModuleKind) : "module" (k:InstanceKind) : "inst" - (k:StructuralMemKind) : "smem" (k:ReadAccessorKind) : "racc" (k:WriteAccessorKind) : "wacc" @@ -434,7 +435,7 @@ defn bundle-field-type (v:Type,s:Symbol) -> Type : val ft = for p in fields(v) find : name(p) == s if ft != false : type(ft as Field) else : UnknownType() - (v) : error(string-join(["Accessing subfield " s " on a non-Bundle type."])) + (v) : UnknownType() defn get-vector-subtype (v:Type) -> Type : match(v) : @@ -2018,22 +2019,30 @@ public defn run-passes (c: Circuit, p: List<Char>,file:String) : if PRINT-CIRCUITS : print(c*) if PRINT-CIRCUITS : println-all(["Finished " name "\n"]) - ; Early passes: - ; If modules have a reset defined, must be an INPUT and UInt(1) if contains(p,'X') or contains(p,'A') : do-stage("High Form Check", check-high-form) if contains(p,'X') or contains(p,'a') : do-stage("Temp Elimination", temp-elimination) if contains(p,'X') or contains(p,'b') : do-stage("Working IR", to-working-ir) + if contains(p,'X') or contains(p,'c') : do-stage("Make Explicit Reset", make-explicit-reset) + if contains(p,'X') or contains(p,'d') : do-stage("Resolve Kinds", resolve-kinds) + if contains(p,'X') or contains(p,'D') : do-stage("Check Kinds", check-kinds) + if contains(p,'X') or contains(p,'e') : do-stage("Infer Types", infer-types) if contains(p,'X') or contains(p,'f') : do-stage("Resolve Genders", resolve-genders) - if contains(p,'X') or contains(p,'g') : do-stage("Expand Accessors", expand-accessors) - if contains(p,'X') or contains(p,'h') : do-stage("Lower To Ground", lower-to-ground) + if contains(p,'X') or contains(p,'g') : do-stage("Expand Accessors", expand-accessors) ;mem kind + if contains(p,'X') or contains(p,'h') : do-stage("Lower To Ground", lower-to-ground) ;inst kind if contains(p,'X') or contains(p,'i') : do-stage("Expand Indexed Connects", expand-connect-indexed) - if contains(p,'X') or contains(p,'k') : do-stage("Expand Whens", expand-whens) - if contains(p,'X') or contains(p,'l') : do-stage("Infer Widths", infer-widths) - if contains(p,'X') or contains(p,'m') : do-stage("Inline Instances", inline-instances) + +; make sure no bundle types + if contains(p,'X') or contains(p,'k') : do-stage("Expand Whens", expand-whens) ; requires types, lowering + + if contains(p,'X') or contains(p,'l') : do-stage("Infer Widths", infer-widths) ; requires lowering, expand whens + + if contains(p,'X') or contains(p,'m') : do-stage("Inline Instances", inline-instances) ;inst kind + if contains(p,'X') or contains(p,'n') : do-stage("Split Expressions", split-exp) + if contains(p,'X') or contains(p,'o') : do-stage("Real IR", to-real-ir) if contains(p,'X') or contains(p,'F') : do-stage("To Flo", emit-flo{file,_}) println("Done!") diff --git a/test/errors/high-form/InstanceNotModule.fir b/test/errors/high-form/InstanceNotModule.fir new file mode 100644 index 00000000..3b228d37 --- /dev/null +++ b/test/errors/high-form/InstanceNotModule.fir @@ -0,0 +1,8 @@ +; RUN: firrtl -i %s -o %s.flo -x X -p c | tee %s.out | FileCheck %s +; CHECK: Module Top2 is not defined. + +circuit Top : + module Top : + wire x : UInt<1> + inst t of Top2 + diff --git a/test/errors/high-form/InvalidLOC.fir b/test/errors/high-form/InvalidLOC.fir new file mode 100644 index 00000000..5270577b --- /dev/null +++ b/test/errors/high-form/InvalidLOC.fir @@ -0,0 +1,18 @@ +; RUN: firrtl -i %s -o %s.flo -x X -p c | tee %s.out | FileCheck %s +; CHECK: Invalid connect to an expression that is not a reference or a WritePort. +; CHECK: Invalid connect to an expression that is not a reference or a WritePort. +; CHECK: Invalid connect to an expression that is not a reference or a WritePort. +; CHECK: Invalid connect to an expression that is not a reference or a WritePort. +; CHECK: Invalid connect to an expression that is not a reference or a WritePort. +; CHECK: Invalid connect to an expression that is not a reference or a WritePort. + +circuit Top : + module Top : + wire x : UInt + add(x,x) := UInt(1) + Pad(x,?) := UInt(1) + Register(x,x) := UInt(1) + ReadPort(x,x,x) := UInt(1) + UInt(1) := UInt(1) + SInt(1) := UInt(1) + diff --git a/test/errors/high-form/InvalidSubexp.fir b/test/errors/high-form/InvalidSubexp.fir new file mode 100644 index 00000000..85fad6fb --- /dev/null +++ b/test/errors/high-form/InvalidSubexp.fir @@ -0,0 +1,9 @@ +; RUN: firrtl -i %s -o %s.flo -x X -p c | tee %s.out | FileCheck %s +; CHECK: Invalid index access to non-reference. +; CHECK: Invalid subfield access to non-reference. + +circuit Top : + module Top : + wire x : UInt<4> + add(x,x)[10] := UInt(1) + add(x,x).x := UInt(1) diff --git a/test/errors/high-form/NegUInt.fir b/test/errors/high-form/NegUInt.fir new file mode 100644 index 00000000..a92da633 --- /dev/null +++ b/test/errors/high-form/NegUInt.fir @@ -0,0 +1,7 @@ +; RUN: firrtl -i %s -o %s.flo -x X -p c | tee %s.out | FileCheck %s +; CHECK: UIntValue cannot be negative. + +circuit Top : + module Top : + wire x : UInt<4> + x := UInt(-2) diff --git a/test/errors/high-form/Prefix.fir b/test/errors/high-form/Prefix.fir new file mode 100644 index 00000000..17be36f6 --- /dev/null +++ b/test/errors/high-form/Prefix.fir @@ -0,0 +1,9 @@ +; RUN: firrtl -i %s -o %s.flo -x X -p c | tee %s.out | FileCheck %s +; CHECK: Reference x$y and x share a prefix. + +circuit Top : + module Top : + wire x : UInt<1> + wire x$y : UInt<2> + + diff --git a/test/errors/high-form/Unique.fir b/test/errors/high-form/Unique.fir new file mode 100644 index 00000000..de95e6cd --- /dev/null +++ b/test/errors/high-form/Unique.fir @@ -0,0 +1,16 @@ +; RUN: firrtl -i %s -o %s.flo -x X -p c | tee %s.out | FileCheck %s + +; CHECK: Reference x does not have a unique name. +; CHECK: Reference p does not have a unique name. +; CHECK-NOT: Reference q does not have a unique name. + +circuit Top : + module Top : + wire x : UInt<1> + wire x : UInt<2> + wire p : UInt<3> + wire q : UInt<3> + when p : + wire p : UInt<4> + module Other : + wire q : UInt<3> diff --git a/test/errors/high-form/WrongReset.fir b/test/errors/high-form/WrongReset.fir new file mode 100644 index 00000000..c936f0b3 --- /dev/null +++ b/test/errors/high-form/WrongReset.fir @@ -0,0 +1,15 @@ +; RUN: firrtl -i %s -o %s.flo -x X -p c | tee %s.out | FileCheck %s + +; CHECK: Module Top has a reset that is not of type UInt<1>. +; CHECK: Module B has a reset that is not of type UInt<1>. +; CHECK: Module C has a reset that is not of type UInt<1>. + +circuit Top : + module Top : + input reset : SInt<1> + module B : + input reset : UInt + module C : + output reset : UInt<1> + + diff --git a/test/errors/parser/InstanceNotRef.fir b/test/errors/parser/InstanceNotRef.fir new file mode 100644 index 00000000..a6996fee --- /dev/null +++ b/test/errors/parser/InstanceNotRef.fir @@ -0,0 +1,8 @@ +; 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. + +circuit Top : + module Top : + wire x : UInt<1> + inst t of add(UInt(1),UInt(1)) + |
