diff options
| author | jackbackrack | 2015-05-02 23:56:46 -0700 |
|---|---|---|
| committer | jackbackrack | 2015-05-02 23:56:46 -0700 |
| commit | 1b57cff7dfc245dd0a0f7a1a591db6dc04e245e0 (patch) | |
| tree | b9be5d3c14ef853ed9104c31392973917ea4f2e8 /src | |
| parent | 07dd1e577a5f605388bc18c37802c8c9a00801a6 (diff) | |
| parent | 2006604530fb8fd214fe4e8e182bedacd71b49b3 (diff) | |
merge
Diffstat (limited to 'src')
| -rw-r--r-- | src/main/stanza/errors.stanza | 139 | ||||
| -rw-r--r-- | src/main/stanza/firrtl-ir.stanza | 5 | ||||
| -rw-r--r-- | src/main/stanza/firrtl-main.stanza | 1 | ||||
| -rw-r--r-- | src/main/stanza/firrtl-test-main.stanza | 1 | ||||
| -rw-r--r-- | src/main/stanza/passes.stanza | 103 | ||||
| -rw-r--r-- | src/main/stanza/primop.stanza | 1 |
6 files changed, 216 insertions, 34 deletions
diff --git a/src/main/stanza/errors.stanza b/src/main/stanza/errors.stanza new file mode 100644 index 00000000..43575854 --- /dev/null +++ b/src/main/stanza/errors.stanza @@ -0,0 +1,139 @@ +defpackage firrtl/errors : + import core + import verse + import firrtl/ir2 + import firrtl/ir-utils + import firrtl/primops + import firrtl/passes + import firrtl-main + +;========== 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 + +;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 + +;AFTER LOWERING +; All things connect to once + +; ?? +; No combinational loops +; cannot connect to a pad, or a register. only connct to a reference + +definterface HighFormException <: Exception +defn HighFormException (s:String) : + new HighFormException : + defmethod print (o:OutputStream, this) : + print(o, s) + +defn HighFormExceptions (xs:Streamable<HighFormException>) : + HighFormException(string-join(xs, "\n")) + +defn NotUnique (info:FileInfo|False, name:Symbol) : + HighFormException $ string-join $ + [info ": Reference " name " does not have a unique name."] + +defn IsPrefix (info:FileInfo|False, name:Symbol, prefix:Symbol, dec:FileInfo|False) : + HighFormException $ string-join $ + [info ": Reference " name " is an invalid name because the prefix " prefix " is declared at " dec "."] + +defn InvalidLOC (info:FileInfo|False) : + HighFormException $ 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 UndeclaredReference (info:FileInfo|False, name:Symbol) : + HighFormException $ string-join $ + [info ": Reference " name " is not declared."] + +defn MemWithFlip (info:FileInfo|False, name:Symbol) : + HighFormException $ string-join $ + [info ": Memory " name " cannot be a bundle type with flips."] + +defn InvalidSubfield (info:FileInfo|False, name:Symbol) : + HighFormException $ string-join $ + [info ": Invalid subfield access to non-reference."] + +defn InvalidIndex (info:FileInfo|False, name:Symbol) : + HighFormException $ string-join $ + [info ": Invalid index access to non-reference."] + +defn NoTopModule (info:FileInfo|False, name:Symbol) : + HighFormException $ string-join $ + [info ": A single module must be named " name "."] + +;================ Check Helper Functions ============== +defn has-flip? (t:Type) -> True|False : + var has? = false + defn find-flip (t:Type) -> Type : + match(t) : + (t:BundleType) : + for f in fields(t) do : + if flip(f) == REVERSE : has? = true + t + (t) : t + find-flip(t) + map(find-flip,t) + has? +;================= 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 + +public defn check-high-form (c:Circuit) -> Circuit : + val errors = Vector<HighFormException>() + + defn check-high-form-s (s:Stmt) -> Stmt : + map{check-high-form-s,_} $ match(s) : + (s:DefMemory) : + if has-flip?(type(s)) : add(errors, MemWithFlip(info!(s), name(s))) + s + (s) : s + defn check-high-form-m (ms:List<Module>) -> False : + var number-top-m = 0 + for m in ms do : + if name(m) == main(c) : number-top-m = number-top-m + 1 + check-high-form-s(body(m)) + if number-top-m != 1 : add(errors,NoTopModule(info!(c),main(c))) + + check-high-form-m(modules(c)) + throw(HighFormExceptions(errors)) when not empty?(errors) + c + + diff --git a/src/main/stanza/firrtl-ir.stanza b/src/main/stanza/firrtl-ir.stanza index 63a28211..67d2c2d9 100644 --- a/src/main/stanza/firrtl-ir.stanza +++ b/src/main/stanza/firrtl-ir.stanza @@ -2,6 +2,9 @@ defpackage firrtl/ir2 : import core import verse +public defmulti info! (x:?) -> False +public defmethod info! (x:?) : false + public definterface Direction public val INPUT = new Direction public val OUTPUT = new Direction @@ -236,3 +239,5 @@ public defstruct Module : public defstruct Circuit : modules: List<Module> main: Symbol + + diff --git a/src/main/stanza/firrtl-main.stanza b/src/main/stanza/firrtl-main.stanza index 92bb066f..efc6a7d0 100644 --- a/src/main/stanza/firrtl-main.stanza +++ b/src/main/stanza/firrtl-main.stanza @@ -8,6 +8,7 @@ #include("ir-parser.stanza") #include("passes.stanza") #include("primop.stanza") +#include("errors.stanza") defpackage firrtl-main : import core diff --git a/src/main/stanza/firrtl-test-main.stanza b/src/main/stanza/firrtl-test-main.stanza index f929455d..ca9bfa33 100644 --- a/src/main/stanza/firrtl-test-main.stanza +++ b/src/main/stanza/firrtl-test-main.stanza @@ -8,6 +8,7 @@ #include("ir-parser.stanza") #include("passes.stanza") #include("primop.stanza") +#include("errors.stanza") defpackage firrtl-main : import core diff --git a/src/main/stanza/passes.stanza b/src/main/stanza/passes.stanza index b14a96e3..910b7f3d 100644 --- a/src/main/stanza/passes.stanza +++ b/src/main/stanza/passes.stanza @@ -5,6 +5,7 @@ defpackage firrtl/passes : import firrtl/ir-utils import firrtl/primops import firrtl-main + import firrtl/errors ;============== EXCEPTIONS ================================= defclass PassException <: Exception @@ -838,7 +839,9 @@ defn lower (body:Stmt) -> Stmt : switch fn ([x,y]) : lgender == x and rgender == y : [FEMALE,MALE] : ConnectToIndexed(index(s),locs,r*) [MALE,FEMALE] : ConnectFromIndexed(index(s),r*,locs) - (s:Begin|Conditionally|EmptyStmt) : map(lower-stmt,s) + (s:Conditionally) : + Conditionally(exp(head $ expand-expr(pred(s))),lower-stmt(conseq(s)),lower-stmt(alt(s))) + (s:Begin|EmptyStmt) : map(lower-stmt,s) lower-stmt(body) @@ -862,24 +865,38 @@ defn lower-to-ground (c:Circuit) -> Circuit : defn expand-connect-indexed-stmt (s: Stmt) -> Stmt : defn equality (e1:Expression,e2:Expression) -> Expression : DoPrim(EQUAL-UU-OP,list(e1,e2),List(),UIntType(UnknownWidth())) + defn get-name (e:Expression) -> Symbol : + match(e) : + (e:WRef) : symbol-join([name(e) `#]) + (e:WSubfield) : symbol-join([get-name(exp(e)) `. name(e) `#]) + (e:WIndex) : symbol-join([get-name(exp(e)) `. to-symbol(value(e)) `#]) + (e) : `T match(s) : (s:ConnectToIndexed) : Begin $ if length(locs(s)) == 0 : list(EmptyStmt()) else : - List(Connect(head(locs(s)),exp(s)), to-list $ - for (i in 1 to false, l in tail(locs(s))) stream : Conditionally( - equality(index(s),UIntValue(i,UnknownWidth())), - Connect(l,exp(s)), - EmptyStmt()) + val ref = WRef(firrtl-gensym(get-name(exp(s))),type(index(s)),NodeKind(),UNKNOWN-GENDER) + append( + list(Connect(head(locs(s)),exp(s)),DefNode(name(ref),index(s))) + to-list $ + for (i in 1 to false, l in tail(locs(s))) stream : Conditionally( + equality(ref,UIntValue(i,UnknownWidth())), + Connect(l,exp(s)), + EmptyStmt() + ) ) (s:ConnectFromIndexed) : Begin $ if length(exps(s)) == 0 : list(EmptyStmt()) else : - List(Connect(loc(s),head(exps(s))), to-list $ - for (i in 1 to false, e in tail(exps(s))) stream : Conditionally( - equality(index(s),UIntValue(i,UnknownWidth())), - Connect(loc(s),e), - EmptyStmt()) + val ref = WRef(firrtl-gensym(get-name(loc(s))),type(index(s)),NodeKind(),UNKNOWN-GENDER) + append( + list(Connect(loc(s),head(exps(s))),DefNode(name(ref),index(s))) + to-list $ + for (i in 1 to false, e in tail(exps(s))) stream : Conditionally( + equality(ref,UIntValue(i,UnknownWidth())), + Connect(loc(s),e), + EmptyStmt() + ) ) (s) : map(expand-connect-indexed-stmt,s) @@ -1349,6 +1366,11 @@ defmethod equal? (w1:Width,w2:Width) -> True|False : if not contains?(args(w2),w) : ret(false) ret(true) (w1:IntWidth,w2:IntWidth) : width(w1) == width(w2) + (w1:PlusWidth,w2:PlusWidth) : + (arg1(w1) == arg1(w2) and arg2(w1) == arg2(w2)) or (arg1(w1) == arg2(w2) and arg2(w1) == arg1(w2)) + (w1:MinusWidth,w2:MinusWidth) : + (arg1(w1) == arg1(w2) and arg2(w1) == arg2(w2)) or (arg1(w1) == arg2(w2) and arg2(w1) == arg1(w2)) + (w1:ExpWidth,w2:ExpWidth) : arg1(w1) == arg1(w2) (w1:UnknownWidth,w2:UnknownWidth) : true (w1,w2) : false defn apply (a:Int|False,b:Int|False, f: (Int,Int) -> Int) -> Int|False : @@ -1380,6 +1402,18 @@ defn solve-constraints (l:List<WGeq>) -> HashTable<Symbol,Int> : for x in args(w*) do : add(v,x) (w*) : add(v,w*) MaxWidth(unique(v)) + (w:PlusWidth) : + match(arg1(w),arg2(w)) : + (w1:IntWidth,w2:IntWidth) : IntWidth(width(w1) + width(w2)) + (w1,w2) : w + (w:MinusWidth) : + match(arg1(w),arg2(w)) : + (w1:IntWidth,w2:IntWidth) : IntWidth(width(w1) - width(w2)) + (w1,w2) : w + (w:ExpWidth) : + match(arg1(w)) : + (w1:IntWidth) : IntWidth(pow(2,width(w1)) - 1) + (w1) : w (w) : w defn substitute (w:Width,h:HashTable<Symbol,Width>) -> Width : ;println-all-debug(["Substituting for [" w "]"]) @@ -1458,25 +1492,25 @@ defn solve-constraints (l:List<WGeq>) -> HashTable<Symbol,Int> : ; 2) Remove Cycles ; 3) Move to solved if not self-recursive val u = make-unique(l) - ;println-debug("======== UNIQUE CONSTRAINTS ========") - ;for x in u do : println-debug(x) - ;println-debug("====================================") + println-debug("======== UNIQUE CONSTRAINTS ========") + for x in u do : println-debug(x) + println-debug("====================================") val f = HashTable<Symbol,Width>(symbol-hash) val o = Vector<Symbol>() for x in u do : - ;println-debug("==== SOLUTIONS TABLE ====") - ;for x in f do : println-debug(x) - ;println-debug("=========================") + println-debug("==== SOLUTIONS TABLE ====") + for x in f do : println-debug(x) + println-debug("=========================") val [n e] = [key(x) value(x)] val e-sub = substitute(e,f) - ;println-debug(["Solving " n " => " e]) - ;println-debug(["After Substitute: " n " => " e-sub]) - ;println-debug("==== SOLUTIONS TABLE (Post Substitute) ====") - ;for x in f do : println-debug(x) - ;println-debug("=========================") + println-debug(["Solving " n " => " e]) + println-debug(["After Substitute: " n " => " e-sub]) + println-debug("==== SOLUTIONS TABLE (Post Substitute) ====") + for x in f do : println-debug(x) + println-debug("=========================") val e* = remove-cycle{n,_} $ e-sub ;println-debug(["After Remove Cycle: " n " => " e*]) if not self-rec?(n,e*) : @@ -1485,28 +1519,28 @@ defn solve-constraints (l:List<WGeq>) -> HashTable<Symbol,Int> : add(o,n) f[n] = e* - ;println-debug("Forward Solved Constraints") - ;for x in f do : println-debug(x) + println-debug("Forward Solved Constraints") + for x in f do : println-debug(x) ; Backwards Solve val b = HashTable<Symbol,Width>(symbol-hash) for i in (length(o) - 1) through 0 by -1 do : val n = o[i] - ;println-all-debug(["SOLVE BACK: [" n " => " f[n] "]"]) - ;println-debug("==== SOLUTIONS TABLE ====") - ;for x in b do : println-debug(x) - ;println-debug("=========================") + println-all-debug(["SOLVE BACK: [" n " => " f[n] "]"]) + println-debug("==== SOLUTIONS TABLE ====") + for x in b do : println-debug(x) + println-debug("=========================") val e* = simplify(b-sub(f[n],b)) - ;println-all-debug(["BACK RETURN: [" n " => " e* "]"]) + println-all-debug(["BACK RETURN: [" n " => " e* "]"]) b[n] = e* - ;println-debug("==== SOLUTIONS TABLE (Post backsolve) ====") - ;for x in b do : println-debug(x) - ;println-debug("=========================") + println-debug("==== SOLUTIONS TABLE (Post backsolve) ====") + for x in b do : println-debug(x) + println-debug("=========================") ; Evaluate val e = evaluate(b) - ;println-debug("Evaluated Constraints") - ;for x in e do : println-debug(x) + println-debug("Evaluated Constraints") + for x in e do : println-debug(x) e public defn width! (t:Type) -> Width : @@ -1979,6 +2013,7 @@ public defn run-passes (c: Circuit, p: List<Char>,file:String) : ; 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) diff --git a/src/main/stanza/primop.stanza b/src/main/stanza/primop.stanza index b293da52..34dd0392 100644 --- a/src/main/stanza/primop.stanza +++ b/src/main/stanza/primop.stanza @@ -185,6 +185,7 @@ public defn lower-and-type-primop (e:DoPrim) -> DoPrim : match(type(args(e)[1]),type(args(e)[2])) : (t1:UIntType, t2:UIntType) : MUX-UU-OP (t1:SIntType, t2:SIntType) : MUX-SS-OP + (t1,t2) : error(to-string(args(e))) MUX-UU-OP : DoPrim(op(e),args(e),consts(e),u()) MUX-SS-OP : DoPrim(op(e),args(e),consts(e),s()) PAD-OP : |
