diff options
Diffstat (limited to 'src/main/stanza/flo.stanza')
| -rw-r--r-- | src/main/stanza/flo.stanza | 228 |
1 files changed, 0 insertions, 228 deletions
diff --git a/src/main/stanza/flo.stanza b/src/main/stanza/flo.stanza deleted file mode 100644 index ad04bb23..00000000 --- a/src/main/stanza/flo.stanza +++ /dev/null @@ -1,228 +0,0 @@ -;Copyright (c) 2014 - 2016 The Regents of the University of -;California (Regents). All Rights Reserved. Redistribution and use in -;source and binary forms, with or without modification, are permitted -;provided that the following conditions are met: -; * Redistributions of source code must retain the above -; copyright notice, this list of conditions and the following -; two paragraphs of disclaimer. -; * Redistributions in binary form must reproduce the above -; copyright notice, this list of conditions and the following -; two paragraphs of disclaimer in the documentation and/or other materials -; provided with the distribution. -; * Neither the name of the Regents nor the names of its contributors -; may be used to endorse or promote products derived from this -; software without specific prior written permission. -;IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, -;SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, -;ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF -;REGENTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -;REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT -;LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -;A PARTICULAR PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF -;ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION -;TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR -;MODIFICATIONS. -defpackage firrtl/flo : - import core - import verse - import firrtl/ir-utils - import firrtl/ir2 - import firrtl/passes - import bigint2 - -;============= Flo Backend ================ - -public defstruct Flo <: Pass : - with-output: (() -> False) -> False -public defmethod pass (b:Flo) -> (Circuit -> Circuit) : emit-flo{with-output(b),_} -public defmethod name (b:Flo) -> String : "To Flo" - -definterface FloKind -defstruct FRegKind <: FloKind -defstruct FWritePortKind <: FloKind : - mem: Expression - index: Expression -defstruct FOutputPortKind <: FloKind - -defn is-sint? (arg:Expression) -> True|False : type(arg) typeof SIntType -defn type (s:DefAccessor) -> Type : type(type(source(s)) as VectorType) - -defn flo-op-name (op:PrimOp, args:List<Expression>) -> String : - switch {op == _ } : - ADD-OP : "add" - ADD-WRAP-OP : "add" - SUB-OP : "sub" - SUB-WRAP-OP : "sub" - MUL-OP : "mul" ;; todo: signed version - DIV-OP : "div" ;; todo: signed version - REM-OP : "mod" ;; todo: signed version - QUO-OP : "div" ;; todo: signed version - REM-OP : "mod" ;; todo: signed version - LESS-OP : "lt" ;; todo: signed version - LESS-EQ-OP : "lte" ;; todo: swap args - GREATER-OP : "lt" ;; todo: swap args - GREATER-EQ-OP : "lte" ;; todo: signed version - NEQUIV-OP : "neq" - EQUIV-OP : "eq" - NEQUAL-OP : "neq" - EQUAL-OP : "eq" - MUX-OP : "mux" - NEG-OP : "neg" - AS-UINT-OP : "mov" - AS-SINT-OP : "mov" - SHIFT-LEFT-OP : "lsh" - SHIFT-RIGHT-OP : if is-sint?(args[0]): "arsh" else: "rsh" - DYN-SHIFT-LEFT-OP : "lsh" - DYN-SHIFT-RIGHT-OP : if is-sint?(args[0]): "arsh" else: "rsh" - PAD-OP : if is-sint?(args[0]): "arsh" else: "rsh" - CONVERT-OP : if is-sint?(args[0]): "arsh" else: "rsh" - 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" - BIT-XOR-REDUCE-OP : "xorr" - else : - error $ string-join $ ["Unable to print Primop: " op] - -defn sane-width (wd:Width) -> Int|Long : - match(wd) : - (w:LongWidth) : max(to-long(1), width(w)) - (w) : error(string-join(["Unknown width: " w])) - -defn prim-width (type:Type) -> Int|Long : - match(type) : - (t:UIntType) : sane-width(width(t)) - (t:SIntType) : sane-width(width(t)) - (t:ClockType) : 1 - (t) : error("Bad prim width type") - -defn emit-all (es:Streamable, top:Symbol) : - for e in es do : - match(e) : - (ex:Expression) : emit!(ex,top) - (ex:String) : print(ex) - (ex:Symbol) : print(ex) - ;; (ex:Int) : print-all([ex "'" sizeof(ex)]) - (ex:Int) : print(ex) - (ex) : print(ex) - -defn emit! (e:Expression,top:Symbol) : - defn greater-op? (op: PrimOp) -> True|False : - contains?([GREATER-OP], op) - defn greater-eq-op? (op: PrimOp) -> True|False : - contains?([GREATER-EQ-OP], op) - defn less-eq-op? (op: PrimOp) -> True|False : - contains?([LESS-EQ-OP], op) - defn less-op? (op: PrimOp) -> True|False : - contains?([LESS-OP], op) - defn cmp-op? (op: PrimOp) -> True|False : - greater-op?(op) or greater-eq-op?(op) or less-op?(op) or less-eq-op?(op) or - contains?([EQUAL-OP NEQUAL-OP] op) - match(e) : - (e:Ref) : emit-all([top "::" name(e)], top) - (e:UIntValue) : emit-all([value(e) "'" sane-width(width(e))], top) - (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:DoPrim) : - if cmp-op?(op(e)) : - emit-all([flo-op-name(op(e), args(e)) "'" prim-width(type(args(e)[0]))], top) - if greater-op?(op(e)) or greater-eq-op?(op(e)) : - emit-all([" " args(e)[1] " " args(e)[0]], top) - else : - emit-all([" " args(e)[0] " " args(e)[1]], top) - else if op(e) == BIT-SELECT-OP : - emit-all([flo-op-name(op(e), args(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([flo-op-name(op(e), args(e)) "'" w " " args(e)[0] " " consts(e)[1]], top) - else if op(e) == CONCAT-OP : - val w = prim-width(type(args(e)[1])) - emit-all([flo-op-name(op(e), args(e)) "'" w " " args(e)[0] " " args(e)[1]], top) - else if op(e) == PAD-OP or op(e) == CONVERT-OP : - emit-all([flo-op-name(op(e), args(e)) "'" prim-width(type(e)) " " args(e)[0] " 0"], top) - else : - emit-all([flo-op-name(op(e), args(e)) "'" prim-width(type(e))], top) - for arg in args(e) do : - print(" ") - emit!(arg, top) - for const in consts(e) do : - print-all([" " const "'" req-num-bits(const)]) - (e) : error("SHOULDN'T EMIT THIS") ;; print-all(["EMIT(" e ")"]) - ;(e) : emit-all(["mov'" prim-width(type(e)) " " e], top) ;TODO, not sure which one is right - -defn maybe-mov (e:Expression) -> String : - val need-mov? = match(e) : - (e:Ref) : true - (e:UIntValue) : true - (e:SIntValue) : true - (e:Subfield) : true - (e:Index) : true - (e) : false - if need-mov?: "mov " else: "" - -defn emit-s (s:Stmt, flokinds:HashTable<Symbol,FloKind>, top:Symbol,sh:HashTable<Symbol,Int>) : - defn emit-connect (s:Connect, en:Expression) : - match(loc(s)) : - (r:Ref) : - val n = name(r) - if key?(flokinds,n) : - match(flokinds[n]) : - (k:FRegKind) : - emit-all(["reg'" prim-width(type(r)) " " en " " exp(s)], top) - (k:FWritePortKind) : - emit-all([top "::" n " = wr'" prim-width(type(r)) " " en " " mem(k) " " index(k) " " exp(s) "\n"], top) - (k:FOutputPortKind) : - emit-all([top "::" n " = out'" prim-width(type(r)) " " exp(s) "\n"], top) - (k) : error("Shouldn't be here") - else : - emit-all([top "::" n " = " maybe-mov(exp(s)) exp(s) "\n"], top) - (o) : - println-all(["CONNEcT LOC " loc(s)]) - error("Unknown Connect") - match(s) : - (s:DefWire) : "" - (s:DefPoison) : "" - (s:DefInstance) : error("Shouldn't be here") - (e:DefAccessor) : - if acc-dir == READ : - emit-all(["rd'" prim-width(type(e)) " " "1" " " source(e) " " index(e)], top) - (s:DefMemory) : - val vtype = type(s) as VectorType - emit-all([top "::" name(s) " = mem'" prim-width(type(vtype)) " " size(vtype) "\n"], top) - (s:DefNode) : - emit-all([top "::" name(s) " = " maybe-mov(value(s)) value(s) "\n"], top) - (s:Begin) : do(emit-s{_, flokinds, top,sh}, body(s)) - (s:Connect) : emit-connect(s,UIntValue(BigIntLit("1"),LongWidth(1))) - (s:Conditionally) : emit-connect(conseq(s) as Connect,pred(s)) - (s) : s - -defn emit-module (m:InModule,sh:HashTable<Symbol,Int>) : - val flokinds = HashTable<Symbol,FloKind>(symbol-hash) - defn build-table (s:Stmt) -> False : - do(build-table,s) - match(s) : - (s:DefRegister) : flokinds[name(s)] = FRegKind() - (s:DefAccessor) : - switch {_ == acc-dir(s)} : - WRITE : flokinds[name(s)] = FWritePortKind(source(s),index(s)) - else : false - (s) : false - - for port in ports(m) do : - if name(port) ==`reset : - emit-all([name(m) "::" name(port) " = rst'1\n"], name(m)) - else : switch {_ == direction(port)} : - INPUT : print-all([name(m) "::" name(port) " = " "in'" prim-width(type(port)) "\n"]) - OUTPUT : flokinds[name(port)] = FOutputPortKind() - emit-s(body(m), flokinds, name(m),sh) - -public defn emit-flo (with-output:(() -> False) -> False, c:Circuit) : - with-output $ { - emit-module(modules(c)[0] as InModule,get-sym-hash(modules(c)[0] as InModule)) - false - } - c |
