aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorazidar2015-06-02 17:24:41 -0700
committerazidar2015-06-02 17:24:41 -0700
commit0a0c2d7c13c5beaa7c5132963112cc9e747ff287 (patch)
treeac7c4694e86d939cb693bc25d554284f4326c271 /src
parenteb5ca3c967c929c8331fd17e04dbd9402e41e986 (diff)
Added low firrtl check. Corrected bug in prefix matching in high firrtl check
Diffstat (limited to 'src')
-rw-r--r--src/main/stanza/compilers.stanza7
-rw-r--r--src/main/stanza/custom-compiler.stanza2
-rw-r--r--src/main/stanza/errors.stanza274
-rw-r--r--src/main/stanza/passes.stanza9
4 files changed, 150 insertions, 142 deletions
diff --git a/src/main/stanza/compilers.stanza b/src/main/stanza/compilers.stanza
index 9f8959ad..f86493a2 100644
--- a/src/main/stanza/compilers.stanza
+++ b/src/main/stanza/compilers.stanza
@@ -34,6 +34,7 @@ public defmethod passes (c:StandardFlo) -> List<Pass> :
SpecialRename(`#,`_)
SpecialRename(`$,`::)
CheckHighForm(`::)
+ CheckLowForm()
Flo(file(c))
]
@@ -59,8 +60,10 @@ public defmethod passes (c:StandardVerilog) -> List<Pass> :
Pad()
SplitExp()
ToRealIR()
- SpecialRename(`#,`__)
- SpecialRename(`$,`_)
+ SpecialRename(`#,`_)
+ SpecialRename(`$,`__)
+ CheckHighForm(`__)
+ CheckLowForm()
Verilog(file(c))
]
diff --git a/src/main/stanza/custom-compiler.stanza b/src/main/stanza/custom-compiler.stanza
index 1ca29bdd..aa21504b 100644
--- a/src/main/stanza/custom-compiler.stanza
+++ b/src/main/stanza/custom-compiler.stanza
@@ -32,6 +32,8 @@ public defmethod passes (c:InstrumentedVerilog) -> List<Pass> :
SplitExp()
ToRealIR()
SpecialRename(`#,`_)
+ CheckHighForm(`_)
+ CheckLowForm()
Verilog(file(c))
]
diff --git a/src/main/stanza/errors.stanza b/src/main/stanza/errors.stanza
index aff22460..01027d47 100644
--- a/src/main/stanza/errors.stanza
+++ b/src/main/stanza/errors.stanza
@@ -133,14 +133,15 @@ defn is-prefix? (s:Symbol,v:Vector<Symbol>,sym:Symbol) -> Symbol|False :
var is? = true
val s1* = to-string(s1)
val s2* = to-string(s2)
+ val st = to-string(sym)
for (x in s1*, y in s2*) do :
if x != y : is? = false
- if length(s1*) > length(s2*) :
- if s1*[length(s2*)] != to-string(sym)[0] : is? = false
- if length(s1*) < length(s2*) :
- if s2*[length(s1*)] != to-string(sym)[0] : is? = false
- if length(s1*) == length(s2*) :
- is? = false
+ if abs(length(s1*) - length(s2*)) < length(st) : is? = false
+ else :
+ if length(s1*) > length(s2*) :
+ if substring(s1*,length(s2*),length(s2*) + length(st)) != st : is? = false
+ if length(s1*) < length(s2*) :
+ if substring(s2*,length(s1*),length(s1*) + length(st)) != st : is? = false
is?
label<Symbol|False> myret :
for x in v do :
@@ -688,134 +689,145 @@ public defn check-genders (c:Circuit) -> Circuit :
throw(PassExceptions(errors)) when not empty?(errors)
c
-;================= High Form Check ==========================
+;================= Low Form Check ==========================
;AFTER LOWERING
; o All things connect to once
; o no reg
; o no accessors
; o only vecs are for memories
; o no bundles (future, will have them for mems)
-; o
-;
-;public defstruct CheckLowForm <: Pass :
-; sym : Symbol
-;public defmethod pass (b:CheckLowForm) -> (Circuit -> Circuit) : check-low-form{_,sym(b)}
-;public defmethod name (b:CheckLowForm) -> String : "Low Form Check"
-;public defmethod short-name (b:CheckLowForm) -> String : "low-form-check"
-;
-;;----------------- Errors ------------------------
-;defn NotUnique (info:FileInfo, name:Symbol) :
-; PassException $ string-join $
-; [info ": Reference " name " does not have a unique name."]
-;
-;
-;;---------------- Helper Functions --------------
-;
-;;--------------- Check Low Form Pass -------------------
-;public defn check-low-form (c:Circuit,sym:Symbol) -> Circuit :
-; val errors = Vector<PassException>()
-;
-; 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) :
-; if not contains?(name(e),names) :
-; add(errors,UndeclaredReference(info,name(e)))
-; (e:Subfield) :
-; match(exp(e)) :
-; (e:Ref|Subfield|Index) : false
-; (e) : add(errors,InvalidSubfield(info))
-; (e:Index) :
-; 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) < to-long $ 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 :
-; defn check-name (info:FileInfo,name:Symbol) -> False :
-; if contains?(name,names) : add(errors,NotUnique(info,name))
-; val prefix = is-prefix?(name,names,sym)
-; 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) :
-; check-name(info(s),name(s))
-; add(names,name(s))
-; (s:DefMemory) :
-; check-name(info(s),name(s))
-; add(names,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)))
-; check-name(info(s),name(s))
-; add(names,name(s))
-; (s:DefNode) :
-; check-name(info(s),name(s))
-; add(names,name(s))
-; (s:DefAccessor) :
-; check-name(info(s),name(s))
-; 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 }()
-;
-; defn check-high-form-m (m:Module) -> False :
-; val names = Vector<Symbol>()
-; for m in modules(c) do :
-; add(names,name(m))
-; for p in ports(m) do :
-; add(names,name(p))
-; 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),_},type(p))
-; map(check-high-form-w{info(p),_},type(p))
-;
-;
-;
-; add(names,`reset)
-; match(m) :
-; (m:ExModule) : false
-; (m:InModule) : check-high-form-s(body(m),names)
-; false
-;
-; var number-top-m = 0
-; for m in modules(c) do :
-; if name(m) == main(c) : number-top-m = number-top-m + 1
-; check-high-form-m(m)
-; if number-top-m != 1 : add(errors,NoTopModule(info!(c),main(c)))
-; throw(PassExceptions(errors)) when not empty?(errors)
-; c
-;
+
+public defstruct CheckLowForm <: Pass
+public defmethod pass (b:CheckLowForm) -> (Circuit -> Circuit) : check-low-form
+public defmethod name (b:CheckLowForm) -> String : "Low Form Check"
+public defmethod short-name (b:CheckLowForm) -> String : "low-form-check"
+
+;----------------- Errors ------------------------
+defn IncorrectRegisterUsage (info:FileInfo) :
+ PassException $ string-join $
+ [info ": Register can only be used on the right side of a connect statement."]
+
+defn IncorrectReadPortUsage (info:FileInfo) :
+ PassException $ string-join $
+ [info ": ReadPort can only be used on the right side of a connect statement."]
+
+defn IncorrectWritePortUsage (info:FileInfo) :
+ PassException $ string-join $
+ [info ": WritePort can only be used on the left side of a connect statement."]
+
+defn NoReg (info:FileInfo,name:Symbol) :
+ PassException $ string-join $
+ [info ": Invalid reg declaration " name ". No reg declarations are allowed in low firrtl."]
+
+defn NoAccessor (info:FileInfo,name:Symbol) :
+ PassException $ string-join $
+ [info ": Invalid accessor declaration " name ". No accessor declarations are allowed in low firrtl."]
+
+defn InvalidVec (info:FileInfo,name:Symbol) :
+ PassException $ string-join $
+ [info ": Expression " name " has an illegal vector type."]
+
+defn InvalidBundle (info:FileInfo,name:Symbol) :
+ PassException $ string-join $
+ [info ": Expression " name " has an illegal bundle type."]
+
+defn NoWhen (info:FileInfo) :
+ PassException $ string-join $
+ [info ": Illegal when statement. No when statements are allowed in low firrtl."]
+
+defn SingleAssignment (info:FileInfo,name:Symbol) :
+ PassException $ string-join $
+ [info ": Illegal assignment to " name ". Wires can only be assigned to once."]
+
+defn NoOnReset (info:FileInfo) :
+ PassException $ string-join $
+ [info ": Invalid use of on-reset. No on-resets are allowed in low firrtl."]
+
+defn NoBulkConnect (info:FileInfo) :
+ PassException $ string-join $
+ [info ": Invalid use of <>. No <>'s are allowed in low firrtl."]
+
+;---------------- Helper Functions --------------
+
+;--------------- Check Low Form Pass -------------------
+public defn check-low-form (c:Circuit) -> Circuit :
+ val errors = Vector<PassException>()
+
+ defn check-low-form-t (info:FileInfo,t:Type,name:Symbol) -> False :
+ match(t) :
+ (t:VectorType) : add(errors,InvalidVec(info,name))
+ (t:BundleType) : add(errors,InvalidBundle(info,name))
+ (t) : false
+
+ defn check-low-form-m (m:Module) -> False :
+ for p in ports(m) do :
+ check-low-form-t(info(p),type(p),name(p))
+
+ val assigned? = Vector<Symbol>()
+ val insts = Vector<Symbol>()
+ val mems = Vector<Symbol>()
+ defn check-correct-exp (info:FileInfo,e:Expression) -> False :
+ do(check-correct-exp{info,_:Expression},e)
+ match(e) :
+ (e:Ref) :
+ if contains?(insts,name(e)) :
+ for f in fields(type(e) as BundleType) do :
+ check-low-form-t(info,type(f),name(e))
+ if contains?(mems,name(e)) :
+ check-low-form-t(info,type(type(e) as VectorType),name(e))
+ (e:Register) : add(errors,IncorrectRegisterUsage(info))
+ (e:ReadPort) : add(errors,IncorrectReadPortUsage(info))
+ (e:WritePort) : add(errors,IncorrectWritePortUsage(info))
+ (e) : check-low-form-t(info,type(e),to-symbol $ to-string(e))
+ defn check-low-form-s (s:Stmt) -> False :
+ match(s) :
+ (s:DefWire) :
+ check-low-form-t(info(s),type(s),name(s))
+ (s:DefMemory) :
+ check-low-form-t(info(s),type(type(s)),name(s))
+ add(mems,name(s))
+ (s:DefInstance) :
+ for f in fields(type(module(s)) as BundleType) do :
+ check-low-form-t(info(s),type(f),name(s))
+ add(insts,name(s))
+ (s:DefNode) :
+ check-correct-exp(info(s),value(s))
+ (s:DefRegister) : add(errors,NoReg(info(s),name(s)))
+ (s:DefAccessor) : add(errors,NoAccessor(info(s),name(s)))
+ (s:Conditionally) : add(errors,NoWhen(info(s)))
+ (s:OnReset) : add(errors,NoOnReset(info(s)))
+ (s:BulkConnect) : add(errors,NoBulkConnect(info(s)))
+ (s:Connect) :
+ match(exp(s)) :
+ (e:Register) :
+ check-low-form-t(info(s),type(e),to-symbol $ to-string(e))
+ check-correct-exp(info(s),value(e))
+ check-correct-exp(info(s),enable(e))
+ (e:ReadPort) :
+ check-low-form-t(info(s),type(e),to-symbol $ to-string(e))
+ check-correct-exp(info(s),index(e))
+ check-correct-exp(info(s),enable(e))
+ (e) : check-correct-exp(info(s),e)
+ match(loc(s)) :
+ (e:WritePort) :
+ check-low-form-t(info(s),type(e),to-symbol $ to-string(e))
+ check-correct-exp(info(s),index(e))
+ check-correct-exp(info(s),enable(e))
+ (e:Ref|Subfield) :
+ val n* = to-symbol $ to-string $ e
+ if contains?(assigned?,n*) : add(errors,SingleAssignment(info(s),n*))
+ else : add(assigned?,to-symbol $ to-string $ e)
+ (e) : check-correct-exp(info(s),e)
+ (s:EmptyStmt) : false
+ (s:Begin) : do(check-low-form-s,s)
+
+ match(m) :
+ (m:ExModule) : false
+ (m:InModule) : check-low-form-s(body(m))
+ false
+
+ for m in modules(c) do :
+ check-low-form-m(m)
+ throw(PassExceptions(errors)) when not empty?(errors)
+ c
+
diff --git a/src/main/stanza/passes.stanza b/src/main/stanza/passes.stanza
index fb889cf4..53ef2f47 100644
--- a/src/main/stanza/passes.stanza
+++ b/src/main/stanza/passes.stanza
@@ -1665,15 +1665,6 @@ defn gen-constraints (m:Module, h:HashTable<Symbol,Type>, v:Vector<WGeq>) -> Mod
(e:WSubfield) : WSubfield(exp(e),name(e),bundle-field-type(type(exp(e)),name(e)),gender(e))
(e:WIndex) : error("Shouldn't be here")
(e:DoPrim) : DoPrim(op(e),args(e),consts(e),primop-gen-constraints(e,v))
- ;(e:Pad) :
- ; val value-w = width!(value(e))
- ; val pad-w = remove-unknowns-w(width(e))
- ; add(v,WGeq(pad-w, value-w))
- ; val pad-t = match(type(e)) :
- ; (t:UIntType) : UIntType(pad-w)
- ; (t:SIntType) : SIntType(pad-w)
- ; (t) : error("Shouldn't be here")
- ; Pad(value(e),pad-w,pad-t)
(e:ReadPort) : ReadPort(mem(e),index(e),type(type(mem(e)) as VectorType),enable(e))
(e:WritePort) : WritePort(mem(e),index(e),type(type(mem(e)) as VectorType),enable(e))
(e:Register) : Register(type(value(e)),value(e),enable(e))