aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorjackbackrack2015-05-02 23:56:46 -0700
committerjackbackrack2015-05-02 23:56:46 -0700
commit1b57cff7dfc245dd0a0f7a1a591db6dc04e245e0 (patch)
treeb9be5d3c14ef853ed9104c31392973917ea4f2e8 /src
parent07dd1e577a5f605388bc18c37802c8c9a00801a6 (diff)
parent2006604530fb8fd214fe4e8e182bedacd71b49b3 (diff)
merge
Diffstat (limited to 'src')
-rw-r--r--src/main/stanza/errors.stanza139
-rw-r--r--src/main/stanza/firrtl-ir.stanza5
-rw-r--r--src/main/stanza/firrtl-main.stanza1
-rw-r--r--src/main/stanza/firrtl-test-main.stanza1
-rw-r--r--src/main/stanza/passes.stanza103
-rw-r--r--src/main/stanza/primop.stanza1
6 files changed, 216 insertions, 34 deletions
diff --git a/src/main/stanza/errors.stanza b/src/main/stanza/errors.stanza
new file mode 100644
index 00000000..43575854
--- /dev/null
+++ b/src/main/stanza/errors.stanza
@@ -0,0 +1,139 @@
+defpackage firrtl/errors :
+ import core
+ import verse
+ import firrtl/ir2
+ import firrtl/ir-utils
+ import firrtl/primops
+ import firrtl/passes
+ import firrtl-main
+
+;========== ALL CHECKS =================
+;CAUGHT IN PARSER
+; No nested modules <- parser
+; Only modules in circuit (no statements or expressions) <- parser
+
+;CAUGHT in HIGH FORM CHECK
+; Unique names per module
+; No name can be a prefix of any other name.
+; Can only connect to a Ref or Subfield or Index
+; UInt only has positive ints
+; all references are declared
+; mems cannot be a bundle with flips
+; cannot connect to Register or ReadPort
+
+;AFTER KIND RESOLUTION
+; Cannot connect directly to a mem ever
+; onreset can only handle a register
+
+;AFTER TYPE INFERENCE
+; expression in pad must be a ground type
+; Subfields are only on bundles, before type inference <- need to not error, just do unknown-type
+; node's value cannot be a bundle with a flip in it
+; 2nd arg in dshr/l must be UInt
+; pred in conditionally must be of type UInt
+; Type checking
+
+;AFTER WIDTH INFERENCE
+; No names
+; No Unknowns
+; All widths are positive
+; Pad's width is greater than value's width
+; pad's width is greater than value's width
+
+;AFTER LOWERING
+; All things connect to once
+
+; ??
+; No combinational loops
+; cannot connect to a pad, or a register. only connct to a reference
+
+definterface HighFormException <: Exception
+defn HighFormException (s:String) :
+ new HighFormException :
+ defmethod print (o:OutputStream, this) :
+ print(o, s)
+
+defn HighFormExceptions (xs:Streamable<HighFormException>) :
+ HighFormException(string-join(xs, "\n"))
+
+defn NotUnique (info:FileInfo|False, name:Symbol) :
+ HighFormException $ string-join $
+ [info ": Reference " name " does not have a unique name."]
+
+defn IsPrefix (info:FileInfo|False, name:Symbol, prefix:Symbol, dec:FileInfo|False) :
+ HighFormException $ string-join $
+ [info ": Reference " name " is an invalid name because the prefix " prefix " is declared at " dec "."]
+
+defn InvalidLOC (info:FileInfo|False) :
+ HighFormException $ string-join $
+ [info ": Invalid connect to an expression that is not a reference or a WritePort."]
+
+defn NegUInt (info:FileInfo|False) :
+ HighFormException $ string-join $
+ [info ": UInt has a negative value."]
+
+defn UndeclaredReference (info:FileInfo|False, name:Symbol) :
+ HighFormException $ string-join $
+ [info ": Reference " name " is not declared."]
+
+defn MemWithFlip (info:FileInfo|False, name:Symbol) :
+ HighFormException $ string-join $
+ [info ": Memory " name " cannot be a bundle type with flips."]
+
+defn InvalidSubfield (info:FileInfo|False, name:Symbol) :
+ HighFormException $ string-join $
+ [info ": Invalid subfield access to non-reference."]
+
+defn InvalidIndex (info:FileInfo|False, name:Symbol) :
+ HighFormException $ string-join $
+ [info ": Invalid index access to non-reference."]
+
+defn NoTopModule (info:FileInfo|False, name:Symbol) :
+ HighFormException $ string-join $
+ [info ": A single module must be named " name "."]
+
+;================ Check Helper Functions ==============
+defn has-flip? (t:Type) -> True|False :
+ var has? = false
+ defn find-flip (t:Type) -> Type :
+ match(t) :
+ (t:BundleType) :
+ for f in fields(t) do :
+ if flip(f) == REVERSE : has? = true
+ t
+ (t) : t
+ find-flip(t)
+ map(find-flip,t)
+ has?
+;================= High Form Check ==========================
+;CAUGHT in HIGH FORM CHECK
+; o Unique names per module
+; o No name can be a prefix of any other name.
+; o Can only connect to a Ref or Subfield or Index
+; o UInt only has positive ints
+; o all references are declared
+; o cannot connect to Register or ReadPort
+; * A module has the same name as main of circuit
+; * mems cannot be a bundle with flips
+
+public defn check-high-form (c:Circuit) -> Circuit :
+ val errors = Vector<HighFormException>()
+
+ defn check-high-form-s (s:Stmt) -> Stmt :
+ map{check-high-form-s,_} $ match(s) :
+ (s:DefMemory) :
+ if has-flip?(type(s)) : add(errors, MemWithFlip(info!(s), name(s)))
+ s
+ (s) : s
+ defn check-high-form-m (ms:List<Module>) -> False :
+ var number-top-m = 0
+ for m in ms do :
+ if name(m) == main(c) : number-top-m = number-top-m + 1
+ check-high-form-s(body(m))
+ if number-top-m != 1 : add(errors,NoTopModule(info!(c),main(c)))
+
+ check-high-form-m(modules(c))
+ throw(HighFormExceptions(errors)) when not empty?(errors)
+ c
+
+
diff --git a/src/main/stanza/firrtl-ir.stanza b/src/main/stanza/firrtl-ir.stanza
index 63a28211..67d2c2d9 100644
--- a/src/main/stanza/firrtl-ir.stanza
+++ b/src/main/stanza/firrtl-ir.stanza
@@ -2,6 +2,9 @@ defpackage firrtl/ir2 :
import core
import verse
+public defmulti info! (x:?) -> False
+public defmethod info! (x:?) : false
+
public definterface Direction
public val INPUT = new Direction
public val OUTPUT = new Direction
@@ -236,3 +239,5 @@ public defstruct Module :
public defstruct Circuit :
modules: List<Module>
main: Symbol
+
+
diff --git a/src/main/stanza/firrtl-main.stanza b/src/main/stanza/firrtl-main.stanza
index 92bb066f..efc6a7d0 100644
--- a/src/main/stanza/firrtl-main.stanza
+++ b/src/main/stanza/firrtl-main.stanza
@@ -8,6 +8,7 @@
#include("ir-parser.stanza")
#include("passes.stanza")
#include("primop.stanza")
+#include("errors.stanza")
defpackage firrtl-main :
import core
diff --git a/src/main/stanza/firrtl-test-main.stanza b/src/main/stanza/firrtl-test-main.stanza
index f929455d..ca9bfa33 100644
--- a/src/main/stanza/firrtl-test-main.stanza
+++ b/src/main/stanza/firrtl-test-main.stanza
@@ -8,6 +8,7 @@
#include("ir-parser.stanza")
#include("passes.stanza")
#include("primop.stanza")
+#include("errors.stanza")
defpackage firrtl-main :
import core
diff --git a/src/main/stanza/passes.stanza b/src/main/stanza/passes.stanza
index b14a96e3..910b7f3d 100644
--- a/src/main/stanza/passes.stanza
+++ b/src/main/stanza/passes.stanza
@@ -5,6 +5,7 @@ defpackage firrtl/passes :
import firrtl/ir-utils
import firrtl/primops
import firrtl-main
+ import firrtl/errors
;============== EXCEPTIONS =================================
defclass PassException <: Exception
@@ -838,7 +839,9 @@ defn lower (body:Stmt) -> Stmt :
switch fn ([x,y]) : lgender == x and rgender == y :
[FEMALE,MALE] : ConnectToIndexed(index(s),locs,r*)
[MALE,FEMALE] : ConnectFromIndexed(index(s),r*,locs)
- (s:Begin|Conditionally|EmptyStmt) : map(lower-stmt,s)
+ (s:Conditionally) :
+ Conditionally(exp(head $ expand-expr(pred(s))),lower-stmt(conseq(s)),lower-stmt(alt(s)))
+ (s:Begin|EmptyStmt) : map(lower-stmt,s)
lower-stmt(body)
@@ -862,24 +865,38 @@ defn lower-to-ground (c:Circuit) -> Circuit :
defn expand-connect-indexed-stmt (s: Stmt) -> Stmt :
defn equality (e1:Expression,e2:Expression) -> Expression :
DoPrim(EQUAL-UU-OP,list(e1,e2),List(),UIntType(UnknownWidth()))
+ defn get-name (e:Expression) -> Symbol :
+ match(e) :
+ (e:WRef) : symbol-join([name(e) `#])
+ (e:WSubfield) : symbol-join([get-name(exp(e)) `. name(e) `#])
+ (e:WIndex) : symbol-join([get-name(exp(e)) `. to-symbol(value(e)) `#])
+ (e) : `T
match(s) :
(s:ConnectToIndexed) : Begin $
if length(locs(s)) == 0 : list(EmptyStmt())
else :
- List(Connect(head(locs(s)),exp(s)), to-list $
- for (i in 1 to false, l in tail(locs(s))) stream : Conditionally(
- equality(index(s),UIntValue(i,UnknownWidth())),
- Connect(l,exp(s)),
- EmptyStmt())
+ val ref = WRef(firrtl-gensym(get-name(exp(s))),type(index(s)),NodeKind(),UNKNOWN-GENDER)
+ append(
+ list(Connect(head(locs(s)),exp(s)),DefNode(name(ref),index(s)))
+ to-list $
+ for (i in 1 to false, l in tail(locs(s))) stream : Conditionally(
+ equality(ref,UIntValue(i,UnknownWidth())),
+ Connect(l,exp(s)),
+ EmptyStmt()
+ )
)
(s:ConnectFromIndexed) : Begin $
if length(exps(s)) == 0 : list(EmptyStmt())
else :
- List(Connect(loc(s),head(exps(s))), to-list $
- for (i in 1 to false, e in tail(exps(s))) stream : Conditionally(
- equality(index(s),UIntValue(i,UnknownWidth())),
- Connect(loc(s),e),
- EmptyStmt())
+ val ref = WRef(firrtl-gensym(get-name(loc(s))),type(index(s)),NodeKind(),UNKNOWN-GENDER)
+ append(
+ list(Connect(loc(s),head(exps(s))),DefNode(name(ref),index(s)))
+ to-list $
+ for (i in 1 to false, e in tail(exps(s))) stream : Conditionally(
+ equality(ref,UIntValue(i,UnknownWidth())),
+ Connect(loc(s),e),
+ EmptyStmt()
+ )
)
(s) : map(expand-connect-indexed-stmt,s)
@@ -1349,6 +1366,11 @@ defmethod equal? (w1:Width,w2:Width) -> True|False :
if not contains?(args(w2),w) : ret(false)
ret(true)
(w1:IntWidth,w2:IntWidth) : width(w1) == width(w2)
+ (w1:PlusWidth,w2:PlusWidth) :
+ (arg1(w1) == arg1(w2) and arg2(w1) == arg2(w2)) or (arg1(w1) == arg2(w2) and arg2(w1) == arg1(w2))
+ (w1:MinusWidth,w2:MinusWidth) :
+ (arg1(w1) == arg1(w2) and arg2(w1) == arg2(w2)) or (arg1(w1) == arg2(w2) and arg2(w1) == arg1(w2))
+ (w1:ExpWidth,w2:ExpWidth) : arg1(w1) == arg1(w2)
(w1:UnknownWidth,w2:UnknownWidth) : true
(w1,w2) : false
defn apply (a:Int|False,b:Int|False, f: (Int,Int) -> Int) -> Int|False :
@@ -1380,6 +1402,18 @@ defn solve-constraints (l:List<WGeq>) -> HashTable<Symbol,Int> :
for x in args(w*) do : add(v,x)
(w*) : add(v,w*)
MaxWidth(unique(v))
+ (w:PlusWidth) :
+ match(arg1(w),arg2(w)) :
+ (w1:IntWidth,w2:IntWidth) : IntWidth(width(w1) + width(w2))
+ (w1,w2) : w
+ (w:MinusWidth) :
+ match(arg1(w),arg2(w)) :
+ (w1:IntWidth,w2:IntWidth) : IntWidth(width(w1) - width(w2))
+ (w1,w2) : w
+ (w:ExpWidth) :
+ match(arg1(w)) :
+ (w1:IntWidth) : IntWidth(pow(2,width(w1)) - 1)
+ (w1) : w
(w) : w
defn substitute (w:Width,h:HashTable<Symbol,Width>) -> Width :
;println-all-debug(["Substituting for [" w "]"])
@@ -1458,25 +1492,25 @@ defn solve-constraints (l:List<WGeq>) -> HashTable<Symbol,Int> :
; 2) Remove Cycles
; 3) Move to solved if not self-recursive
val u = make-unique(l)
- ;println-debug("======== UNIQUE CONSTRAINTS ========")
- ;for x in u do : println-debug(x)
- ;println-debug("====================================")
+ println-debug("======== UNIQUE CONSTRAINTS ========")
+ for x in u do : println-debug(x)
+ println-debug("====================================")
val f = HashTable<Symbol,Width>(symbol-hash)
val o = Vector<Symbol>()
for x in u do :
- ;println-debug("==== SOLUTIONS TABLE ====")
- ;for x in f do : println-debug(x)
- ;println-debug("=========================")
+ println-debug("==== SOLUTIONS TABLE ====")
+ for x in f do : println-debug(x)
+ println-debug("=========================")
val [n e] = [key(x) value(x)]
val e-sub = substitute(e,f)
- ;println-debug(["Solving " n " => " e])
- ;println-debug(["After Substitute: " n " => " e-sub])
- ;println-debug("==== SOLUTIONS TABLE (Post Substitute) ====")
- ;for x in f do : println-debug(x)
- ;println-debug("=========================")
+ println-debug(["Solving " n " => " e])
+ println-debug(["After Substitute: " n " => " e-sub])
+ println-debug("==== SOLUTIONS TABLE (Post Substitute) ====")
+ for x in f do : println-debug(x)
+ println-debug("=========================")
val e* = remove-cycle{n,_} $ e-sub
;println-debug(["After Remove Cycle: " n " => " e*])
if not self-rec?(n,e*) :
@@ -1485,28 +1519,28 @@ defn solve-constraints (l:List<WGeq>) -> HashTable<Symbol,Int> :
add(o,n)
f[n] = e*
- ;println-debug("Forward Solved Constraints")
- ;for x in f do : println-debug(x)
+ println-debug("Forward Solved Constraints")
+ for x in f do : println-debug(x)
; Backwards Solve
val b = HashTable<Symbol,Width>(symbol-hash)
for i in (length(o) - 1) through 0 by -1 do :
val n = o[i]
- ;println-all-debug(["SOLVE BACK: [" n " => " f[n] "]"])
- ;println-debug("==== SOLUTIONS TABLE ====")
- ;for x in b do : println-debug(x)
- ;println-debug("=========================")
+ println-all-debug(["SOLVE BACK: [" n " => " f[n] "]"])
+ println-debug("==== SOLUTIONS TABLE ====")
+ for x in b do : println-debug(x)
+ println-debug("=========================")
val e* = simplify(b-sub(f[n],b))
- ;println-all-debug(["BACK RETURN: [" n " => " e* "]"])
+ println-all-debug(["BACK RETURN: [" n " => " e* "]"])
b[n] = e*
- ;println-debug("==== SOLUTIONS TABLE (Post backsolve) ====")
- ;for x in b do : println-debug(x)
- ;println-debug("=========================")
+ println-debug("==== SOLUTIONS TABLE (Post backsolve) ====")
+ for x in b do : println-debug(x)
+ println-debug("=========================")
; Evaluate
val e = evaluate(b)
- ;println-debug("Evaluated Constraints")
- ;for x in e do : println-debug(x)
+ println-debug("Evaluated Constraints")
+ for x in e do : println-debug(x)
e
public defn width! (t:Type) -> Width :
@@ -1979,6 +2013,7 @@ public defn run-passes (c: Circuit, p: List<Char>,file:String) :
; Early passes:
; If modules have a reset defined, must be an INPUT and UInt(1)
+ if contains(p,'X') or contains(p,'A') : do-stage("High Form Check", check-high-form)
if contains(p,'X') or contains(p,'a') : do-stage("Temp Elimination", temp-elimination)
if contains(p,'X') or contains(p,'b') : do-stage("Working IR", to-working-ir)
if contains(p,'X') or contains(p,'c') : do-stage("Make Explicit Reset", make-explicit-reset)
diff --git a/src/main/stanza/primop.stanza b/src/main/stanza/primop.stanza
index b293da52..34dd0392 100644
--- a/src/main/stanza/primop.stanza
+++ b/src/main/stanza/primop.stanza
@@ -185,6 +185,7 @@ public defn lower-and-type-primop (e:DoPrim) -> DoPrim :
match(type(args(e)[1]),type(args(e)[2])) :
(t1:UIntType, t2:UIntType) : MUX-UU-OP
(t1:SIntType, t2:SIntType) : MUX-SS-OP
+ (t1,t2) : error(to-string(args(e)))
MUX-UU-OP : DoPrim(op(e),args(e),consts(e),u())
MUX-SS-OP : DoPrim(op(e),args(e),consts(e),s())
PAD-OP :