diff options
| author | azidar | 2015-04-09 16:57:00 -0700 |
|---|---|---|
| committer | azidar | 2015-04-09 16:57:00 -0700 |
| commit | a604e0789a85d8b3c5d6def2f9860047f479b68a (patch) | |
| tree | ff2890d273f30155c52b610824a3ea632f2c12c6 /src | |
| parent | 16b9cb55c7d3e546af7eee3528079c9ac9bb530b (diff) | |
Added more 'fake' tests. infer-widths now collects constraints
Diffstat (limited to 'src')
| -rw-r--r-- | src/main/stanza/firrtl-ir.stanza | 14 | ||||
| -rw-r--r-- | src/main/stanza/ir-parser.stanza | 2 | ||||
| -rw-r--r-- | src/main/stanza/ir-utils.stanza | 1 | ||||
| -rw-r--r-- | src/main/stanza/passes.stanza | 204 |
4 files changed, 193 insertions, 28 deletions
diff --git a/src/main/stanza/firrtl-ir.stanza b/src/main/stanza/firrtl-ir.stanza index 977c8ca1..f10dba0c 100644 --- a/src/main/stanza/firrtl-ir.stanza +++ b/src/main/stanza/firrtl-ir.stanza @@ -153,19 +153,19 @@ public defstruct Register <: Expression : enable: Expression public definterface Stmt -public defstruct DefWire <: Stmt : +public defstruct DefWire <: Stmt : ;LOW name: Symbol type: Type public defstruct DefRegister <: Stmt : name: Symbol type: Type -public defstruct DefInstance <: Stmt : +public defstruct DefInstance <: Stmt : ;LOW name: Symbol module: Expression -public defstruct DefMemory <: Stmt : +public defstruct DefMemory <: Stmt : ;LOW name: Symbol type: VectorType -public defstruct DefNode <: Stmt : +public defstruct DefNode <: Stmt : ;LOW name: Symbol value: Expression public defstruct DefAccessor <: Stmt : @@ -176,12 +176,12 @@ public defstruct Conditionally <: Stmt : pred: Expression conseq: Stmt alt: Stmt -public defstruct Begin <: Stmt : +public defstruct Begin <: Stmt : ;LOW body: List<Stmt> -public defstruct Connect <: Stmt : +public defstruct Connect <: Stmt : ;LOW loc: Expression exp: Expression -public defstruct EmptyStmt <: Stmt +public defstruct EmptyStmt <: Stmt ;LOW public definterface Type public defstruct UIntType <: Type : diff --git a/src/main/stanza/ir-parser.stanza b/src/main/stanza/ir-parser.stanza index 8f0cc8e3..87458185 100644 --- a/src/main/stanza/ir-parser.stanza +++ b/src/main/stanza/ir-parser.stanza @@ -259,6 +259,8 @@ rd.defsyntax firrtl : WritePort(mem, index, UnknownType(), enable) (ReadPort (@do ?mem:#exp ?index:#exp ?enable:#exp)) : ReadPort(mem, index, UnknownType(), enable) + (Register (@do ?value:#exp ?enable:#exp)) : + Register(UnknownType(),value,enable) (?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 5e03ab54..1f33547e 100644 --- a/src/main/stanza/ir-utils.stanza +++ b/src/main/stanza/ir-utils.stanza @@ -235,6 +235,7 @@ defmethod map (f: Expression -> Expression, e:Expression) -> Expression : (e:DoPrim) : DoPrim(op(e), map(f, args(e)), consts(e), type(e)) (e:ReadPort) : ReadPort(f(mem(e)), f(index(e)), type(e), enable(e)) (e:WritePort) : WritePort(f(mem(e)), f(index(e)), type(e), enable(e)) + (e:Register) : Register(type(e),f(value(e)),f(enable(e))) (e) : e public defmulti map<?T> (f: Expression -> Expression, c:?T&Stmt) -> T diff --git a/src/main/stanza/passes.stanza b/src/main/stanza/passes.stanza index 482765c3..313191c8 100644 --- a/src/main/stanza/passes.stanza +++ b/src/main/stanza/passes.stanza @@ -240,6 +240,7 @@ defmethod map (f: Expression -> Expression, e: WSubfield) : WSubfield(f(exp(e)), name(e), type(e), gender(e)) defmethod map (f: Expression -> Expression, e: WIndex) : WIndex(f(exp(e)), value(e), type(e), gender(e)) + defmethod map (f: Expression -> Expression, c:WDefAccessor) : WDefAccessor(name(c), f(source(c)), f(index(c)), gender(c)) defmethod map (f: Expression -> Expression, c:ConnectToIndexed) : @@ -303,7 +304,7 @@ defn resolve-kinds (c:Circuit) : defn find-stmt (s:Stmt) -> Stmt : match(s) : (s:DefWire) : kinds[name(s)] = NodeKind() - ;TODO add DefNode + (s:DefNode) : kinds[name(s)] = NodeKind() (s:DefRegister) : kinds[name(s)] = RegKind() (s:DefInstance) : kinds[name(s)] = InstanceKind() (s:DefMemory) : kinds[name(s)] = MemKind() @@ -631,8 +632,7 @@ defn resolve-genders (c:Circuit) : get-gender(name(s),BI-GENDER) s (s:DefNode) : - get-gender(name(s),MALE) - s + DefNode(name(s),resolve-expr(value(s),get-gender(name(s),MALE))) (s:DefInstance) : get-gender(name(s),FEMALE) DefInstance(name(s),resolve-expr(module(s),FEMALE)) @@ -674,9 +674,11 @@ defn resolve-genders (c:Circuit) : (e) : map(resolve-expr{_,MALE},e) var module* = resolve-iter(m) + println(genders) while not done? : done? = true module* = resolve-iter(m) + println(genders) module* defn resolve-genders (m:Module, c:Circuit) -> Module : @@ -1420,33 +1422,191 @@ defn expand-whens (c:Circuit) -> Circuit : ; Then, you solve width constraints. ; Finally, you replace all width variables with the solved ; widths. +; Low FIRRTL Pass. defstruct VarWidth <: Width : name: Symbol +defstruct PlusWidth <: Width : + arg1 : Width + arg2 : Width +defstruct MinusWidth <: Width : + arg1 : Width + arg2 : Width +defstruct MaxWidth <: Width : + arg1 : Width + arg2 : Width defmethod print (o:OutputStream, w:VarWidth) : print(o,name(w)) +defmethod print (o:OutputStream, w:MaxWidth) : + print-all(o,["max(" arg1(w) "," arg2(w) ")"]) +defmethod print (o:OutputStream, w:PlusWidth) : + print-all(o,[ arg1(w) " + " arg2(w)]) +defmethod print (o:OutputStream, w:MinusWidth) : + print-all(o,[ arg1(w) " - " arg2(w)]) + +definterface Constraint +defstruct WGeq <: Constraint : + loc : Width + exp : Width +defstruct WEq <: Constraint : + loc : Width + exp : Width +defmethod print (o:OutputStream, c:WGeq) : + print-all(o,[ loc(c) " >= " exp(c)]) +defmethod print (o:OutputStream, c:WEq) : + print-all(o,[ loc(c) " = " exp(c)]) + ;defn remove-var-widths (c:Circuit) -> Circuit : -;defn solve-constraints (l:List<WCon>) -> HashTable<Symbol,Int> : +;defn solve-constraints (l:List<WGeq>) -> HashTable<Symbol,Int> : -;defn gen-constraints (m:Module) -> List<WCon> : -; val v = Vector<WCon>() -; val h = HashTable<Symbol,Width>(symbol-hash) -; -; -; defn get-width (e:Expression) -> Width : -; match(e) : -; (e:WRef) : -; val w = get-width(type(e)) -; add(v,WGeq(w,h[name(e)])) -; add(v,WGeq(h[name(e)],w)) -; w -; (e:WSubfield) : ;assumes only subfields are instances -; add(v,WGeq(w, -; defn gen-constraints (s:Stmt) -> Stmt : -; match(map(gen-constraints,s)) : +defn width! (t:Type) -> Width : + match(t) : + (t:UIntType) : width(t) + (t:SIntType) : width(t) + (t) : error("No width!") +defn prim-width (e:DoPrim,v:Vector<WGeq>) -> Width : + defn e-width (e:Expression) -> Width : width!(type(e)) + defn wpc (l:List<Expression>,c:List<Int>) : PlusWidth(e-width(l[0]),IntWidth(c[0])) + defn wmc (l:List<Expression>,c:List<Int>) : MinusWidth(e-width(l[0]),IntWidth(c[0])) + defn maxw (l:List<Expression>) : MaxWidth(e-width(l[0]),e-width(l[1])) + defn mp1 (l:List<Expression>) : PlusWidth(MaxWidth(e-width(l[0]),e-width(l[1])),IntWidth(1)) + defn sum (l:List<Expression>) : PlusWidth(e-width(l[0]),e-width(l[1])) + 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 : 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) + MUX-UU-OP : maxw(args(e)) + MUX-SS-OP : maxw(args(e)) + PAD-U-OP : IntWidth(consts(e)[0]) + PAD-S-OP : IntWidth(consts(e)[0]) + AS-UINT-U-OP : e-width(args(e)[0]) + AS-UINT-S-OP : e-width(args(e)[0]) + AS-SINT-U-OP : e-width(args(e)[0]) + AS-SINT-S-OP : e-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 : PlusWidth(e-width(args(e)[0]),IntWidth(1)) + CONVERT-S-OP : e-width(args(e)[0]) + 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 : IntWidth(1) + BITS-SELECT-OP : IntWidth(consts(e)[0] - consts(e)[1]) + +defn gen-constraints (c:Circuit, m:Module) -> List<WGeq> : + val v = Vector<WGeq>() + val h = HashTable<Symbol,Type>(symbol-hash) + + defn get-width (e:Expression) -> Width : + match(e) : + (e:WRef) : + val [wdec wref] = match(kind(e)) : + (k:InstanceKind) : error("Shouldn't be here") + (k:MemKind) : + [width! $ type $ (h[name(e)] as VectorType), + width! $ type $ (type(e) as VectorType)] + (k) : + [width! $ h[name(e)], + width! $ type(e)] + add(v,WGeq(wdec,wref)) + add(v,WGeq(wref,wdec)) + wdec + (e:WSubfield) : ;assumes only subfields are instances + val wdec = width! $ bundle-field-type(h[name(exp(e) as WRef)],name(e)) + val wref = width! $ bundle-field-type(type(exp(e)),name(e)) + add(v,WGeq(wdec,wref)) + add(v,WGeq(wref,wdec)) + wdec + (e:WIndex) : error("Shouldn't be here") + (e:UIntValue) : width(e) + (e:SIntValue) : width(e) + (e:DoPrim) : prim-width(e,v) + (e:ReadPort|WritePort) : + add(v,WGeq(get-width(enable(e)),IntWidth(1))) + add(v,WGeq(IntWidth(1),get-width(enable(e)))) + get-width(mem(e)) + (e:Register) : + add(v,WGeq(get-width(enable(e)),IntWidth(1))) + add(v,WGeq(IntWidth(1),get-width(enable(e)))) + val w = width!(type(e)) + add(v,WGeq(get-width(value(e)),w)) + add(v,WGeq(w,get-width(value(e)))) + w + defn gen-constraints (s:Stmt) -> Stmt : + match(map(gen-constraints,s)) : + (s:DefWire) : h[name(s)] = type(s) + (s:DefInstance) : h[name(s)] = h[name(module(s) as WRef)] + (s:DefMemory) : h[name(s)] = type(s) + (s:DefNode) : h[name(s)] = type(value(s)) + (s:Connect) : + add(v,WGeq(get-width(loc(s)),get-width(exp(s)))) + add(v,WGeq(get-width(exp(s)),get-width(loc(s)))) + (s) : "" + s + + for m in modules(c) do : + h[name(m)] = BundleType(map(to-field,ports(m))) + for p in ports(m) do : + h[name(p)] = type(p) + gen-constraints(body(m)) + to-list(v) defn remove-unknown-widths (c:Circuit) -> Circuit : @@ -1476,8 +1636,10 @@ defn remove-unknown-widths (c:Circuit) -> Circuit : defn infer-widths (c:Circuit) -> Circuit : val c* = remove-unknown-widths(c) + for m in modules(c*) do : + val l = gen-constraints(c*,m) + for x in l do : println(x) c* - ;val l = gen-constraints(c*) ;val h = solve-constraints(l) ;replace-var-widths(c*,h) |
