diff options
| author | azidar | 2015-05-13 17:08:29 -0700 |
|---|---|---|
| committer | azidar | 2015-05-13 17:08:29 -0700 |
| commit | 521a4277bfc1d764dc9ee771c604200525e871cb (patch) | |
| tree | 53cba82f8e209b3ca98dc367726928e96331fca8 /src/main/stanza/errors.stanza | |
| parent | 2cf26ba655e59937f5a52aa50db2d97538d1fdde (diff) | |
Added source indicators from FIRRTL files. Pass in -p i to get them printed. Should show up with check passes
Diffstat (limited to 'src/main/stanza/errors.stanza')
| -rw-r--r-- | src/main/stanza/errors.stanza | 139 |
1 files changed, 119 insertions, 20 deletions
diff --git a/src/main/stanza/errors.stanza b/src/main/stanza/errors.stanza index 53ed1bdf..30414afd 100644 --- a/src/main/stanza/errors.stanza +++ b/src/main/stanza/errors.stanza @@ -171,24 +171,24 @@ public defn check-high-form (c:Circuit) -> Circuit : if prefix typeof Symbol : add(errors,IsPrefix(info,name,prefix as Symbol)) map{check-high-form-s{_,names},_} $ { - match(map(check-high-form-e{info!(s),_,names},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)) + check-name(info(s),name(s)) add(names,name(s)) - if has-flip?(type(s)) : add(errors, MemWithFlip(info!(s), name(s))) + if has-flip?(type(s)) : add(errors, MemWithFlip(info(s), name(s))) (s:DefInstance) : if not contains?(name(module(s) as Ref),map(name,modules(c))) : - add(errors, ModuleNotDefined(info!(s),name(module(s) as Ref))) + 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)) + check-valid-loc(info(s),loc(s)) (s) : false s }() @@ -281,17 +281,17 @@ public defn check-kinds (c:Circuit) -> Circuit : 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) + do(check-kinds-e{info(s),_:Expression},s) match(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: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)) + 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)) + check-is-reg(info(s),loc(s)) + check-not-mem(info(s),exp(s)) (s) : false do(check-kinds-s,s) @@ -377,7 +377,7 @@ public defn check-types (c:Circuit) -> Circuit : (e:WSubfield) : match(type(exp(e))) : (t:BundleType) : - val ft = for p in fields(t) find : name(p) == s + 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) : @@ -398,12 +398,15 @@ public defn check-types (c:Circuit) -> Circuit : e defn check-types-s (s:Stmt) -> Stmt : map{check-types-s,_} $ - match(map(check-types-e{info!(s),_},s)) : - (s:Connect|OnReset) : - if type(loc(s)) == type(exp(s)) : add(errors,InvalidConnect(info!(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))) + if type(pred(s)) != u() : add(errors,PredNotUInt(info(s))) s (s) : s @@ -411,3 +414,99 @@ public defn check-types (c:Circuit) -> Circuit : 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 + +;----------------- Errors --------------------- +defn WrongGender (info:FileInfo,expr:Symbol,wrong:Symbol,right:Symbol) : + PassException $ string-join $ + [info ": Expression " expr "has gender " wrong " but requires gender " right "."] + +defn UnknownGenders (info:FileInfo,name:Symbol) : + PassException $ string-join $ + [info ": Accessor " name " has an unknown gender."] + +;---------------- Helper Functions -------------- +defn dir-to-gender (d:Direction) -> Gender : + switch {_ == d} : + INPUT : MALE + OUTPUT : FEMALE + +;----------------- Check Genders Pass --------------------- + +public defn check-genders (c:Circuit) -> Circuit : + val errors = Vector<PassException>() + defn check-gender (info:FileInfo,genders:HashTable<Symbol,Gender>,e:Expression,right:Gender) -> False : + val gender = get-gender(e,genders) + if gender != right and gender != BI-GENDER: + add(errors,WrongGender(info,to-symbol(e),to-symbol(gender),to-symbol(right))) + + 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:Pad) : MALE + (e:DoPrim) : MALE + (e:UIntValue) : MALE + (e:SIntValue) : MALE + (e:ReadPort) : MALE + (e:WritePort) : FEMALE + (e:Register) : 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:Pad) : check-gender(info,genders,value(e),MALE) + (e:DoPrim) : + for e in args(e) do : + check-gender(info,genders,e,MALE) + (e:UIntValue) : false + (e:SIntValue) : false + (e:ReadPort) : do(check-gender{info,genders,_,MALE},e) + (e:WritePort) : do(check-gender{info,genders,_,MALE},e) + (e:Register) : do(check-gender{info,genders,_,MALE},e) + + defn check-genders-s (s:Stmt,genders:HashTable<Symbol,Gender>) -> False : + do(check-genders-e{info(s),_:Expression,genders},s) + match(s) : + (s:DefWire) : genders[name(s)] = BI-GENDER + (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:WDefAccessor) : + if gender(s) == UNKNOWN-GENDER : add(errors,UnknownGenders(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: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:EmptyStmt) : false + (s:Begin) : false + + + for m in modules(c) do : + val genders = HashTable<Symbol,Gender>(symbol-hash) + for p in ports(m) do : + genders[name(p)] = dir-to-gender(direction(p)) + check-genders-s(body(m),genders) + throw(PassExceptions(errors)) when not empty?(errors) + c |
