aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorazidar2015-05-26 17:33:40 -0700
committerazidar2015-05-26 17:33:40 -0700
commitcf80ff9c83c2fedd42ec186a3e342520c89f91ab (patch)
treeebbf3455b91e8840d49057754585d567dacea384 /src
parenteb125225cb96875f31a9af0db187406782b75223 (diff)
Added <>. Added additional checks for primops. Added new chisel3 files.
Diffstat (limited to 'src')
-rw-r--r--src/main/stanza/errors.stanza210
-rw-r--r--src/main/stanza/firrtl-ir.stanza4
-rw-r--r--src/main/stanza/ir-parser.stanza1
-rw-r--r--src/main/stanza/ir-utils.stanza3
-rw-r--r--src/main/stanza/passes.stanza32
-rw-r--r--src/main/stanza/primop.stanza1
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())