aboutsummaryrefslogtreecommitdiff
path: root/src/main/stanza/errors.stanza
diff options
context:
space:
mode:
authorazidar2015-08-25 14:13:00 -0700
committerazidar2015-08-25 14:13:13 -0700
commiteb1ab67b6cc3fd4a549da563bf643bd519d7562e (patch)
treea21f0ca828398a33a68f38209429cc6beed86edc /src/main/stanza/errors.stanza
parent6cd96b6315c32bbf6c4ace28197ff1d4be86a129 (diff)
Added width check pass with tests. #22.
Diffstat (limited to 'src/main/stanza/errors.stanza')
-rw-r--r--src/main/stanza/errors.stanza232
1 files changed, 142 insertions, 90 deletions
diff --git a/src/main/stanza/errors.stanza b/src/main/stanza/errors.stanza
index 77e48263..72535242 100644
--- a/src/main/stanza/errors.stanza
+++ b/src/main/stanza/errors.stanza
@@ -16,13 +16,6 @@ defpackage firrtl/errors :
; * Only modules in circuit (no statements or expressions) <- parser
; * Module must be a reference in inst declaration
-;AFTER WIDTH INFERENCE
-; o No names
-; o No Unknowns
-; o All widths are positive
-; o pad's width is greater than value's width
-; o widths are large enough to contain value
-
;AFTER ??????
; o No combinational loops
@@ -92,10 +85,6 @@ defn ModuleNotDefined (info:FileInfo, name:Symbol) :
PassException $ string-join $
[info ": Module " 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>."]
-
defn IncorrectNumArgs (info:FileInfo, op:Symbol, n:Int) :
PassException $ string-join $
[info ": [module " mname "] Primop " op " requires " n " expression arguments."]
@@ -106,7 +95,7 @@ defn IncorrectNumConsts (info:FileInfo, op:Symbol, n:Int) :
defn NegWidth (info:FileInfo) :
PassException $ string-join $
- [info ": [module " mname "] Width cannot be negative."]
+ [info ": [module " mname "] Width cannot be negative or zero."]
defn NegVecSize (info:FileInfo) :
PassException $ string-join $
@@ -264,7 +253,7 @@ public defn check-high-form (c:Circuit) -> Circuit :
defn check-high-form-w (info:FileInfo,w:Width,unknown-ok?:True|False) -> Width :
match(w) :
(w:IntWidth) :
- if width(w) < 0 : add(errors,NegWidth(info))
+ if width(w) <= 0 : add(errors,NegWidth(info))
w
(w:UnknownWidth) :
if unknown-ok? == false : add(errors,IllegalUnknownWidth(info))
@@ -363,15 +352,6 @@ public defn check-high-form (c:Circuit) -> Circuit :
mnames[name(m)] = true
for p in ports(m) do :
names[name(p)] = true
- ;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)))
map(check-high-form-t{info(p),_,true},type(p))
map(check-high-form-w{info(p),_,true},type(p))
@@ -466,7 +446,6 @@ public defn check-kinds (c:Circuit) -> Circuit :
throw(PassExceptions(errors)) when not empty?(errors)
c
-
;==================== CHECK TYPES =====================
; o Subfields are only on bundles, before type inference <- need to not error, just do unknown-type
; o Indexes are only on vectors
@@ -833,6 +812,146 @@ public defn check-genders (c:Circuit) -> Circuit :
throw(PassExceptions(errors)) when not empty?(errors)
c
+;;================ Initialization Check ==================
+; Error on all componenents that are not connected to.
+
+public defstruct CheckInitialization <: Pass
+public defmethod pass (b:CheckInitialization) -> (Circuit -> Circuit) : check-init
+public defmethod name (b:CheckInitialization) -> String : "Check Initialization"
+public defmethod short-name (b:CheckInitialization) -> String : "check-init"
+
+;----------------- Errors ------------------------
+
+defn RefNotInitialized (info:FileInfo, name:Symbol) :
+ PassException $ string-join $
+ [info ": [module " mname "] Reference " name " is not fully initialized."]
+
+;------------ Helper Functions -------------
+
+;------------ Pass ------------------
+
+public defn check-init (c:Circuit) :
+ val errors = Vector<PassException>()
+
+ defn check-init-m (m:InModule) :
+ val init? = HashTable<Symbol,FileInfo|True>(symbol-hash)
+ defn get-name (e:Expression) -> Symbol :
+ match(e) :
+ (e:Ref) : name(e)
+ (e:Subfield) : symbol-join([get-name(exp(e)) `. name(e)])
+ (e) : error("Shouldn't be here")
+
+ defn check-init-s (s:Stmt) :
+ do(check-init-s,s)
+ match(s) :
+ (s:DefWire|DefRegister) : init?[name(s)] = info(s)
+ (s:DefAccessor) :
+ if acc-dir(s) == WRITE : init?[name(s)] = info(s)
+ (s:DefInstance) :
+ for f in fields(type(module(s)) as BundleType) do :
+ if flip(f) == REVERSE :
+ init?[symbol-join([name(s) `. name(f)])] = info(s)
+ (s:Connect) :
+ init?[get-name(loc(s))] = true
+ (s) : false
+
+ for p in ports(m) do :
+ if direction(p) == OUTPUT :
+ init?[name(p)] = info(p)
+
+ check-init-s(body(m))
+
+ for x in init? do :
+ match(value(x)) :
+ (v:FileInfo) : add(errors, RefNotInitialized(v,key(x)))
+ (v) : false
+
+ for m in modules(c) do :
+ mname = name(m)
+ match(m) :
+ (m:InModule) : check-init-m(m)
+ (m) : false
+
+ throw(PassExceptions(errors)) when not empty?(errors)
+ c
+
+;================= Width Check ==========================
+;AFTER WIDTH INFERENCE
+; * No names
+; * No Unknowns
+; * All widths are positive
+; * widths are large enough to contain value
+
+
+public defstruct CheckWidths <: Pass
+public defmethod pass (b:CheckWidths) -> (Circuit -> Circuit) : check-width
+public defmethod name (b:CheckWidths) -> String : "Width Check"
+public defmethod short-name (b:CheckWidths) -> String : "width-check"
+
+;----------------- Errors ------------------------
+
+defn UninferredWidth (info:FileInfo) :
+ PassException $ string-join $
+ [info ": [module " mname "] Uninferred width."]
+
+defn WidthTooSmall (info:FileInfo,v:String) :
+ PassException $ string-join $
+ [info ": [module " mname "] Width too small for constant " v "."]
+
+;---------------- Helper Functions --------------
+
+;--------------- Check Width Pass -------------------
+public defn check-width (c:Circuit) -> Circuit :
+ val errors = Vector<PassException>()
+
+ defn check-width-m (m:Module) -> False :
+ defn check-width-w (info:FileInfo,w:Width) -> Width :
+ match(w) :
+ (w:IntWidth) :
+ if width(w) <= 0 : add(errors,NegWidth(info))
+ (w:LongWidth) :
+ if width(w) <= to-long(0) : add(errors,NegWidth(info))
+ (w) :
+ add(errors,UninferredWidth(info))
+ w
+
+ defn check-width-e (info:FileInfo,e:Expression) -> Expression :
+ match(map(check-width-e{info,_},e)) :
+ (e:UIntValue|SIntValue) :
+ match(width(e)) :
+ (w:IntWidth) :
+ if num-bits(value(e)) > width(w) :
+ add(errors,WidthTooSmall(info,to-string(value(e))))
+ (w:LongWidth) :
+ if to-long(num-bits(value(e))) > width(w) :
+ add(errors,WidthTooSmall(info,to-string(value(e))))
+ (w) : add(errors,UninferredWidth(info))
+ check-width-w(info,width(e))
+ (e:DoPrim) : false
+ (e) : false
+
+ ;mapr(check-width-w{info,_},type(map(check-width-e{info,_},e)))
+ e
+
+ defn check-width-s (s:Stmt) -> Stmt :
+ map(check-width-e{info(s),_},map(check-width-s,s))
+ map(mapr{check-width-w{info(s),_},_:Type},s)
+
+ for p in ports(m) do :
+ mapr(check-width-w{info(p),_},type(p))
+
+ match(m) :
+ (m:ExModule) : false
+ (m:InModule) : check-width-s(body(m))
+ false
+
+ for m in modules(c) do :
+ mname = name(m)
+ check-width-m(m)
+ throw(PassExceptions(errors)) when not empty?(errors)
+ c
+
+
;================= Low Form Check ==========================
;AFTER LOWERING
; o All things connect to once
@@ -944,70 +1063,3 @@ public defn check-low-form (c:Circuit) -> Circuit :
throw(PassExceptions(errors)) when not empty?(errors)
c
-
-;;================ Initialization Check ==================
-; Error on all componenents that are not connected to.
-
-public defstruct CheckInitialization <: Pass
-public defmethod pass (b:CheckInitialization) -> (Circuit -> Circuit) : check-init
-public defmethod name (b:CheckInitialization) -> String : "Check Initialization"
-public defmethod short-name (b:CheckInitialization) -> String : "check-init"
-
-;----------------- Errors ------------------------
-
-defn RefNotInitialized (info:FileInfo, name:Symbol) :
- PassException $ string-join $
- [info ": [module " mname "] Reference " name " is not fully initialized."]
-
-;------------ Helper Functions -------------
-
-;------------ Pass ------------------
-
-public defn check-init (c:Circuit) :
- val errors = Vector<PassException>()
-
- defn check-init-m (m:InModule) :
- val init? = HashTable<Symbol,FileInfo|True>(symbol-hash)
- defn get-name (e:Expression) -> Symbol :
- match(e) :
- (e:Ref) : name(e)
- (e:Subfield) : symbol-join([get-name(exp(e)) `. name(e)])
- (e) : error("Shouldn't be here")
-
- defn check-init-s (s:Stmt) :
- do(check-init-s,s)
- match(s) :
- (s:DefWire|DefRegister) : init?[name(s)] = info(s)
- (s:DefAccessor) :
- if acc-dir(s) == WRITE : init?[name(s)] = info(s)
- (s:DefInstance) :
- for f in fields(type(module(s)) as BundleType) do :
- if flip(f) == REVERSE :
- init?[symbol-join([name(s) `. name(f)])] = info(s)
- (s:Connect) :
- init?[get-name(loc(s))] = true
- (s) : false
-
- for p in ports(m) do :
- if direction(p) == OUTPUT :
- init?[name(p)] = info(p)
-
- check-init-s(body(m))
-
- for x in init? do :
- match(value(x)) :
- (v:FileInfo) : add(errors, RefNotInitialized(v,key(x)))
- (v) : false
-
- for m in modules(c) do :
- mname = name(m)
- match(m) :
- (m:InModule) : check-init-m(m)
- (m) : false
-
- throw(PassExceptions(errors)) when not empty?(errors)
- c
-
-
-
-