diff options
| -rw-r--r-- | TODO | 6 | ||||
| -rw-r--r-- | notes/chisel.04.06.15.txt | 2 | ||||
| -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 | ||||
| -rw-r--r-- | test/passes/infer-widths/gcd.fir | 6 | ||||
| -rw-r--r-- | test/passes/infer-widths/simple.fir | 13 | ||||
| -rw-r--r-- | test/passes/jacktest/bundlewire.fir | 25 | ||||
| -rw-r--r-- | test/passes/jacktest/risc.fir | 69 | ||||
| -rw-r--r-- | test/passes/jacktest/testlower.fir | 20 |
11 files changed, 314 insertions, 48 deletions
@@ -1,16 +1,18 @@ TODO Change parser to use <> syntax (and update all tests) (patrick) Think about on-reset, add it + Think about expanding mems, more complicated than first glance! + Think about max(op1,op2) for muxes. Make instances always male, flip the bundles on declaration Talk to palmer/patrick about how writing passes is going to be supported Add asserts, printf to spec Write lowering step for primops Figure out how widths propogate for all updated primops (Adam) Add bit-reduce-and etc to primops (Jonathan) - Write pass to rename identifiers (alpha-transform) (Adam) + //HANDLED IN FRONT END// Write pass to rename identifiers (alpha-transform) (Adam) Add partial bulk connect (Scott, Stephen) Add FIFOs to the IR (Palmer) - Multi-streams for print statements (Jack) + Multi-streams for print statements/asserts (Jack) Consider def female node. (Patrick) Think about supporting generic primops on bundles and vecs (Adam) (wait until front-end more completed) diff --git a/notes/chisel.04.06.15.txt b/notes/chisel.04.06.15.txt index 67f80aa5..5e509ed2 100644 --- a/notes/chisel.04.06.15.txt +++ b/notes/chisel.04.06.15.txt @@ -9,7 +9,7 @@ mem m : { tag : UInt<10> data : UInt<128> }[32] accessor w = m[i] == Low FIRRTL == -mem m : { tag : UInt<10> data : UInt<128> }[32] +mem m : { tag : UInt<10>[32] data : UInt<128>[32] } wire w#tag : UInt<10> wire w#data : UInt<128> WritePort(m.tag,i,en*) := w#tag 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) diff --git a/test/passes/infer-widths/gcd.fir b/test/passes/infer-widths/gcd.fir index 3e1a02f5..2adba2b8 100644 --- a/test/passes/infer-widths/gcd.fir +++ b/test/passes/infer-widths/gcd.fir @@ -6,7 +6,7 @@ circuit top : input x : UInt input y : UInt output q : UInt - q := sub-wrap(x, y) + q := sub-wrap-uu(x, y) module gcd : input a : UInt(16) input b : UInt(16) @@ -17,7 +17,7 @@ circuit top : reg y : UInt x.init := UInt(0) y.init := UInt(42) - when gt(x, y) : + when gt-uu(x, y) : inst s of subtracter s.x := x s.y := y @@ -30,7 +30,7 @@ circuit top : when e : x := a y := b - v := equal(v, UInt(0)) + v := equal-uu(v, UInt(0)) z := x module top : input a : UInt(16) diff --git a/test/passes/infer-widths/simple.fir b/test/passes/infer-widths/simple.fir new file mode 100644 index 00000000..f98d98da --- /dev/null +++ b/test/passes/infer-widths/simple.fir @@ -0,0 +1,13 @@ +; RUN: firrtl %s abcefghipjk cT | tee %s.out | FileCheck %s + +;CHECK: Infer Widths +circuit top : + module top : + wire e : UInt + wire x : UInt + reg y : UInt + y := mux-uu(e, UInt(1), equal-uu(gt-uu(x, x), UInt(0))) + + +; CHECK: Finished Infer Widths + diff --git a/test/passes/jacktest/bundlewire.fir b/test/passes/jacktest/bundlewire.fir index 0356597e..18e246a9 100644 --- a/test/passes/jacktest/bundlewire.fir +++ b/test/passes/jacktest/bundlewire.fir @@ -2,19 +2,16 @@ ; CHECK: Expand Whens -circuit BundleWire : - module BundleWire : - input in : { y : UInt(32), x : UInt(32) } - output outs : { y : UInt(32), x : UInt(32) }[4] - - wire coords : { y : UInt(32), x : UInt(32) }[4] - coords.0 := in - outs.0 := coords.0 - coords.1 := in - outs.1 := coords.1 - coords.2 := in - outs.2 := coords.2 - coords.3 := in - outs.3 := coords.3 +circuit TestLower : + module Inst : + input x : UInt + output y : UInt + module TestLower : + mem m : {data : { w : UInt , x : UInt } tag : { y : UInt, z : UInt }}[8] + wire index : UInt + accessor r = m[index] + + inst i of Inst + i.x := r ; CHECK: Finished Expand Whens diff --git a/test/passes/jacktest/risc.fir b/test/passes/jacktest/risc.fir new file mode 100644 index 00000000..d8197112 --- /dev/null +++ b/test/passes/jacktest/risc.fir @@ -0,0 +1,69 @@ +; RUN: firrtl %s abcefghipj c | tee %s.out | FileCheck %s +; CHECK: Expand Whens +circuit Risc : + module Risc : + output out : UInt(32) + output valid : UInt(1) + input boot : UInt(1) + input isWr : UInt(1) + input wrAddr : UInt(8) + input wrData : UInt(32) + + mem file : UInt(32)[256] + mem code : UInt(32)[256] + node T_51 = UInt(0, 8) + reg pc : UInt(8) + pc.init := T_51 + node add_op = UInt(0, 1) + node imm_op = UInt(1, 1) + accessor inst = code[pc] + node op = bits(inst, 31, 24) + node rci = bits(inst, 23, 16) + node rai = bits(inst, 15, 8) + node rbi = bits(inst, 7, 0) + node T_52 = UInt(0, 1) + node T_53 = equal(rai, T_52) + node T_54 = UInt(0, 1) + accessor T_55 = file[rai] + node ra = mux(T_53, T_54, T_55) + node T_56 = UInt(0, 1) + node T_57 = equal(rbi, T_56) + node T_58 = UInt(0, 1) + accessor T_59 = file[rbi] + node rb = mux(T_57, T_58, T_59) + wire rc : UInt(32) + node T_60 = UInt(0, 1) + valid := T_60 + node T_61 = UInt(0, 1) + out := T_61 + node T_62 = UInt(0, 1) + rc := T_62 + when isWr : + accessor T_63 = code[wrAddr] + T_63 := wrData + else : when boot : + node T_64 = UInt(0, 1) + pc := T_64 + else : + node T_65 = equal(add_op, op) + when T_65 : + node T_66 = add-wrap(ra, rb) + rc := T_66 + node T_67 = equal(imm_op, op) + when T_67 : + node T_68 = shl(rai, 8) + node T_69 = bit-or(T_68, rbi) + rc := T_69 + out := rc + node T_70 = UInt(255, 8) + node T_71 = equal(rci, T_70) + when T_71 : + node T_72 = UInt(1, 1) + valid := T_72 + else : + accessor T_73 = file[rci] + T_73 := rc + node T_74 = UInt(1, 1) + node T_75 = add-wrap(pc, T_74) + pc := T_75 +; CHECK: Finished Expand Whens diff --git a/test/passes/jacktest/testlower.fir b/test/passes/jacktest/testlower.fir new file mode 100644 index 00000000..0356597e --- /dev/null +++ b/test/passes/jacktest/testlower.fir @@ -0,0 +1,20 @@ +; RUN: firrtl %s abcefghipj cg | tee %s.out | FileCheck %s + +; CHECK: Expand Whens + +circuit BundleWire : + module BundleWire : + input in : { y : UInt(32), x : UInt(32) } + output outs : { y : UInt(32), x : UInt(32) }[4] + + wire coords : { y : UInt(32), x : UInt(32) }[4] + coords.0 := in + outs.0 := coords.0 + coords.1 := in + outs.1 := coords.1 + coords.2 := in + outs.2 := coords.2 + coords.3 := in + outs.3 := coords.3 + +; CHECK: Finished Expand Whens |
