diff options
| author | azidar | 2015-04-15 15:44:56 -0700 |
|---|---|---|
| committer | azidar | 2015-04-15 15:44:56 -0700 |
| commit | 98c721d17ab8352c618c7917b8188e14959f2bad (patch) | |
| tree | f0e2d291d53b6b1fb3313b6624c91e4afd66f377 /src | |
| parent | 530e324acccdff7101bda4109bdf54185f476c92 (diff) | |
Finished flo backend. Restructured todo list
Diffstat (limited to 'src')
| -rw-r--r-- | src/main/stanza/firrtl-ir.stanza | 4 | ||||
| -rw-r--r-- | src/main/stanza/ir-parser.stanza | 1 | ||||
| -rw-r--r-- | src/main/stanza/passes.stanza | 235 |
3 files changed, 221 insertions, 19 deletions
diff --git a/src/main/stanza/firrtl-ir.stanza b/src/main/stanza/firrtl-ir.stanza index f10dba0c..358ad9aa 100644 --- a/src/main/stanza/firrtl-ir.stanza +++ b/src/main/stanza/firrtl-ir.stanza @@ -81,6 +81,9 @@ public val GREATER-EQ-UU-OP = new PrimOp public val GREATER-EQ-US-OP = new PrimOp public val GREATER-EQ-SU-OP = new PrimOp public val GREATER-EQ-SS-OP = new PrimOp +public val NEQUAL-OP = new PrimOp +public val NEQUAL-UU-OP = new PrimOp +public val NEQUAL-SS-OP = new PrimOp public val EQUAL-OP = new PrimOp public val EQUAL-UU-OP = new PrimOp public val EQUAL-SS-OP = new PrimOp @@ -105,6 +108,7 @@ public val SHIFT-RIGHT-S-OP = new PrimOp public val CONVERT-OP = new PrimOp public val CONVERT-U-OP = new PrimOp public val CONVERT-S-OP = new PrimOp +public val BIT-NOT-OP = new PrimOp public val BIT-AND-OP = new PrimOp public val BIT-OR-OP = new PrimOp public val BIT-XOR-OP = new PrimOp diff --git a/src/main/stanza/ir-parser.stanza b/src/main/stanza/ir-parser.stanza index 87458185..065aec34 100644 --- a/src/main/stanza/ir-parser.stanza +++ b/src/main/stanza/ir-parser.stanza @@ -239,6 +239,7 @@ rd.defsyntax firrtl : operators[`convert] = CONVERT-OP operators[`convert-u] = CONVERT-U-OP operators[`convert-s] = CONVERT-S-OP + operators[`bit-not] = BIT-NOT-OP operators[`bit-and] = BIT-AND-OP operators[`bit-or] = BIT-OR-OP operators[`bit-xor] = BIT-XOR-OP diff --git a/src/main/stanza/passes.stanza b/src/main/stanza/passes.stanza index b8059778..63c504a9 100644 --- a/src/main/stanza/passes.stanza +++ b/src/main/stanza/passes.stanza @@ -189,7 +189,6 @@ defn any-debug? (e:Expression|Stmt|Type|Port|Field) : (hasGender(e) and PRINT-GENDERS) or (hasType(e) and PRINT-TYPES) or (hasWidth(e) and PRINT-WIDTHS) or - (hasType(e) and PRINT-WIDTHS) or (hasKind(e) and PRINT-KINDS) defmethod print-debug (o:OutputStream, e:Expression|Stmt|Type|Port|Field) : @@ -492,6 +491,7 @@ defn get-primop-rettype (e:DoPrim) -> Type : CONVERT-OP : s() CONVERT-U-OP : s() CONVERT-S-OP : s() + BIT-NOT-OP : u() BIT-AND-OP : u() BIT-OR-OP : u() BIT-XOR-OP : u() @@ -1730,6 +1730,7 @@ defn gen-constraints (m:Module, h:HashTable<Symbol,Type>, v:Vector<WGeq>) -> Mod 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)) @@ -1762,11 +1763,17 @@ defn gen-constraints (m:Module, h:HashTable<Symbol,Type>, v:Vector<WGeq>) -> Mod (e:Register) : Register(type(value(e)),value(e),enable(e)) (e:UIntValue) : match(width(e)) : - (w:UnknownWidth) : UIntValue(value(e),VarWidth(gensym(`w))) + (w:UnknownWidth) : + val w* = VarWidth(gensym(`w)) + add(v,WGeq(w*,IntWidth(ceil-log2(value(e))))) + UIntValue(value(e),w*) (w) : e (e:SIntValue) : match(width(e)) : - (w:UnknownWidth) : SIntValue(value(e),VarWidth(gensym(`w))) + (w:UnknownWidth) : + val w* = VarWidth(gensym(`w)) + add(v,WGeq(w*,IntWidth(1 + ceil-log2(abs(value(e)))))) + SIntValue(value(e),w*) (w) : e (e) : e @@ -1868,21 +1875,29 @@ defn inline-instances (c:Circuit) : val h = HashTable<Symbol,Module>(symbol-hash) val h-s = HashTable<Symbol,Stmt>(symbol-hash) defn inline-inst (s:Stmt) -> Stmt : - match(map(inline-inst,s)) : - (s:DefInstance) : - val n = name(module(s) as WRef) - val m = h[n] - val body* = - if key?(h-s,n) : h-s[n] - else : - val v = Vector<Stmt>() - for p in ports(m) do : - add(v,DefWire(name(p),type(p))) - add(v,inline-inst(body(m))) - Begin(to-list(v)) - h-s[n] = body* - rename-s(body*,name(s)) - (s) : s + match(map(inline-inst,s)) : + (s:DefInstance) : + val n = name(module(s) as WRef) + val m = h[n] + val body* = + if key?(h-s,n) : h-s[n] + else : + val v = Vector<Stmt>() + for p in ports(m) do : + add(v,DefWire(name(p),type(p))) + add(v,inline-inst(body(m))) + Begin(to-list(v)) + h-s[n] = body* + rename-s(body*,name(s)) + (s) : map(inline-inst-e,s) + defn inline-inst-e (e:Expression) -> Expression : + match(map(inline-inst-e,e)) : + (e:WSubfield) : + match(kind(exp(e) as WRef)) : + (k:InstanceKind) : + WRef(symbol-join([name(exp(e) as WRef) "$" name(e)]),type(e),k,gender(e)) + (k:MemKind) : e + (e) : e defn rename (ref:Symbol,n:Symbol) -> Symbol : symbol-join([n "$" ref]) defn rename-e (e:Expression,n:Symbol) -> Expression : match(map(rename-e{_,n},e)) : @@ -1955,6 +1970,188 @@ defn to-real-ir (c:Circuit) : for m in modules(c) map : Module(name(m), ports(m), to-stmt(body(m))) +;============= FLO PRINTER ====================================== +; Emit + +defn flo-op-name (op:PrimOp) -> String : + switch {op == _ } : + ;NEG-OP : "neg" + ;NEG-OP : "neg" + ;NEG-OP : "neg" + ;NEG-OP : "neg" + ADD-UU-OP : "add" + ADD-US-OP : "add" + ADD-SU-OP : "add" + ADD-SS-OP : "add" + ADD-WRAP-UU-OP : "add" + ADD-WRAP-US-OP : "add" + ADD-WRAP-SU-OP : "add" + ADD-WRAP-SS-OP : "add" + SUB-UU-OP : "sub" + SUB-US-OP : "sub" + SUB-SU-OP : "sub" + SUB-SS-OP : "sub" + SUB-WRAP-UU-OP : "sub" + SUB-WRAP-US-OP : "sub" + SUB-WRAP-SU-OP : "sub" + SUB-WRAP-SS-OP : "sub" + MUL-UU-OP : "mul" ;; todo: signed version + MUL-US-OP : "mul" ;; todo: signed version + MUL-SU-OP : "mul" ;; todo: signed version + MUL-SS-OP : "mul" ;; todo: signed version + DIV-UU-OP : "div" ;; todo: signed version + DIV-US-OP : "div" ;; todo: signed version + DIV-SU-OP : "div" ;; todo: signed version + DIV-SS-OP : "div" ;; todo: signed version + MOD-UU-OP : "mod" ;; todo: signed version + MOD-US-OP : "mod" ;; todo: signed version + MOD-SU-OP : "mod" ;; todo: signed version + MOD-SS-OP : "mod" ;; todo: signed version + LESS-UU-OP : "lt" ;; todo: signed version + LESS-US-OP : "lt" ;; todo: signed version + LESS-SU-OP : "lt" ;; todo: signed version + LESS-SS-OP : "lt" ;; todo: signed version + LESS-EQ-UU-OP : "lte" ;; todo: swap args + LESS-EQ-US-OP : "lte" ;; todo: swap args + LESS-EQ-SU-OP : "lte" ;; todo: swap args + LESS-EQ-SS-OP : "lte" ;; todo: swap args + GREATER-UU-OP : "lte" ;; todo: swap args BROKEN + GREATER-US-OP : "lte" ;; todo: swap args BROKEN + GREATER-SU-OP : "lte" ;; todo: swap args BROKEN + GREATER-SS-OP : "lte" ;; todo: swap args BROKEN + GREATER-EQ-UU-OP : "lt" ;; todo: signed version + GREATER-EQ-US-OP : "lt" ;; todo: signed version + GREATER-EQ-SU-OP : "lt" ;; todo: signed version + GREATER-EQ-SS-OP : "lt" ;; todo: signed version + NEQUAL-UU-OP : "neq" + NEQUAL-SS-OP : "neq" + EQUAL-UU-OP : "eq" + EQUAL-SS-OP : "eq" + MUX-UU-OP : "mux" + MUX-SS-OP : "mux" + PAD-U-OP : "rsh" ;; todo: signed version + PAD-S-OP : "rsh" ;; todo: signed version + ;AS-UINT-U-OP : + ;AS-UINT-S-OP : + ;AS-SINT-U-OP : + ;AS-SINT-S-OP : + SHIFT-LEFT-U-OP : "lsh" ;; todo: signed version + SHIFT-LEFT-S-OP : "lsh" ;; todo: signed version + SHIFT-RIGHT-U-OP : "rsh" + SHIFT-RIGHT-S-OP : "rsh" + ;CONVERT-U-OP : + ;CONVERT-S-OP : + BIT-AND-OP : "and" + BIT-NOT-OP : "not" + BIT-OR-OP : "or" + BIT-XOR-OP : "xor" + CONCAT-OP : "cat" + BIT-SELECT-OP : "rsh" + BITS-SELECT-OP : "rsh" + else : error $ string-join $ ["Unable to print Primop: " op] + +defn sane-width (wd:Width) -> Int : + match(wd) : + (w:IntWidth) : max(1, width(w)) + (w) : error("Unknown width") + +defn prim-width (type:Type) -> Int : + match(type) : + (t:UIntType) : sane-width(width(t)) + (t:SIntType) : sane-width(width(t)) + (t) : error("Bad prim width type") + +defn sizeof (in: Int) -> Int : + ;; if in == 1: 1 else: to-int(ceil(log(in)/log(2))) + max(1, ceil-log2(in)) + +defn emit-all (o:OutputStream, es:Streamable, top:Symbol) : + for e in es do : + match(e) : + (ex:Expression) : emit!(o,e,top) + (ex:String) : print(o, ex) + (ex:Symbol) : print(o, ex) + ;; (ex:Int) : print-all(o, [ex "'" sizeof(ex)]) + (ex:Int) : print(o, ex) + (ex) : print(o, ex) + +defn emit! (o:OutputStream, e:Expression,top:Symbol) : + defn cmp-op? (op: PrimOp) -> True|False : + contains?([EQUAL-OP, NEQUAL-OP, GREATER-OP, LESS-EQ-OP, LESS-OP, GREATER-EQ-OP], op) + match(e) : + (e:Ref) : emit-all(o,[top "::" name(e)], top) + (e:UIntValue) : emit-all(o,[value(e) "'" sane-width(width(e))], top) + (e:SIntValue) : emit-all(o,[value(e) "'" sane-width(width(e))], top) + (e:Subfield) : emit-all(o,[exp(e) "/" name(e)], top) + (e:Index) : emit-all(o,[exp(e) "/" value(e)], top) + (e:Register) : + emit-all(o,["reg'" prim-width(type(e)) " " enable(e) " " value(e)], top) + (e:ReadPort) : + emit-all(o,["rd'" prim-width(type(e)) " " enable(e) " " mem(e) " " index(e)], top) + (e:DoPrim) : + if cmp-op?(op(e)) : + emit-all(o, [flo-op-name(op(e)) "'" prim-width(type(args(e)[0]))], top) + if op(e) == GREATER-OP or op(e) == LESS-EQ-OP : + emit-all(o, [" " args(e)[1] " " args(e)[0]], top) + else : + emit-all(o, [" " args(e)[0] " " args(e)[1]], top) + else if op(e) == BIT-SELECT-OP : + emit-all(o, [flo-op-name(op(e)) "'1 " args(e)[0] " " consts(e)[0]], top) + else if op(e) == BITS-SELECT-OP : + val w = consts(e)[0] - consts(e)[1] + 1 + emit-all(o, [flo-op-name(op(e)) "'" w " " args(e)[0] " " consts(e)[1]], top) + ;; else if op(e) == CONCAT-OP : + ;; val w = consts(e)[0] - consts(e)[1] + 1 + ;; emit-all(o, [flo-op-name(op(e)) "'" w " " args(e)[0] " " consts(e)[1]], top) + else : + emit-all(o, [flo-op-name(op(e)) "'" prim-width(type(e))], top) + if op(e) == PAD-OP : + emit-all(o, [" " args(e)[0] " 0"], top) + else : + for arg in args(e) do : + print(o, " ") + emit!(o, arg, top) + for const in consts(e) do : + print(o, " ") + print(o, const) + (e) : print-all(o, ["EMIT(" e ")"]) + ;(e) : emit-all(o, ["mov'" prim-width(type(e)) " " e], top) + +defn emit-s (o:OutputStream, s:Stmt, v:List<Symbol>, top:Symbol) : + match(s) : + (s:DefWire) : "" + (s:DefInstance) : error("Shouldn't be here") + (s:DefMemory) : + val vtype = type(s) as VectorType + emit-all(o, [top "::" name(s) " = mem'" prim-width(type(vtype)) " " size(vtype) "\n"], top) + (s:DefNode) : emit-all(o, [top "::" name(s) " = " value(s) "\n"], top) + (s:Begin) : do(emit-s{o, _, v, top}, body(s)) + (s:Connect) : + if loc(s) typeof WritePort : + val e = loc(s) as WritePort + val name = gensym("T") + emit-all(o, [top "::" name " = wr'" prim-width(type(e)) " " enable(e) " " top "::" mem(e) " " index(e) " " exp(s) "\n"], top) + else : + val n = name(loc(s) as Ref) + if contains?(v,n) : + emit-all(o, [n " = out'" prim-width(type(loc(s))) " " exp(s) "\n"], top) + else : + emit-all(o, [top "::" n " = " exp(s) "\n"], top) + (s) : s + +defn emit-module (o:OutputStream, m:Module) : + val v = Vector<Symbol>() + for port in ports(m) do : + if name(port) ==`reset : + emit-all(o, [name(m) "::" name(port) " = rst'1\n"], name(m)) + else : switch {_ == direction(port)} : + INPUT : print-all(o, [name(m) "::" name(port) " = " "in'" prim-width(type(port)) "\n"]) + OUTPUT : add(v,name(port)) + emit-s(o, body(m), to-list(v), name(m)) + +public defn emit-flo (o:OutputStream, c:Circuit) : + emit-module(o, modules(c)[0]) + c ;============= DRIVER ====================================== public defn run-passes (c: Circuit, p: List<Char>) : @@ -1984,7 +2181,7 @@ public defn run-passes (c: Circuit, p: List<Char>) : if contains(p,'l') : do-stage("Inline Instances", inline-instances) if contains(p,'m') : do-stage("Split Expressions", split-exp) if contains(p,'n') : do-stage("Real IR", to-real-ir) - + if contains(p,'o') : do-stage("To Flo", emit-flo{STANDARD-OUTPUT,_}) println("Done!") |
