aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorjackbackrack2015-04-22 21:14:38 -0700
committerjackbackrack2015-04-22 21:14:38 -0700
commita60a8951ff54342ee7d57484a535b05daebd3341 (patch)
treecd70427839cd42c8b7b7e650e399e8e8880e0ff0 /src
parentd1bc615be8e214713d5b13a767b2a8abbeeb173a (diff)
parenta4f7aa2b81a021f21a49bd4059d051bc0f949880 (diff)
merge
Diffstat (limited to 'src')
-rw-r--r--src/main/stanza/firrtl-ir.stanza4
-rw-r--r--src/main/stanza/firrtl-test-main.stanza1
-rw-r--r--src/main/stanza/ir-parser.stanza16
-rw-r--r--src/main/stanza/ir-utils.stanza4
-rw-r--r--src/main/stanza/passes.stanza196
-rw-r--r--src/main/stanza/primop.stanza214
6 files changed, 242 insertions, 193 deletions
diff --git a/src/main/stanza/firrtl-ir.stanza b/src/main/stanza/firrtl-ir.stanza
index d4d12400..f14378cc 100644
--- a/src/main/stanza/firrtl-ir.stanza
+++ b/src/main/stanza/firrtl-ir.stanza
@@ -161,6 +161,10 @@ public defstruct Register <: Expression :
type: Type with: (as-method => true)
value: Expression
enable: Expression
+public defstruct Pad <: Expression :
+ value: Expression
+ width: Width
+ type: Type with: (as-method => true)
public definterface Stmt
public defstruct DefWire <: Stmt : ;LOW
diff --git a/src/main/stanza/firrtl-test-main.stanza b/src/main/stanza/firrtl-test-main.stanza
index 54fcb7f9..f929455d 100644
--- a/src/main/stanza/firrtl-test-main.stanza
+++ b/src/main/stanza/firrtl-test-main.stanza
@@ -25,6 +25,7 @@ defn set-printvars! (p:List<Char>) :
if contains(p,'T') : PRINT-TWIDTHS = true
if contains(p,'g') : PRINT-GENDERS = true
if contains(p,'c') : PRINT-CIRCUITS = true
+ if contains(p,'d') : PRINT-DEBUG = true
;firrtl -i gcd.fir -o gcd.flo -x qabcefghipjklmno -p c
defn main () :
diff --git a/src/main/stanza/ir-parser.stanza b/src/main/stanza/ir-parser.stanza
index 6ec0c4d2..1772d773 100644
--- a/src/main/stanza/ir-parser.stanza
+++ b/src/main/stanza/ir-parser.stanza
@@ -203,13 +203,19 @@ defsyntax firrtl :
operators[`bit-or-reduce] = BIT-OR-REDUCE-OP
operators[`bit-xor-reduce] = BIT-XOR-REDUCE-OP
+ defrule width :
+ width = (?) :
+ UnknownWidth()
+ width = (?width:#int) :
+ IntWidth(ut(width))
+
defrule exp-form :
- exp-form = (UInt (@do ?value:#int ?width:#int)) :
- UIntValue(ut(value), IntWidth(ut(width)))
+ exp-form = (UInt (@do ?value:#int ?width:#width)) :
+ UIntValue(ut(value), width)
exp-form = (UInt (@do ?value:#int)) :
UIntValue(ut(value), UnknownWidth())
- exp-form = (SInt (@do ?value:#int ?width:#int)) :
- SIntValue(ut(value), IntWidth(ut(width)))
+ exp-form = (SInt (@do ?value:#int ?width:#width)) :
+ SIntValue(ut(value), width)
exp-form = (SInt (@do ?value:#int)) :
SIntValue(ut(value), UnknownWidth())
exp-form = (WritePort (@do ?mem:#exp ?index:#exp ?enable:#exp)) :
@@ -218,6 +224,8 @@ defsyntax firrtl :
ReadPort(mem, index, UnknownType(), enable)
exp-form = (Register (@do ?value:#exp ?enable:#exp)) :
Register(UnknownType(),value,enable)
+ exp-form = (Pad (@do ?value:#exp ?width:#width)) :
+ Pad(value,width,UnknownType())
exp-form = (?op:#symbol (@do ?es:#exp ... ?ints:#int ...)) :
println("Op-symbol is:~" % [op])
match(get?(operators, ut(op), false)) :
diff --git a/src/main/stanza/ir-utils.stanza b/src/main/stanza/ir-utils.stanza
index 2df09b8e..86fe56d1 100644
--- a/src/main/stanza/ir-utils.stanza
+++ b/src/main/stanza/ir-utils.stanza
@@ -150,6 +150,7 @@ defmethod print (o:OutputStream, e:Expression) :
(e:ReadPort) : print-all(o, ["ReadPort(" mem(e) ", " index(e) ", " enable(e) ")"])
(e:WritePort) : print-all(o, ["WritePort(" mem(e) ", " index(e) ", " enable(e) ")"])
(e:Register) : print-all(o, ["Register(" value(e) ", " enable(e) ")"])
+ (e:Pad) : print-all(o, ["Pad(" value(e) ", " width(e) ")"])
print-debug(o,e)
defmethod print (o:OutputStream, c:Stmt) :
@@ -246,6 +247,7 @@ defmethod map (f: Expression -> Expression, e:Expression) -> Expression :
(e:ReadPort) : ReadPort(f(mem(e)), f(index(e)), type(e), f(enable(e)))
(e:WritePort) : WritePort(f(mem(e)), f(index(e)), type(e), f(enable(e)))
(e:Register) : Register(type(e),f(value(e)),f(enable(e)))
+ (e:Pad) : Pad(f(value(e)),width(e),type(e))
(e) : e
public defmulti map<?T> (f: Expression -> Expression, c:?T&Stmt) -> T
@@ -270,6 +272,7 @@ defmethod map (f: Width -> Width, c:Expression) -> Expression :
match(c) :
(c:UIntValue) : UIntValue(value(c),f(width(c)))
(c:SIntValue) : SIntValue(value(c),f(width(c)))
+ (c:Pad) : Pad(value(c),f(width(c)),type(c))
(c) : c
public defmulti map<?T> (f: Width -> Width, c:?T&Type) -> T
@@ -289,6 +292,7 @@ defmethod map (f: Type -> Type, c:Expression) -> Expression :
(c:ReadPort) : ReadPort(mem(c),index(c),f(type(c)),enable(c))
(c:WritePort) : WritePort(mem(c),index(c),f(type(c)),enable(c))
(c:Register) : Register(f(type(c)),value(c),enable(c))
+ (c:Pad) : Pad(value(c),width(c),f(type(c)))
(c) : c
public defmulti map<?T> (f: Type -> Type, c:?T&Stmt) -> T
diff --git a/src/main/stanza/passes.stanza b/src/main/stanza/passes.stanza
index c4e4598b..8ca29258 100644
--- a/src/main/stanza/passes.stanza
+++ b/src/main/stanza/passes.stanza
@@ -155,7 +155,17 @@ public var PRINT-WIDTHS : True|False = false
public var PRINT-TWIDTHS : True|False = false
public var PRINT-GENDERS : True|False = false
public var PRINT-CIRCUITS : True|False = false
+public var PRINT-DEBUG : True|False = false
;=== Printers ===
+
+public defn println-all-debug (l:?) -> False :
+ if PRINT-DEBUG : println-all(l)
+ else : false
+
+public defn println-debug (s:?) -> False :
+ if PRINT-DEBUG : println(s)
+ else : false
+
defmethod print (o:OutputStream, k:Kind) :
print{o, _} $
match(k) :
@@ -175,12 +185,12 @@ defn hasGender (e:Expression|Stmt|Type|Port|Field) :
e typeof WRef|WSubfield|WIndex|WDefAccessor|WRegInit
defn hasWidth (e:Expression|Stmt|Type|Port|Field) :
- e typeof UIntType|SIntType|UIntValue|SIntValue
+ e typeof UIntType|SIntType|UIntValue|SIntValue|Pad
defn hasType (e:Expression|Stmt|Type|Port|Field) :
e typeof Ref|Subfield|Index|DoPrim|WritePort|ReadPort|WRef|WSubfield
|WIndex|DefWire|DefRegister|DefMemory|Register
- |VectorType|Port|Field|WRegInit
+ |VectorType|Port|Field|WRegInit|Pad
defn hasKind (e:Expression|Stmt|Type|Port|Field) :
e typeof WRef
@@ -446,6 +456,8 @@ defn infer-exp-types (e:Expression, l:List<KeyValue<Symbol,Type>>) -> Expression
;DoPrim(op(e),args(e),consts(e),get-primop-rettype(e))
(e:ReadPort) : ReadPort(mem(e),index(e),get-vector-subtype(type(mem(e))),enable(e))
(e:WritePort) : WritePort(mem(e),index(e),get-vector-subtype(type(mem(e))),enable(e))
+ (e:Register) : Register(type(value(e)),value(e),enable(e))
+ (e:Pad) : Pad(value(e),width(e),type(value(e)))
(e:UIntValue|SIntValue) : e
defn infer-types (s:Stmt, l:List<KeyValue<Symbol,Type>>) -> [Stmt List<KeyValue<Symbol,Type>>] :
@@ -474,7 +486,7 @@ defn infer-types (m:Module, l:List<KeyValue<Symbol,Type>>) -> Module :
val ptypes =
for p in ports(m) map :
name(p) => type(p)
- ;println-all(append(ptypes,l))
+ println-all-debug(append(ptypes,l))
val [s,l*] = infer-types(body(m),append(ptypes, l))
Module(name(m),ports(m),s)
@@ -482,7 +494,7 @@ defn infer-types (c:Circuit) -> Circuit :
val l =
for m in modules(c) map :
name(m) => BundleType(map(to-field,ports(m)))
- ;println-all(l)
+ println-all-debug(l)
Circuit{ _, main(c) } $
for m in modules(c) map :
infer-types(m,l)
@@ -587,11 +599,11 @@ defn resolve-genders (c:Circuit) :
(e) : map(resolve-expr{_,MALE},e)
var module* = resolve-iter(m)
- ;println(genders)
+ println-debug(genders)
while not done? :
done? = true
module* = resolve-iter(m)
- ;println(genders)
+ ;println-debug(genders)
module*
defn resolve-genders (m:Module, c:Circuit) -> Module :
@@ -619,7 +631,7 @@ defn expand-vector (e:Expression) -> List<Expression> :
defn expand-stmt (s:Stmt) -> Stmt :
match(s) :
(s:WDefAccessor) :
- ;println-all(["Matched WDefAcc with " name(s)])
+ println-all-debug(["Matched WDefAcc with " name(s)])
val mem? = match(source(s)) :
(e:WRef) : kind(e) typeof MemKind
(e) : false
@@ -715,11 +727,11 @@ defn lower (body:Stmt, table:HashTable<Symbol,List<KeyValue<Expression,Flip>>>)
lower-stmt(s*)
(s:Connect) : Begin{_} $
for (l in expand-expr(loc(s)), r in expand-expr(exp(s))) map :
- println(s)
+ println-debug(s)
val lgender = calc-gender(FEMALE,loc(s)) * value(l)
val rgender = calc-gender(MALE,exp(s)) * value(r)
- println(loc(s))
- println(exp(s))
+ println-debug(loc(s))
+ println-debug(exp(s))
switch fn ([x,y]) : lgender == x and rgender == y :
[FEMALE,MALE] : Connect(key(l),key(r))
[MALE,FEMALE] : Connect(key(r),key(l))
@@ -779,7 +791,7 @@ defn lower (body:Stmt, table:HashTable<Symbol,List<KeyValue<Expression,Flip>>>)
headn(tailn(exps,len * value(e)),len)
(e) : list(KeyValue(e, DEFAULT))
- ;println(table)
+ ;println-debug(table)
lower-stmt(body)
defn get-entries (n:Symbol,t:Type) -> List<KeyValue<WRef,Flip>> :
@@ -955,7 +967,7 @@ defn initialize-registers (c:Circuit) :
defn explicit-init-scope (s:Stmt) -> Stmt :
val h = HashTable<Symbol,True|False>(symbol-hash)
using-init(s,h)
- ;println(h)
+ ;println-debug(h)
val [s* t] = rename(s,h)
add-when(s*,t)
@@ -1262,7 +1274,7 @@ defn build-tables (s:Stmt,
add(decs,s)
for f in fields(type(module(s)) as BundleType) do :
val n = to-symbol("~.~" % [name(s),name(f)]) ; only on inputs
- ;println-all(["In DefInst adding: " n])
+ println-all-debug(["In DefInst adding: " n])
kinds[n] = InstanceKind()
assign[n] = SVNul()
stmts[n] = s
@@ -1282,12 +1294,12 @@ defn build-tables (s:Stmt,
if kinds[i] typeof WireKind|InstanceKind|NodeKind : a
else : SVMux(pred(s),SVNul(),a)
(c:False,a:False) : error("Shouldn't be here")
- ;println("TABLE-C")
- ;for x in assign-c do : println(x)
- ;println("TABLE-A")
- ;for x in assign-a do : println(x)
- ;println("TABLE")
- ;for x in assign do : println(x)
+ ;println-debug("TABLE-C")
+ ;for x in assign-c do : println-debug(x)
+ ;println-debug("TABLE-A")
+ ;for x in assign-a do : println-debug(x)
+ ;println-debug("TABLE")
+ ;for x in assign do : println-debug(x)
(s:Connect) :
val key* = match(loc(s)) :
(e:WRef) : name(e)
@@ -1314,14 +1326,14 @@ defn expand-whens (m:Module) -> Module :
val enables = get-enables(assign,kinds)
for x in enables do : enables[key(x)] = optimize(value(x))
- ;println("Assigns")
- ;for x in assign do : println(x)
- ;println("Kinds")
- ;for x in kinds do : println(x)
- ;println("Decs")
- ;for x in decs do : println(x)
- ;println("Enables")
- ;for x in enables do : println(x)
+ ;println-debug("Assigns")
+ ;for x in assign do : println-debug(x)
+ ;println-debug("Kinds")
+ ;for x in kinds do : println-debug(x)
+ ;println-debug("Decs")
+ ;for x in decs do : println-debug(x)
+ ;println-debug("Enables")
+ ;for x in enables do : println-debug(x)
Module(name(m),ports(m),expand-whens(assign,kinds,stmts,decs,enables))
@@ -1412,30 +1424,30 @@ defn solve-constraints (l:List<WGeq>) -> HashTable<Symbol,Int> :
val v = Vector<Width>()
for w* in args(w) do :
match(w*) :
- (w:MaxWidth) :
- for x in args(w) do : add(v,x)
- (w) : add(v,w)
+ (w*:MaxWidth) :
+ for x in args(w*) do : add(v,x)
+ (w*) : add(v,w*)
MaxWidth(unique(v))
(w) : w
defn substitute (w:Width,h:HashTable<Symbol,Width>) -> Width :
- ;println-all(["Substituting for [" w "]"])
+ ;println-all-debug(["Substituting for [" w "]"])
val w* = simplify(w)
- ;println-all(["After Simplify: [" w "]"])
+ ;println-all-debug(["After Simplify: [" w* "]"])
match(map(substitute{_,h},simplify(w))) :
(w:VarWidth) :
- ;println("matched varwidth!")
+ ;println-debug("matched varwidth!")
if contains?(name(w),h) :
- ;println("Contained!")
- ;println-all(["Width: " w])
- ;println-all(["Accessed: " h[name(w)]])
+ ;println-debug("Contained!")
+ ;println-all-debug(["Width: " w])
+ ;println-all-debug(["Accessed: " h[name(w)]])
val t = simplify(substitute(h[name(w)],h))
;val t = h[name(w)]
- ;println-all(["Width after sub: " t])
+ ;println-all-debug(["Width after sub: " t])
h[name(w)] = t
t
else : w
(w):
- ;println-all(["not varwidth!" w])
+ ;println-all-debug(["not varwidth!" w])
w
defn b-sub (w:Width,h:HashTable<Symbol,Width>) -> Width:
match(map(b-sub{_,h},w)) :
@@ -1444,11 +1456,11 @@ defn solve-constraints (l:List<WGeq>) -> HashTable<Symbol,Int> :
else : w
(w) : w
defn remove-cycle (n:Symbol,w:Width) -> Width :
- ;println-all(["Removing cycle for " n " inside " w])
+ ;println-all-debug(["Removing cycle for " n " inside " w])
val w* = match(map(remove-cycle{n,_},w)) :
(w:MaxWidth) : MaxWidth(to-list(filter({_ != VarWidth(n)},args(w))))
(w) : w
- ;println-all(["After removing cycle for " n ", returning " w*])
+ ;println-all-debug(["After removing cycle for " n ", returning " w*])
w*
defn self-rec? (n:Symbol,w:Width) -> True|False :
var has? = false
@@ -1467,7 +1479,7 @@ defn solve-constraints (l:List<WGeq>) -> HashTable<Symbol,Int> :
if length(l) == 0 : 0
else : apply(head(l),apply-l(tail(l),f),f)
defn max (a:Int,b:Int) -> Int :
- if a > b : a
+ if a >= b : a
else : b
defn solve (w:Width) -> Int|False :
match(w) :
@@ -1490,55 +1502,55 @@ 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("======== UNIQUE CONSTRAINTS ========")
- ;for x in u do : println(x)
- ;println("====================================")
+ ;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("==== SOLUTIONS TABLE ====")
- ;for x in f do : println(x)
- ;println("=========================")
+ ;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(["Solving " n " => " e])
- ;println(["After Substitute: " n " => " e-sub])
- ;println("==== SOLUTIONS TABLE (Post Substitute) ====")
- ;for x in f do : println(x)
- ;println("=========================")
+ ;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(["After Remove Cycle: " n " => " e*])
+ ;println-debug(["After Remove Cycle: " n " => " e*])
if not self-rec?(n,e*) :
- ;println-all(["Not rec!: " n " => " e*])
- ;println-all(["Adding [" n "=>" e* "] to Solutions Table"])
+ ;println-all-debug(["Not rec!: " n " => " e*])
+ ;println-all-debug(["Adding [" n "=>" e* "] to Solutions Table"])
add(o,n)
f[n] = e*
- ;println("Forward Solved Constraints")
- ;for x in f do : println(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(["SOLVE BACK: [" n " => " f[n] "]"])
- ;println("==== SOLUTIONS TABLE ====")
- ;for x in b do : println(x)
- ;println("=========================")
+ ;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(["BACK RETURN: [" n " => " e* "]"])
+ ;println-all-debug(["BACK RETURN: [" n " => " e* "]"])
b[n] = e*
- ;println("==== SOLUTIONS TABLE (Post backsolve) ====")
- ;for x in b do : println(x)
- ;println("=========================")
+ ;println-debug("==== SOLUTIONS TABLE (Post backsolve) ====")
+ ;for x in b do : println-debug(x)
+ ;println-debug("=========================")
; Evaluate
val e = evaluate(b)
- ;println("Evaluated Constraints")
- ;for x in e do : println(x)
+ ;println-debug("Evaluated Constraints")
+ ;for x in e do : println-debug(x)
e
public defn width! (t:Type) -> Width :
@@ -1549,7 +1561,6 @@ public defn width! (t:Type) -> Width :
public defn width! (e:Expression) -> Width : width!(type(e))
defn gen-constraints (m:Module, h:HashTable<Symbol,Type>, v:Vector<WGeq>) -> Module:
-
defn gen-constraints-s (s:Stmt) -> Stmt :
match(map(gen-constraints-s,s)) :
(s:DefWire) : DefWire(name(s),h[name(s)])
@@ -1570,6 +1581,15 @@ 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, IntWidth(0)))
+ 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))
@@ -1610,13 +1630,13 @@ defn build-environment (c:Circuit,m:Module,h:HashTable<Symbol,Type>) -> HashTabl
defn replace-var-widths (c:Circuit,h:HashTable<Symbol,Int>) -> Circuit :
defn replace-var-widths-w (w:Width) -> Width :
- ;println-all(["REPLACE: " w])
+ println-all-debug(["REPLACE: " w])
val w* = match(w) :
(w:VarWidth) :
if key?(h,name(w)) : IntWidth(h[name(w)])
else: w
(w) : w
- ;println-all(["WITH: " w*])
+ println-all-debug(["WITH: " w*])
w*
val modules* = for m in modules(c) map :
@@ -1639,29 +1659,27 @@ defn infer-widths (c:Circuit) -> Circuit :
for x in t do :
t0[key(x)] = value(x)
- ;val c* = remove-unknown-widths(c)
- ;println(c*)
val v = Vector<WGeq>()
val ports* = HashTable<Symbol,Type>(symbol-hash)
for m in modules(c) do :
ports*[name(m)] = remove-unknowns(BundleType(map(to-field,ports(m))))
val modules* = for m in modules(c) map :
- ;println-all(["====== MODULE(" name(m) ") ENV ======"])
+ println-all-debug(["====== MODULE(" name(m) ") ENV ======"])
val h = build-environment(c,m,deepcopy(ports*))
- ;for x in h do: println(x)
- ;println-all(["====================================="])
+ for x in h do: println-debug(x)
+ println-all-debug(["====================================="])
val m* = gen-constraints(m,h,v)
- ;println-all(["====== MODULE(" name(m) ") ======"])
- ;println(m*)
- ;println-all(["====================================="])
+ println-all-debug(["====== MODULE(" name(m) ") ======"])
+ println-debug(m*)
+ println-all-debug(["====================================="])
m*
- ;println("======== ALL CONSTRAINTS ========")
- ;for x in v do : println(x)
- ;println("=================================")
+ println-debug("======== ALL CONSTRAINTS ========")
+ for x in v do : println-debug(x)
+ println-debug("=================================")
val h = solve-constraints(to-list(v))
- ;println("======== SOLVED CONSTRAINTS ========")
- ;for x in h do : println(x)
- ;println("====================================")
+ println-debug("======== SOLVED CONSTRAINTS ========")
+ for x in h do : println-debug(x)
+ println-debug("====================================")
replace-var-widths(Circuit(modules*,main(c)),h)
@@ -1738,7 +1756,7 @@ defn split-exp (c:Circuit) :
false
defn split-exp-e (e:Expression,v:Vector<Stmt>,n:Symbol|False) -> Expression :
match(map(split-exp-e{_,v,n},e)):
- (e:Subfield|DoPrim|ReadPort|Register|WritePort) :
+ (e:Subfield|DoPrim|Pad|ReadPort|Register|WritePort) :
val n* =
if n typeof False : gensym(`T)
else : to-symbol $ string-join $ [n as Symbol gensym(`#)]
@@ -1836,6 +1854,8 @@ defn flo-op-name (op:PrimOp) -> String :
MUX-SS-OP : "mux"
PAD-U-OP : "rsh" ;; todo: signed version
PAD-S-OP : "rsh" ;; todo: signed version
+ NEG-U-OP : "neg"
+ NEG-S-OP : "neg"
;AS-UINT-U-OP :
;AS-UINT-S-OP :
;AS-SINT-U-OP :
@@ -1889,6 +1909,8 @@ defn emit! (e:Expression,top:Symbol) :
(e:SIntValue) : emit-all([value(e) "'" sane-width(width(e))], top)
(e:Subfield) : emit-all([exp(e) "/" name(e)], top)
(e:Index) : emit-all([exp(e) "/" value(e)], top)
+ (e:Pad) :
+ emit-all(["rsh'" prim-width(type(e)) " " value(e) " " width(e)], top)
(e:Register) :
emit-all(["reg'" prim-width(type(e)) " 1 " value(e)], top) ;; enable(e)
(e:ReadPort) :
@@ -1910,8 +1932,8 @@ defn emit! (e:Expression,top:Symbol) :
;; emit-all([flo-op-name(op(e)) "'" w " " args(e)[0] " " consts(e)[1]], top)
else :
emit-all([flo-op-name(op(e)) "'" prim-width(type(e))], top)
- if op(e) == PAD-OP :
- emit-all([" " args(e)[0] " 0"], top)
+ if (op(e) == PAD-U-OP) or (op(e) == PAD-S-OP) :
+ emit-all([" " args(e)[0] " " consts(e)[0]], top)
else :
for arg in args(e) do :
print(" ")
diff --git a/src/main/stanza/primop.stanza b/src/main/stanza/primop.stanza
index b42380e6..14589135 100644
--- a/src/main/stanza/primop.stanza
+++ b/src/main/stanza/primop.stanza
@@ -248,106 +248,116 @@ public defn lower-and-type-primop (e:DoPrim) -> DoPrim :
BIT-XOR-REDUCE-OP: DoPrim(op(e),args(e),consts(e),u())
public defn primop-gen-constraints (e:DoPrim,v:Vector<WGeq>) -> Type :
- defn add-c (w:Width) -> Type:
- val w* = VarWidth(gensym(`w))
- add(v,WGeq(w*,w))
- add(v,WGeq(w,w*))
- match(type(e)) :
- (t:UIntType) : UIntType(w*)
- (t:SIntType) : SIntType(w*)
- (t) : error("Shouldn't be here")
- defn wpc (l:List<Expression>,c:List<Int>) :
- add-c(PlusWidth(width!(l[0]),IntWidth(c[0])))
- defn wmc (l:List<Expression>,c:List<Int>) :
- add-c(MinusWidth(width!(l[0]),IntWidth(c[0])))
- defn maxw (l:List<Expression>) :
- add-c(MaxWidth(map(width!,l)))
- defn cons (ls:List<Expression>) :
- val l = width!(ls[0])
- val r = width!(ls[1])
- add(v,WGeq(l,r))
- add(v,WGeq(r,l))
- add-c(l)
- add-c(r)
- defn mp1 (l:List<Expression>) :
- add-c(PlusWidth(MaxWidth(list(width!(l[0]),width!(l[1]))),IntWidth(1)))
- defn sum (l:List<Expression>) :
- add-c(PlusWidth(width!(l[0]),width!(l[1])))
+ defn all-equal (ls:List<Expression>) -> Width :
+ if length(ls) == 1 : width!(ls[0])
+ else :
+ val m = MaxWidth(map(width!,ls))
+ for (l in ls) do :
+ add(v,WGeq(width!(l),m))
+ m
+ ;defn new-width (w:Width) -> Width:
+ ; val w* = VarWidth(gensym(`w))
+ ; add(v,WGeq(w*,w))
+ ; ;add(v,WGeq(w,w*))
+ ; w*
+ ;defn width-plus-const (l:List<Expression>,c:List<Int>) -> Width :
+ ; new-width(PlusWidth(width!(l[0]),IntWidth(c[0])))
+ ;defn width-minus-const (l:List<Expression>,c:List<Int>) -> Width :
+ ; new-width(MinusWidth(width!(l[0]),IntWidth(c[0])))
+ ;defn max-width (l:List<Expression>) -> Width :
+ ; new-width(MaxWidth(map(width!,l)))
+ ;defn max-plus-one (l:List<Expression>) -> Width :
+ ; new-width(PlusWidth(MaxWidth(list(width!(l[0]),width!(l[1]))),IntWidth(1)))
+ ;defn sum (l:List<Expression>) -> Width :
+ ; new-width(PlusWidth(width!(l[0]),width!(l[1])))
+
+ println-all-debug(["Looking at " op(e) " with inputs " args(e)])
+ val all-args-not-equal = list(MUX-UU-OP,MUX-SS-OP,CONCAT-OP)
+ ;val consts-gte-args = list(PAD-U-OP,PAD-S-OP)
+
+ val w* =
+ if not contains?(all-args-not-equal,op(e)) :
+ val max-args-w = all-equal(args(e))
+ switch {op(e) == _} :
+ ADD-UU-OP : PlusWidth(max-args-w,IntWidth(1))
+ ADD-US-OP : PlusWidth(max-args-w,IntWidth(1))
+ ADD-SU-OP : PlusWidth(max-args-w,IntWidth(1))
+ ADD-SS-OP : PlusWidth(max-args-w,IntWidth(1))
+ SUB-UU-OP : PlusWidth(max-args-w,IntWidth(1))
+ SUB-US-OP : PlusWidth(max-args-w,IntWidth(1))
+ SUB-SU-OP : PlusWidth(max-args-w,IntWidth(1))
+ SUB-SS-OP : PlusWidth(max-args-w,IntWidth(1))
+ MUL-UU-OP : PlusWidth(max-args-w,max-args-w)
+ MUL-US-OP : PlusWidth(max-args-w,max-args-w)
+ MUL-SU-OP : PlusWidth(max-args-w,max-args-w)
+ MUL-SS-OP : PlusWidth(max-args-w,max-args-w)
+ DIV-UU-OP : max-args-w
+ DIV-US-OP : PlusWidth(max-args-w,IntWidth(1))
+ DIV-SU-OP : max-args-w
+ DIV-SS-OP : PlusWidth(max-args-w,IntWidth(1))
+ ADD-WRAP-UU-OP : max-args-w
+ ADD-WRAP-US-OP : max-args-w
+ ADD-WRAP-SU-OP : max-args-w
+ ADD-WRAP-SS-OP : max-args-w
+ SUB-WRAP-UU-OP : max-args-w
+ SUB-WRAP-US-OP : max-args-w
+ SUB-WRAP-SU-OP : max-args-w
+ SUB-WRAP-SS-OP : max-args-w
+ LESS-UU-OP : IntWidth(1)
+ LESS-US-OP : IntWidth(1)
+ LESS-SU-OP : IntWidth(1)
+ LESS-SS-OP : IntWidth(1)
+ LESS-EQ-UU-OP : IntWidth(1)
+ LESS-EQ-US-OP : IntWidth(1)
+ LESS-EQ-SU-OP : IntWidth(1)
+ LESS-EQ-SS-OP : IntWidth(1)
+ GREATER-UU-OP : IntWidth(1)
+ GREATER-US-OP : IntWidth(1)
+ GREATER-SU-OP : IntWidth(1)
+ GREATER-SS-OP : IntWidth(1)
+ GREATER-EQ-UU-OP : IntWidth(1)
+ GREATER-EQ-US-OP : IntWidth(1)
+ GREATER-EQ-SU-OP : IntWidth(1)
+ GREATER-EQ-SS-OP : IntWidth(1)
+ EQUAL-UU-OP : IntWidth(1)
+ EQUAL-SS-OP : IntWidth(1)
+ NEQUAL-UU-OP : IntWidth(1)
+ NEQUAL-SS-OP : IntWidth(1)
+ PAD-U-OP : IntWidth(consts(e)[0])
+ PAD-S-OP : IntWidth(consts(e)[0])
+ NEG-U-OP : IntWidth(1)
+ NEG-S-OP : IntWidth(1)
+ AS-UINT-U-OP : max-args-w
+ AS-UINT-S-OP : max-args-w
+ AS-SINT-U-OP : max-args-w
+ AS-SINT-S-OP : max-args-w
+ SHIFT-LEFT-U-OP : PlusWidth(max-args-w,IntWidth(consts(e)[0]))
+ SHIFT-LEFT-S-OP : PlusWidth(max-args-w,IntWidth(consts(e)[0]))
+ SHIFT-RIGHT-U-OP : MinusWidth(max-args-w,IntWidth(consts(e)[0]))
+ SHIFT-RIGHT-S-OP : MinusWidth(max-args-w,IntWidth(consts(e)[0]))
+ CONVERT-U-OP : PlusWidth(max-args-w,IntWidth(1))
+ CONVERT-S-OP : max-args-w
+ BIT-NOT-OP : max-args-w
+ BIT-AND-OP : max-args-w
+ BIT-OR-OP : max-args-w
+ BIT-XOR-OP : max-args-w
+ BIT-SELECT-OP : IntWidth(1)
+ BITS-SELECT-OP : IntWidth(consts(e)[0] - consts(e)[1])
+ else :
+ switch {op(e) == _} :
+ MUX-UU-OP :
+ add(v,WGeq(width!(args(e)[0]),IntWidth(1)))
+ all-equal(tail(args(e)))
+ MUX-SS-OP :
+ add(v,WGeq(width!(args(e)[0]),IntWidth(1)))
+ all-equal(tail(args(e)))
+ CONCAT-OP :
+ PlusWidth(width!(args(e)[0]),width!(args(e)[1]))
+
+ val w-var = VarWidth(gensym(`w))
+ add(v,WGeq(w-var,w*))
+ match(type(e)) :
+ (t:UIntType) : UIntType(w-var)
+ (t:SIntType) : SIntType(w-var)
+ (t) : error("Shouldn't be here")
- ;println-all(["Looking at " op(e) " with inputs " args(e)])
- switch {op(e) == _} :
- ADD-UU-OP : mp1(args(e))
- ADD-US-OP : mp1(args(e))
- ADD-SU-OP : mp1(args(e))
- ADD-SS-OP : mp1(args(e))
- SUB-UU-OP : mp1(args(e))
- SUB-US-OP : mp1(args(e))
- SUB-SU-OP : mp1(args(e))
- SUB-SS-OP : mp1(args(e))
- MUL-UU-OP : sum(args(e))
- MUL-US-OP : sum(args(e))
- MUL-SU-OP : sum(args(e))
- MUL-SS-OP : sum(args(e))
- ;(p:DIV-UU-OP) :
- ;(p:DIV-US-OP) :
- ;(p:DIV-SU-OP) :
- ;(p:DIV-SS-OP) :
- ;(p:MOD-UU-OP) :
- ;(p:MOD-US-OP) :
- ;(p:MOD-SU-OP) :
- ;(p:MOD-SS-OP) :
- ;(p:QUO-UU-OP) :
- ;(p:QUO-US-OP) :
- ;(p:QUO-SU-OP) :
- ;(p:QUO-SS-OP) :
- ;(p:REM-UU-OP) :
- ;(p:REM-US-OP) :
- ;(p:REM-SU-OP) :
- ;(p:REM-SS-OP) :
- ADD-WRAP-UU-OP : maxw(args(e))
- ADD-WRAP-US-OP : maxw(args(e))
- ADD-WRAP-SU-OP : maxw(args(e))
- ADD-WRAP-SS-OP : maxw(args(e))
- SUB-WRAP-UU-OP : maxw(args(e))
- SUB-WRAP-US-OP : maxw(args(e))
- SUB-WRAP-SU-OP : maxw(args(e))
- SUB-WRAP-SS-OP : maxw(args(e))
- LESS-UU-OP : add-c(IntWidth(1))
- LESS-US-OP : add-c(IntWidth(1))
- LESS-SU-OP : add-c(IntWidth(1))
- LESS-SS-OP : add-c(IntWidth(1))
- LESS-EQ-UU-OP : add-c(IntWidth(1))
- LESS-EQ-US-OP : add-c(IntWidth(1))
- LESS-EQ-SU-OP : add-c(IntWidth(1))
- LESS-EQ-SS-OP : add-c(IntWidth(1))
- GREATER-UU-OP : add-c(IntWidth(1))
- GREATER-US-OP : add-c(IntWidth(1))
- GREATER-SU-OP : add-c(IntWidth(1))
- GREATER-SS-OP : add-c(IntWidth(1))
- GREATER-EQ-UU-OP : add-c(IntWidth(1))
- GREATER-EQ-US-OP : add-c(IntWidth(1))
- GREATER-EQ-SU-OP : add-c(IntWidth(1))
- GREATER-EQ-SS-OP : add-c(IntWidth(1))
- EQUAL-UU-OP : add-c(IntWidth(1))
- EQUAL-SS-OP : add-c(IntWidth(1))
- MUX-UU-OP : cons(args(e))
- MUX-SS-OP : cons(args(e))
- PAD-U-OP : add-c(IntWidth(consts(e)[0]))
- PAD-S-OP : add-c(IntWidth(consts(e)[0]))
- AS-UINT-U-OP : add-c(width!(args(e)[0]))
- AS-UINT-S-OP : add-c(width!(args(e)[0]))
- AS-SINT-U-OP : add-c(width!(args(e)[0]))
- AS-SINT-S-OP : add-c(width!(args(e)[0]))
- SHIFT-LEFT-U-OP : wpc(args(e),consts(e))
- SHIFT-LEFT-S-OP : wpc(args(e),consts(e))
- SHIFT-RIGHT-U-OP : wmc(args(e),consts(e))
- SHIFT-RIGHT-S-OP : wmc(args(e),consts(e))
- CONVERT-U-OP : add-c(PlusWidth(width!(args(e)[0]),IntWidth(1)))
- CONVERT-S-OP : add-c(width!(args(e)[0]))
- BIT-NOT-OP : maxw(args(e))
- BIT-AND-OP : maxw(args(e))
- BIT-OR-OP : maxw(args(e))
- BIT-XOR-OP : maxw(args(e))
- CONCAT-OP : sum(args(e))
- BIT-SELECT-OP : add-c(IntWidth(1))
- BITS-SELECT-OP : add-c(IntWidth(consts(e)[0] - consts(e)[1]))