diff options
| author | azidar | 2015-05-26 17:33:40 -0700 |
|---|---|---|
| committer | azidar | 2015-05-26 17:33:40 -0700 |
| commit | cf80ff9c83c2fedd42ec186a3e342520c89f91ab (patch) | |
| tree | ebbf3455b91e8840d49057754585d567dacea384 /src | |
| parent | eb125225cb96875f31a9af0db187406782b75223 (diff) | |
Added <>. Added additional checks for primops. Added new chisel3 files.
Diffstat (limited to 'src')
| -rw-r--r-- | src/main/stanza/errors.stanza | 210 | ||||
| -rw-r--r-- | src/main/stanza/firrtl-ir.stanza | 4 | ||||
| -rw-r--r-- | src/main/stanza/ir-parser.stanza | 1 | ||||
| -rw-r--r-- | src/main/stanza/ir-utils.stanza | 3 | ||||
| -rw-r--r-- | src/main/stanza/passes.stanza | 32 | ||||
| -rw-r--r-- | src/main/stanza/primop.stanza | 1 |
6 files changed, 223 insertions, 28 deletions
diff --git a/src/main/stanza/errors.stanza b/src/main/stanza/errors.stanza index 8c5532b0..e8b00087 100644 --- a/src/main/stanza/errors.stanza +++ b/src/main/stanza/errors.stanza @@ -19,7 +19,6 @@ defpackage firrtl/errors : ; 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 @@ -43,6 +42,9 @@ defpackage firrtl/errors : ; * No name can be a prefix of any other name. ; * all references are declared ; * UInt only has positive ints +; * Vector types has positive size +; * Width sizes are positive +; * Primops have the correct number of arguments public defstruct CheckHighForm <: Pass public defmethod pass (b:CheckHighForm) -> (Circuit -> Circuit) : check-high-form @@ -94,6 +96,22 @@ defn WrongReset (info:FileInfo, name:Symbol) : PassException $ string-join $ [info ": Module " name " has a reset that is not of type UInt<1>."] +defn IncorrectNumArgs (info:FileInfo, op:Symbol, n:Int) : + PassException $ string-join $ + [info ": Primop " op " requires " n " expression arguments."] + +defn IncorrectNumConsts (info:FileInfo, op:Symbol, n:Int) : + PassException $ string-join $ + [info ": Primop " op " requires " n " integer arguments."] + +defn NegWidth (info:FileInfo) : + PassException $ string-join $ + [info ": Width cannot be negative."] + +defn NegVecSize (info:FileInfo) : + PassException $ string-join $ + [info ": Vector type size cannot be negative."] + ;---------------- Helper Functions -------------- defn has-flip? (t:Type) -> True|False : var has? = false @@ -134,6 +152,49 @@ defn is-prefix? (s1:Symbol,s2:Symbol) -> True|False : is? = false is? +defn check-high-form-primop (e:DoPrim, errors:Vector<PassException>,info:FileInfo) -> False : + defn correct-num (ne:Int|False,nc:Int) -> False : + if not (ne typeof False) : + if length(args(e)) != ne as Int : add(errors,IncorrectNumArgs(info,to-symbol(op(e)),ne as Int)) + if length(consts(e)) != nc : add(errors,IncorrectNumConsts(info,to-symbol $ op(e),nc)) + + switch {op(e) == _} : + ADD-OP : correct-num(2,0) + SUB-OP : correct-num(2,0) + MUL-OP : correct-num(2,0) + DIV-OP : correct-num(2,0) + MOD-OP : correct-num(2,0) + QUO-OP : correct-num(2,0) + REM-OP : correct-num(2,0) + ADD-WRAP-OP : correct-num(2,0) + SUB-WRAP-OP : correct-num(2,0) + LESS-OP : correct-num(2,0) + LESS-EQ-OP : correct-num(2,0) + GREATER-OP : correct-num(2,0) + GREATER-EQ-OP : correct-num(2,0) + EQUAL-OP : correct-num(2,0) + NEQUAL-OP : correct-num(2,0) + MUX-OP : correct-num(3,0) + PAD-OP : correct-num(1,1) + AS-UINT-OP : correct-num(1,0) + AS-SINT-OP : correct-num(1,0) + DYN-SHIFT-LEFT-OP : correct-num(2,0) + DYN-SHIFT-RIGHT-OP : correct-num(2,0) + SHIFT-LEFT-OP : correct-num(1,1) + SHIFT-RIGHT-OP : correct-num(1,1) + CONVERT-OP : correct-num(1,0) + NEG-OP : correct-num(1,0) + BIT-NOT-OP : correct-num(1,0) + BIT-AND-OP : correct-num(2,0) + BIT-OR-OP : correct-num(2,0) + BIT-XOR-OP : correct-num(2,0) + BIT-AND-REDUCE-OP : correct-num(false,0) + BIT-OR-REDUCE-OP : correct-num(false,0) + BIT-XOR-REDUCE-OP : correct-num(false,0) + CONCAT-OP : correct-num(2,0) + BIT-SELECT-OP : correct-num(1,1) + BITS-SELECT-OP : correct-num(1,2) + ;--------------- Check High Form Pass ------------------- public defn check-high-form (c:Circuit) -> Circuit : val errors = Vector<PassException>() @@ -144,6 +205,20 @@ public defn check-high-form (c:Circuit) -> Circuit : add(errors,InvalidLOC(info)) (e) : false + defn check-high-form-w (info:FileInfo,w:Width) -> Width : + match(w) : + (w:IntWidth) : + if width(w) < 0 : add(errors,NegWidth(info)) + w + (w) : w + + defn check-high-form-t (info:FileInfo,t:Type) -> Type : + match(map(check-high-form-t{info,_},t)) : + (t:VectorType) : + if size(t) < 0 : add(errors,NegVecSize(info)) + (t) : false + map(check-high-form-w{info,_:Width},t) + defn check-high-form-e (info:FileInfo,e:Expression,names:Vector<Symbol>) -> Expression : match(map(check-high-form-e{info,_,names},e)) : (e:Ref) : @@ -157,10 +232,13 @@ public defn check-high-form (c:Circuit) -> Circuit : match(exp(e)) : (e:Ref|Subfield|Index) : false (e) : add(errors,InvalidIndex(info)) + (e:DoPrim) : check-high-form-primop(e,errors,info) ;; (e:UIntValue) : ;; if value(e) < 0 : ;; add(errors,NegUInt(info)) (e) : false + map(check-high-form-w{info,_:Width},e) + map(check-high-form-t{info,_:Type},e) e defn check-high-form-s (s:Stmt,names:Vector<Symbol>) -> Stmt : @@ -169,6 +247,8 @@ public defn check-high-form (c:Circuit) -> Circuit : val prefix = is-prefix?(name,names) if prefix typeof Symbol : add(errors,IsPrefix(info,name,prefix as Symbol)) + map(check-high-form-t{info(s),_:Type},s) + map{check-high-form-s{_,names},_} $ { match(map(check-high-form-e{info(s),_,names},s)) : (s:DefWire|DefRegister) : @@ -191,6 +271,8 @@ public defn check-high-form (c:Circuit) -> Circuit : add(names,name(s)) (s:Connect) : check-valid-loc(info(s),loc(s)) + (s:BulkConnect) : + check-valid-loc(info(s),loc(s)) (s) : false s }() @@ -209,6 +291,9 @@ public defn check-high-form (c:Circuit) -> Circuit : add(errors,WrongReset(info!(m),name(m))) else : add(errors,WrongReset(info!(m),name(m))) + map(check-high-form-t{info(p),_},type(p)) + map(check-high-form-w{info(p),_},type(p)) + add(names,`reset) @@ -284,8 +369,6 @@ public defn check-kinds (c:Circuit) -> Circuit : 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) : do(check-not-mem{info,_},e) defn check-kinds-s (s:Stmt) -> False : do(check-kinds-e{info(s),_:Expression},s) @@ -296,6 +379,9 @@ public defn check-kinds (c:Circuit) -> Circuit : (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)) @@ -309,7 +395,6 @@ public defn check-kinds (c:Circuit) -> Circuit : ;==================== 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 @@ -348,10 +433,6 @@ defn EnableNotUInt (info:FileInfo) : PassException $ string-join $ [info ": Enable is not of UIntType."] -;defn PadNotGround (info:FileInfo) : - ;PassException $ string-join $ - ;[info ": Illegal Pad on non-ground type."] - defn InvalidConnect (info:FileInfo) : PassException $ string-join $ [info ": Type mismatch."] @@ -360,6 +441,27 @@ defn PredNotUInt (info:FileInfo) : PassException $ string-join $ [info ": Predicate not a UIntType."] +defn OpNotGround (info:FileInfo, op:Symbol) : + PassException $ string-join $ + [info ": Primop " op " cannot operate on non-ground types."] + +defn OpNotUInt (info:FileInfo, op:Symbol,e:Symbol) : + PassException $ string-join $ + [info ": Primop " op " requires argument " e " to be a UInt type."] + +defn OpNotAllUInt (info:FileInfo, op:Symbol) : + PassException $ string-join $ + [info ": Primop " op " requires all arguments to be UInt type."] + +defn OpNotAllSameType (info:FileInfo, op:Symbol) : + PassException $ string-join $ + [info ": Primop " op " requires all operands to have the same type."] + +defn NodeWithFlips (info:FileInfo) : + PassException $ string-join $ + [info ": Node cannot be a bundle type with flips."] + + ;---------------- Helper Functions -------------- defmethod equal? (t1:Type,t2:Type) -> True|False : match(t1,t2) : @@ -380,6 +482,64 @@ defmethod equal? (t1:Type,t2:Type) -> True|False : defn u () -> UIntType : UIntType(UnknownWidth()) defn s () -> SIntType : SIntType(UnknownWidth()) +defn check-types-primop (e:DoPrim, errors:Vector<PassException>,info:FileInfo) -> False : + defn all-same-type (ls:List<Expression>) -> False : + for x in ls do : + if type(head(ls)) != type(x) : + add(errors,OpNotAllSameType(info,to-symbol $ op(e))) + defn all-ground (ls:List<Expression>) -> False : + for x in ls do : + if not (type(x) typeof UIntType or type(x) typeof SIntType) : + add(errors,OpNotGround(info,to-symbol $ op(e))) + defn all-uint (ls:List<Expression>) -> False : + for x in ls do : + if not (type(x) typeof UIntType) : + add(errors,OpNotAllUInt(info,to-symbol $ op(e))) + defn is-uint (x:Expression) -> False : + if not (type(x) typeof UIntType) : + 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 : all-same-type(args(e)) + NEQUAL-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-uint(args(e)) + BIT-AND-OP : all-uint(args(e)) + BIT-OR-OP : all-uint(args(e)) + BIT-XOR-OP : all-uint(args(e)) + 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)) + BIT-SELECT-OP : all-uint(args(e)) + BITS-SELECT-OP : all-uint(args(e)) + ;----------------- Check Types Pass --------------------- public defn check-types (c:Circuit) -> Circuit : val errors = Vector<PassException>() @@ -397,30 +557,27 @@ public defn check-types (c:Circuit) -> Circuit : (t:VectorType) : if value(e) >= size(t) : add(errors,IndexTooLarge(info,value(e))) (t) : add(errors,IndexOnNonVector(info)) - (e:DoPrim) : false ;check-types-primop(e) + (e:DoPrim) : check-types-primop(e,errors,info) (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{info(s),_},s)) : - (s:Connect) : - if type(loc(s)) != type(exp(s)) : add(errors,InvalidConnect(info(s))) - s - (s:OnReset) : - if type(loc(s)) != type(exp(s)) : add(errors,InvalidConnect(info(s))) - s - (s:Conditionally) : - if type(pred(s)) != u() : add(errors,PredNotUInt(info(s))) - s - (s) : s + 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: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))) + (s:DefNode) : + if has-flip?(type(value(s))) : add(errors,NodeWithFlips(info(s))) + (s) : false + s }() for m in modules(c) do : check-types-s(body(m)) @@ -469,7 +626,6 @@ public defn check-genders (c:Circuit) -> Circuit : 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:Pad) : MALE (e:DoPrim) : MALE (e:UIntValue) : MALE (e:SIntValue) : MALE @@ -483,7 +639,6 @@ public defn check-genders (c:Circuit) -> Circuit : (e:WRef) : false (e:WSubfield) : false (e:WIndex) : false - ;(e:Pad) : check-gender(info,genders,value(e),MALE) (e:DoPrim) : for e in args(e) do : check-gender(info,genders,e,MALE) @@ -511,6 +666,9 @@ public defn check-genders (c:Circuit) -> Circuit : (s:Connect) : check-gender(info(s),genders,loc(s),FEMALE) check-gender(info(s),genders,exp(s),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) diff --git a/src/main/stanza/firrtl-ir.stanza b/src/main/stanza/firrtl-ir.stanza index 39538498..e13e7655 100644 --- a/src/main/stanza/firrtl-ir.stanza +++ b/src/main/stanza/firrtl-ir.stanza @@ -134,6 +134,10 @@ public defstruct OnReset <: Stmt : ;LOW info: FileInfo with: (as-method => true) loc: Expression exp: Expression +public defstruct BulkConnect <: Stmt : ;LOW + info: FileInfo with: (as-method => true) + loc: Expression + exp: Expression public defstruct Connect <: Stmt : ;LOW info: FileInfo with: (as-method => true) loc: Expression diff --git a/src/main/stanza/ir-parser.stanza b/src/main/stanza/ir-parser.stanza index 0833543f..2f7b3771 100644 --- a/src/main/stanza/ir-parser.stanza +++ b/src/main/stanza/ir-parser.stanza @@ -194,6 +194,7 @@ defsyntax firrtl : stmt = (?s:#stmt/when) : s stmt = (?x:#exp := ?y:#exp!) : Connect(first-info(form),x, y) + stmt = (?x:#exp <> ?y:#exp!) : BulkConnect(first-info(form),x, y) stmt = (on-reset ?x:#exp := ?y:#exp!) : OnReset(first-info(form),x, y) stmt = ((?s:#stmt ?ss:#stmt ... ?rest ...)) : diff --git a/src/main/stanza/ir-utils.stanza b/src/main/stanza/ir-utils.stanza index d2afca05..28cdd136 100644 --- a/src/main/stanza/ir-utils.stanza +++ b/src/main/stanza/ir-utils.stanza @@ -147,6 +147,8 @@ defmethod print (o:OutputStream, c:Stmt) : do(print{o,_}, join(body(c), "\n")) (c:Connect) : print-all(o, [loc(c) " := " exp(c)]) + (c:BulkConnect) : + print-all(o, [loc(c) " <> " exp(c)]) (c:OnReset) : print-all(o, ["on-reset " loc(c) " := " exp(c)]) (c:EmptyStmt) : @@ -231,6 +233,7 @@ defmethod map (f: Expression -> Expression, c:Stmt) -> Stmt : (c:DefInstance) : DefInstance(info(c),name(c), f(module(c))) (c:Conditionally) : Conditionally(info(c),f(pred(c)), conseq(c), alt(c)) (c:Connect) : Connect(info(c),f(loc(c)), f(exp(c))) + (c:BulkConnect) : BulkConnect(info(c),f(loc(c)), f(exp(c))) (c:OnReset) : OnReset(info(c),f(loc(c)),f(exp(c))) (c) : c diff --git a/src/main/stanza/passes.stanza b/src/main/stanza/passes.stanza index b6926a7b..96225064 100644 --- a/src/main/stanza/passes.stanza +++ b/src/main/stanza/passes.stanza @@ -85,6 +85,11 @@ defstruct ConnectFromIndexed <: Stmt : ;================ WORKING IR UTILS ========================= +;defmethod equal? (f1:Flip, f2:Flip) -> True|False : +; switch fn ([x,y]) : f1 == x and f2 == y : +; [DEFAULT,DEFAULT] : true +; [REVERSE,REVERSE] : true +; else : false defn plus (g1:Gender,g2:Gender) -> Gender : switch fn ([x,y]) : g1 == x and g2 == y : @@ -504,7 +509,7 @@ defn infer-types (s:Stmt, l:List<KeyValue<Symbol,Type>>) -> [Stmt List<KeyValue< val [s*,l*] = infer-types(conseq(s),l) val [s**,l**] = infer-types(alt(s),l) [Conditionally(info(s),pred(s),s*,s**),l] - (s:Connect|OnReset|EmptyStmt) : [s,l] + (s:Connect|BulkConnect|OnReset|EmptyStmt) : [s,l] defn infer-types (m:Module, l:List<KeyValue<Symbol,Type>>) -> Module : val ptypes = @@ -607,6 +612,8 @@ defn resolve-genders (c:Circuit) : WDefAccessor(info(s),name(s),source*,index*,gender*) (s:Connect) : Connect(info(s),resolve-expr(loc(s),FEMALE),resolve-expr(exp(s),MALE)) + (s:BulkConnect) : + BulkConnect(info(s),resolve-expr(loc(s),FEMALE),resolve-expr(exp(s),MALE)) (s:OnReset) : OnReset(info(s),resolve-expr(loc(s),FEMALE),resolve-expr(exp(s),MALE)) (s:Conditionally) : @@ -742,7 +749,6 @@ defn index-of-elem (t:BundleType, s:Symbol) -> Int : else : sum = sum + num-elems(type(f)) error("Shouldn't be here") - defn generate-entry (n:Symbol,t:Type) -> List<NTF> : defn uniquify (n*:Symbol) -> Symbol : symbol-join([n "_" n*]) match(t) : @@ -863,6 +869,28 @@ defn lower (body:Stmt) -> Stmt : [MALE,FEMALE] : if s typeof Connect : Connect(info(s),r*,l*) else : OnReset(info(s),r*,l*) + (s:BulkConnect) : + val ls-fake = generate-entry(`null,type(loc(s))) + val rs-fake = generate-entry(`null,type(exp(s))) + val ls = expand-expr(loc(s)) + val rs = expand-expr(exp(s)) + val ls* = Vector<EF>() + val rs* = Vector<EF>() + for (l-fake in ls-fake,l in ls) do : + for (r-fake in rs-fake, r in rs) do : + if name(l-fake) == name(r-fake) and flip(l-fake) == flip(r-fake) and type(l-fake) == type(r-fake) : + add(ls*,l) + add(rs*,r) + Begin $ for (l in to-list(ls*), r in to-list(rs*)) map : + val lgender = FEMALE * flip(l) + val rgender = MALE * flip(r) + val l* = set-gender(exp(l),lgender,flip(l)) + val r* = set-gender(exp(r),rgender,flip(r)) + println-all-debug(["Left: " l " with Gender: " lgender]) + println-all-debug(["Right: " r " with Gender: " rgender]) + switch fn ([x,y]) : lgender == x and rgender == y : + [FEMALE,MALE] : Connect(info(s),l*,r*) + [MALE,FEMALE] : Connect(info(s),r*,l*) (s:ConnectFromIndexed) : Begin(ls) where : val ctable = HashTable<Symbol,Vector<EF>>(symbol-hash) for e in exps(s) do : diff --git a/src/main/stanza/primop.stanza b/src/main/stanza/primop.stanza index 023723b8..7abfa94e 100644 --- a/src/main/stanza/primop.stanza +++ b/src/main/stanza/primop.stanza @@ -5,6 +5,7 @@ defpackage firrtl/primops : import firrtl/ir-utils import firrtl/passes + public defn lower-and-type-primop (e:DoPrim) -> DoPrim : defn u () : UIntType(UnknownWidth()) defn s () : SIntType(UnknownWidth()) |
