diff options
| author | azidar | 2015-04-13 19:14:06 -0700 |
|---|---|---|
| committer | azidar | 2015-04-13 19:14:06 -0700 |
| commit | f201c512295d9ddb8181839c3e8b4160017e8dfc (patch) | |
| tree | b2950bf186fca89fe5e6bfed15c9b5c9b7746bc5 /src | |
| parent | faaf1249013ab2af6cfc0a16dacc738d84aaa21b (diff) | |
Stanza bug
Diffstat (limited to 'src')
| -rw-r--r-- | src/main/stanza/passes.stanza | 861 |
1 files changed, 62 insertions, 799 deletions
diff --git a/src/main/stanza/passes.stanza b/src/main/stanza/passes.stanza index 8b393c13..b861d10a 100644 --- a/src/main/stanza/passes.stanza +++ b/src/main/stanza/passes.stanza @@ -1860,811 +1860,74 @@ defn infer-widths (c:Circuit) -> Circuit : replace-var-widths(Circuit(modules*,main(c)),h) - - - - - - - - - - - - - - - - - - - - - - - - - -;;==================== WIDTH INFERENCE ====================== -;defstruct WidthVar <: Width : -; name: Symbol -; -;defmethod print (o:OutputStream, w:WidthVar) : -; print(o, name(w)) -; -;defn width! (t:Type) : -; match(t) : -; (t:UIntType) : width(t) -; (t:SIntType) : width(t) -; (t) : error("No width field.") -; -;defn put-width (t:Type, w:Width) : -; match(t) : -; (t:UIntType) : UIntType(w) -; (t:SIntType) : SIntType(w) -; (t) : t -; -;defn put-width (e:Expression, w:Width) : -; val type* = put-width(type(e), w) -; put-type(e, type*) -; -;defn add-width-vars (t:Type) : -; defn width? (w:Width) : -; match(w) : -; (w:UnknownWidth) : WidthVar(gensym()) -; (w) : w -; match(t) : -; (t:UIntType) : UIntType(width?(width(t))) -; (t:SIntType) : SIntType(width?(width(t))) -; (t) : map(add-width-vars, t) -; -;defn uint-width (i:Int) : -; var v:Int = i -; var n:Int = 0 -; while v != 0 : -; v = v >> 1 -; n = n + 1 -; IntWidth(n) -; -;defn sint-width (i:Int) : -; if i > 0 : -; val w = uint-width(i) -; IntWidth(width(w) + 1) -; else : -; val w = uint-width(neg(i) - 1) -; IntWidth(width(w) + 1) -; -;defn to-exp (w:Width) : -; match(w) : -; (w:IntWidth) : ELit(width(w)) -; (w:WidthVar) : EVar(name(w)) -; (w) : error $ string-join $ [ -; "Cannot convert " w " to exp."] -; -;defn primop-width (op:PrimOp, ws:List<Width>, ints:List<Int>) -> Exp : -; defn wmax (w1:Width, w2:Width) : -; EMax(to-exp(w1), to-exp(w2)) -; defn wplus (w1:Width, w2:Width) : -; EPlus(to-exp(w1), to-exp(w2)) -; defn wplus (w1:Width, w2:Int) : -; EPlus(to-exp(w1), ELit(w2)) -; defn wminus (w1:Width, w2:Width) : -; EMinus(to-exp(w1), to-exp(w2)) -; defn wminus (w1:Width, w2:Int) : -; EMinus(to-exp(w1), ELit(w2)) -; defn wmax-inc (w1:Width, w2:Width) : -; EPlus(wmax(w1, w2), ELit(1)) -; -; switch {op == _} : -; ADD-OP : wmax-inc(ws[0], ws[1]) -; ADD-WRAP-OP : wmax(ws[0], ws[1]) -; SUB-OP : wmax-inc(ws[0], ws[1]) -; SUB-WRAP-OP : wmax(ws[0], ws[1]) -; MUL-OP : wplus(ws[0], ws[1]) -; DIV-OP : wminus(ws[0], ws[1]) -; MOD-OP : to-exp(ws[1]) -; SHIFT-LEFT-OP : wplus(ws[0], ints[0]) -; SHIFT-RIGHT-OP : wminus(ws[0], ints[0]) -; PAD-OP : ELit(ints[0]) -; BIT-AND-OP : wmax(ws[0], ws[1]) -; BIT-OR-OP : wmax(ws[0], ws[1]) -; BIT-XOR-OP : wmax(ws[0], ws[1]) -; CONCAT-OP : wplus(ws[0], ints[0]) -; BIT-SELECT-OP : ELit(1) -; BITS-SELECT-OP : ELit(ints[0]) -; MUX-OP : wmax(ws[1], ws[2]) -; LESS-OP : ELit(1) -; LESS-EQ-OP : ELit(1) -; GREATER-OP : ELit(1) -; GREATER-EQ-OP : ELit(1) -; EQUAL-OP : ELit(1) -; -;defn put-type (el:Element, t:Type) -> Element : -; match(el) : -; (el:Register) : Register(t, value(el), enable(el)) -; (el:Memory) : Memory(t, writers(el)) -; (el:Node) : Node(t, value(el)) -; (el:Instance) : Instance(t, module(el), ports(el)) -; -;defn generate-constraints (c:Circuit) -> [Circuit, Vector<WConstraint>] : -; ;Constraints -; val cs = Vector<WConstraint>() -; defn new-constraint (Constraint: (Symbol, Exp) -> WConstraint, wvar:Width, width:Width) : -; match(wvar) : -; (wvar:WidthVar) : -; add(cs, Constraint(name(wvar), to-exp(width))) -; (wvar) : -; false -; -; defn to-width (e:Exp) : -; match(e) : -; (e:ELit) : -; IntWidth(width(e)) -; (e:EVar) : -; WidthVar(name(e)) -; (e) : -; val x = gensym() -; add(cs, WidthEqual(x, e)) -; WidthVar(x) -; -; ;Module types -; val mod-types = HashTable<Symbol,Type>(symbol-hash) -; -; defn add-port-vars (m:Module) -> Module : -; val ports* = -; for p in ports(m) map : -; val type* = add-width-vars(type(p)) -; Port(name(p), gender(p), type*) -; mod-types[name(m)] = BundleType(ports*) -; Module(name(m), ports*, body(m)) -; -; ;Add Width Variables -; defn add-module-vars (m:Module) -> Module : -; val types = HashTable<Symbol,Type>(symbol-hash) -; for p in ports(m) do : -; types[name(p)] = type(p) -; -; defn infer-exp-width (e:Expression) -> Expression : -; match(map(infer-exp-width, e)) : -; (e:WRef) : -; match(kind(e)) : -; (k:ModuleKind) : put-type(e, mod-types[name(e)]) -; (k) : put-type(e, types[name(e)]) -; (e:WSubfield) : -; val t = bundle-field-type(type(exp(e)), name(e)) -; put-width(e, width!(t)) -; (e:UIntValue) : -; match(width(e)) : -; (w:UnknownWidth) : UIntValue(value(e), uint-width(value(e))) -; (w) : e -; (e:SIntValue) : -; match(width(e)) : -; (w:UnknownWidth) : SIntValue(value(e), sint-width(value(e))) -; (w) : e -; (e:DoPrim) : -; val widths = map(width!{type(_)}, args(e)) -; val w = to-width(primop-width(op(e), widths, consts(e))) -; put-width(e, w) -; (e:ReadPort) : -; val elem-type = type(type(mem(e)) as VectorType) -; put-width(e, width!(elem-type)) -; -; defn infer-comm-width (c:Stmt) : -; match(c) : -; (c:LetRec) : -; ;Add width vars to elements -; var entries*: List<KeyValue<Symbol,Element>> = -; for entry in entries(c) map : -; val el-name = key(entry) -; key(entry) => -; match(value(entry)) : -; (el:Register|Node) : -; put-type(el, add-width-vars(type(el))) -; (el:Memory) : -; el -; (el:Instance) : -; val mod-type = type(infer-exp-width(module(el))) as BundleType -; val type = BundleType $ to-list $ -; for p in ports(mod-type) filter : -; gender(p) == OUTPUT -; put-type(el, type) -; -; ;Add vars to environment -; for entry in entries* do : -; types[key(entry)] = type(value(entry)) -; -; ;Infer types for elements -; entries* = -; for entry in entries* map : -; key(entry) => map(infer-exp-width, value(entry)) -; -; ;Generate constraints -; for entry in entries* do : -; val el-name = key(entry) -; match(value(entry)) : -; (el:Register) : -; new-constraint(WidthEqual, reg-width, val-width) where : -; val reg-width = width!(types[el-name]) -; val val-width = width!(type(value(el))) -; (el:Node) : -; new-constraint(WidthEqual, node-width, val-width) where : -; val node-width = width!(types[el-name]) -; val val-width = width!(type(value(el))) -; (el:Instance) : -; val mod-type = type(module(el)) as BundleType -; for entry in ports(el) do : -; new-constraint(WidthGreater, port-width, val-width) where : -; val port-name = key(entry) -; val port-width = width!(bundle-field-type(mod-type, port-name)) -; val val-width = width!(type(value(entry))) -; (el) : false -; -; ;Analyze body -; LetRec(entries*, infer-comm-width(body(c))) -; -; (c:Connect) : -; val loc* = infer-exp-width(loc(c)) -; val exp* = infer-exp-width(exp(c)) -; new-constraint(WidthGreater, loc-width, exp-width) where : -; val loc-width = width!(type(loc*)) -; val exp-width = width!(type(exp*)) -; Connect(loc*, exp*) -; -; (c:Begin) : -; map(infer-comm-width, c) -; -; Module(name(m), ports(m), body*) where : -; val body* = infer-comm-width(body(m)) -; -; val c* = -; Circuit(modules*, main(c)) where : -; val ms = map(add-port-vars, modules(c)) -; val modules* = map(add-module-vars, ms) -; [c*, cs] -; -; -;;================== FILL WIDTHS ============================ -;defn fill-widths (c:Circuit, solved:Streamable<WidthEqual>) : -; ;Populate table -; val table = HashTable<Symbol, Width>(symbol-hash) -; for eq in solved do : -; table[name(eq)] = IntWidth(width(value(eq) as ELit)) -; -; defn width? (w:Width) : -; match(w) : -; (w:WidthVar) : get?(table, name(w), UnknownWidth()) -; (w) : w -; -; defn fill-type (t:Type) : -; match(t) : -; (t:UIntType) : UIntType(width?(width(t))) -; (t:SIntType) : SIntType(width?(width(t))) -; (t) : map(fill-type, t) -; -; defn fill-exp (e:Expression) -> Expression : -; val e* = map(fill-exp, e) -; val type* = fill-type(type(e)) -; put-type(e*, type*) -; -; defn fill-element (e:Element) : -; val e* = map(fill-exp, e) -; val type* = fill-type(type(e)) -; put-type(e*, type*) -; -; defn fill-comm (c:Stmt) : -; match(c) : -; (c:LetRec) : -; val entries* = -; for e in entries(c) map : -; key(e) => fill-element(value(e)) -; LetRec(entries*, fill-comm(body(c))) -; (c) : -; map{fill-comm, _} $ -; map(fill-exp, c) -; -; defn fill-port (p:Port) : -; Port(name(p), gender(p), fill-type(type(p))) -; -; defn fill-mod (m:Module) : -; Module(name(m), ports*, body*) where : -; val ports* = map(fill-port, ports(m)) -; val body* = fill-comm(body(m)) -; -; Circuit(modules*, main(c)) where : -; val modules* = map(fill-mod, modules(c)) -; -; -;;=============== TYPE INFERENCE DRIVER ===================== -;defn infer-widths (c:Circuit) : -; val [c*, cs] = generate-constraints(c) -; val solved = solve-widths(cs) -; fill-widths(c*, solved) -; -; -;;================ PAD WIDTHS =============================== -;defn pad-widths (c:Circuit) : -; ;Pad an expression to the given width -; defn pad-exp (e:Expression, w:Int) : -; match(type(e)) : -; (t:UIntType|SIntType) : -; val prev-w = width!(t) as IntWidth -; if width(prev-w) < w : -; val type* = put-width(t, IntWidth(w)) -; DoPrim(PAD-OP, list(e), list(w), type*) -; else : -; e -; (t) : -; e -; -; defn pad-exp (e:Expression, w:Width) : -; val w-value = width(w as IntWidth) -; pad-exp(e, w-value) -; -; ;Convenience -; defn max-width (es:Streamable<Expression>) : -; defn int-width (e:Expression) : -; width(width!(type(e)) as IntWidth) -; maximum(stream(int-width, es)) -; -; defn match-widths (es:List<Expression>) : -; val w = max-width(es) -; map(pad-exp{_, w}, es) -; -; ;Match widths for an expression -; defn match-exp-width (e:Expression) : -; match(map(match-exp-width, e)) : -; (e:DoPrim) : -; if contains?([BIT-AND-OP, BIT-OR-OP, BIT-XOR-OP, EQUAL-OP], op(e)) : -; val args* = match-widths(args(e)) -; DoPrim(op(e), args*, consts(e), type(e)) -; else if op(e) == MUX-OP : -; val args* = List(head(args(e)), match-widths(tail(args(e)))) -; DoPrim(op(e), args*, consts(e), type(e)) -; else : -; e -; (e) : e -; -; defn match-element-width (e:Element) : -; match(map(match-exp-width, e)) : -; (e:Register) : -; val w = width!(type(e)) -; val value* = pad-exp(value(e), w) -; Register(type(e), value*, enable(e)) -; (e:Memory) : -; val width = width!(type(type(e) as VectorType)) -; val writers* = -; for w in writers(e) map : -; WritePort(index(w), pad-exp(value(w), width), enable(w)) -; Memory(type(e), writers*) -; (e:Node) : -; val w = width!(type(e)) -; val value* = pad-exp(value(e), w) -; Node(type(e), value*) -; (e:Instance) : -; val mod-type = type(module(e)) as BundleType -; val ports* = -; for p in ports(e) map : -; val port-type = bundle-field-type(mod-type, key(p)) -; val port-val = pad-exp(value(p), width!(port-type)) -; key(p) => port-val -; Instance(type(e), module(e), ports*) -; -; ;Match widths for a command -; defn match-comm-width (c:Stmt) : -; match(map(match-exp-width, c)) : -; (c:LetRec) : -; val entries* = -; for e in entries(c) map : -; key(e) => match-element-width(value(e)) -; LetRec(entries*, match-comm-width(body(c))) -; (c:Connect) : -; val w = width!(type(loc(c))) -; val exp* = pad-exp(exp(c), w) -; Connect(loc(c), exp*) -; (c) : -; map(match-comm-width, c) -; -; defn match-mod-width (m:Module) : -; Module(name(m), ports(m), body*) where : -; val body* = match-comm-width(body(m)) -; -; Circuit(modules*, main(c)) where : -; val modules* = map(match-mod-width, modules(c)) -; -; -;;================== INLINING =============================== -;defn inline-instances (c:Circuit) : -; val module-table = HashTable<Symbol,Module>(symbol-hash) -; val inlined? = HashTable<Symbol,True|False>(symbol-hash) -; for m in modules(c) do : -; module-table[name(m)] = m -; inlined?[name(m)] = false -; -; ;Convert a module into a sequence of elements -; defn to-elements (m:Module, -; inst:Symbol, -; port-exps:List<KeyValue<Symbol,Expression>>) -> -; List<KeyValue<Symbol, Element>> : -; defn rename-exp (e:Expression) : -; match(e) : -; (e:WRef) : WRef(prefix(inst, name(e)), type(e), kind(e), dir(e)) -; (e) : map(rename-exp, e) -; -; defn to-elements (c:Stmt) -> List<KeyValue<Symbol,Element>> : -; match(c) : -; (c:LetRec) : -; val entries* = -; for entry in entries(c) map : -; val name* = prefix(inst, key(entry)) -; val element* = map(rename-exp, value(entry)) -; name* => element* -; val body* = to-elements(body(c)) -; append(entries*, body*) -; (c:Connect) : -; val ref = loc(c) as WRef -; val name* = prefix(inst, name(ref)) -; list(name* => Node(type(exp(c)), rename-exp(exp(c)))) -; (c:Begin) : -; map-append(to-elements, body(c)) -; -; val inputs = -; for p in ports(m) map-append : -; if gender(p) == INPUT : -; val port-exp = lookup!(port-exps, name(p)) -; val name* = prefix(inst, name(p)) -; list(name* => Node(type(port-exp), port-exp)) -; else : -; List() -; append(inputs, to-elements(body(m))) -; -; ;Inline all instances in the module -; defn inline-instances (m:Module) : -; defn rename-exp (e:Expression) : -; match(e) : -; (e:WSubfield) : -; val inst-exp = exp(e) as WRef -; val name* = prefix(name(inst-exp), name(e)) -; WRef(name*, type(e), NodeKind(), dir(e)) -; (e) : -; map(rename-exp, e) -; -; defn inline-elems (es:List<KeyValue<Symbol,Element>>) : -; for entry in es map-append : -; match(value(entry)) : -; (el:Instance) : -; val mod-name = name(module(el) as WRef) -; val module = inlined-module(mod-name) -; to-elements(module, key(entry), ports(el)) -; (el) : -; list(entry) -; -; defn inline-comm (c:Stmt) : -; match(map(rename-exp, c)) : -; (c:LetRec) : -; val entries* = inline-elems(entries(c)) -; LetRec(entries*, inline-comm(body(c))) -; (c) : -; map(inline-comm, c) -; -; Module(name(m), ports(m), inline-comm(body(m))) -; -; ;Retrieve the inlined instance of a module -; defn inlined-module (name:Symbol) : -; if inlined?[name] : -; module-table[name] -; else : -; val module* = inline-instances(module-table[name]) -; module-table[name] = module* -; inlined?[name] = true -; module* -; -; ;Return the fully inlined circuit -; val main-module = inlined-module(main(c)) -; Circuit(list(main-module), main(c)) +;================= Inline Modules ======================== + +defn inline-instances (c:Circuit) : + val h = HashTable<Symbol,Module>(symbol-hash) + val h-s = HashTable<Symbol,Stmt>(symbol-hash) + for m in modules(c) do : + h[name(m)] = m + defn inline (m:Module,i:Symbol,top?:True|False) -> Stmt : + defn rename (n:Symbol) -> Symbol : + if not top? : to-symbol("~$~" % [i n]) + else : n + defn inline (s:Stmt) -> Stmt : + map{inline-e,_} $ match(map(inline,s)) : + (s:DefWire) : DefWire(rename(name(s)),type(s)) + (s:DefInstance) : + val n = name(module(s)) + val body* = + if key?(h-s,n) : h-s[n] + else : inline(name(module(s) as WRef),name(s)) + h-s[n] = body* + inline(body*) + (s:DefMemory) : DefMemory(rename(name(s)),type(s)) + (s:DefNode) : DefNode(rename(name(s)),value(s)) + (s) : s + defn inline-e (e:Expression) -> Expression : + match(map(inline-e,e)) : + (e:WRef) : WRef(rename(name(e)),type(e),kind(e),gender(e)) + (e:WSubfield) : + match(kind(e)) : + (k:InstanceKind) : + WRef(rename(to-symbol("~$~" % [name(exp(e) as WRef) name(e)]),type(e))) + (k:MemKind) : e + (e) : e + val v = Vector<Stmt>() + for p in ports(m) do : + add(v,DefWire(rename(name(p)),type(p))) + add(v,inline(body(m))) + Begin(to-list(v)) + + val top = for m in modules(c) find : name(m) == main(c) + Circuit(main(c), Module(name(top),ports(top),inline(top,`null,true))) - -;;;================ UTILITIES ================================ -; -; -; -;defn* root-ref (i:Immediate) : -; match(i) : -; (f:Subfield) : root-ref(imm(f)) -; (ind:Index) : root-ref(imm(ind)) -; (r) : r -; -;;defn lookup<?T> (e: Streamable<KeyValue<Immediate,?T>>, i:Immediate) : -;; for entry in e search : -;; if eqv?(key(entry), i) : -;; value(entry) -;; -;;defn lookup!<?T> (e: Streamable<KeyValue<Immediate,?T>>, i:Immediate) : -;; lookup(e, i) as T -;; -;;============ CHECK IF NAMES ARE UNIQUE ==================== -;defn check-duplicate-symbols (names: Streamable<Symbol>, msg: String) : -; val dict = HashTable<Symbol, True>(symbol-hash) -; for name in names do: -; if key?(dict, name): -; throw $ PassException $ string-join $ -; [msg ": " name] -; else: -; dict[name] = true -; -;defn check-duplicates (t: Type) : -; match(t) : -; (t:BundleType) : -; val names = map(name, ports(t)) -; check-duplicate-symbols{names, string-join(_)} $ -; ["Duplicate port name in bundle "] -; do(check-duplicates{type(_)}, ports(t)) -; (t:VectorType) : -; check-duplicates(type(t)) -; (t) : false -; -;defn check-duplicates (c: Stmt) : -; match(c) : -; (c:DefWire) : check-duplicates(type(c)) -; (c:DefRegister) : check-duplicates(type(c)) -; (c:DefMemory) : check-duplicates(type(c)) -; (c) : do(check-duplicates, children(c)) -; -;defn defined-names (c: Stmt) : -; generate<Symbol> : -; loop(c) where : -; defn loop (c:Stmt) : -; match(c) : -; (c:Stmt&HasName) : yield(name(c)) -; (c) : do(loop, children(c)) -; -;defn check-duplicates (m: Module): -; ;Check all duplicate names in all types in all ports and body -; do(check-duplicates{type(_)}, ports(m)) -; check-duplicates(body(m)) -; -; ;Check all names defined in module -; val names = concat(stream(name, ports(m)), -; defined-names(body(m))) -; check-duplicate-symbols{names, string-join(_)} $ -; ["Duplicate definition name in module " name(m)] -; -;defn check-duplicates (c: Circuit) : -; ;Check all duplicate names in all modules -; do(check-duplicates, modules(c)) -; -; ;Check all defined modules -; val names = stream(name, modules(c)) -; check-duplicate-symbols(names, "Duplicate module name") -; -; - - - - +;================= Bring to Real IR ======================== +; Returns a new Circuit with only real IR nodes. -;;================ CLEANUP COMMANDS ========================= -;defn cleanup (c:Stmt) : -; match(c) : -; (c:Begin) : -; to-command $ generate<Stmt> : -; loop(c) where : -; defn loop (c:Stmt) : -; match(c) : -; (c:Begin) : do(loop, body(c)) -; (c:EmptyStmt) : false -; (c) : yield(cleanup(c)) -; (c) : map(cleanup{_ as Stmt}, c) -; -;defn cleanup (c:Circuit) : -; val modules* = -; for m in modules(c) map : -; map(cleanup, m) -; Circuit(modules*, main(c)) -; +defn to-real-ir (c:Circuit) : + defn to-exp (e:Expression) : + match(map(to-exp,e)) : + (e:WRef) : Ref(name(e), type(e)) + (e:WSubfield) : Subfield(exp(e),name(e),type(e)) + (e:WRegInit) : error("Shouldn't be here") + (e:WIndex) : error("Shouldn't be here") + (e) : e + defn to-stmt (s:Stmt) : + match(map(to-exp,s)) : + (e:WDefAccessor) : error("Shouldn't be here") + (e:ConnectToIndexed) : error("Shouldn't be here") + (e:ConnectFromIndexed) : error("Shouldn't be here") + (e) : map(to-stmt) + Circuit(modules*, main(c)) where : + val modules* = + for m in modules(c) map : + Module(name(m), ports(m), to-stmt(body(m))) -;;;============= SHIM ======================================== -;;defn shim (i:Immediate) -> Immediate : -;; match(i) : -;; (i:RegData) : -;; Ref(name(i), gender(i), type(i)) -;; (i:InstPort) : -;; val inst = Ref(name(i), UNKNOWN-GENDER, UnknownType()) -;; Subfield(inst, port(i), gender(i), type(i)) -;; (i:Subfield) : -;; val imm* = shim(imm(i)) -;; put-imm(i, imm*) -;; (i) : i -;; -;;defn shim (c:Stmt) -> Stmt : -;; val c* = map(shim{_ as Immediate}, c) -;; map(shim{_ as Stmt}, c*) -;; -;;defn shim (c:Circuit) -> Circuit : -;; val modules* = -;; for m in modules(c) map : -;; Module(name(m), ports(m), shim(body(m))) -;; Circuit(modules*, main(c)) -;; -;;;================== INLINE MODULES ========================= -;;defn cat-name (p: String|Symbol, s: String|Symbol) -> Symbol : -;; if p == "" or p == `this : ;; TODO: REMOVE THIS WHEN `THIS GETS REMOVED -;; to-symbol(s) -;; else if s == `this : ;; TODO: DITTO -;; to-symbol(p) -;; else : -;; symbol-join([p, "/", s]) -;; -;;defn inline-command (c: Stmt, mods: HashTable<Symbol, Module>, prefix: String, cmds: Vector<Stmt>) : -;; defn rename (n: Symbol) -> Symbol : -;; cat-name(prefix, n) -;; defn inline-name (i:Immediate) -> Symbol : -;; match(i) : -;; (r:Ref) : rename(name(r)) -;; (f:Subfield) : cat-name(inline-name(imm(f)), name(f)) -;; (f:Index) : cat-name(inline-name(imm(f)), to-string(value(f))) -;; defn inline-imm (i:Immediate) -> Ref : -;; Ref(inline-name(i), gender(i), type(i)) -;; match(c) : -;; (c:DefUInt) : add(cmds, DefUInt(rename(name(c)), value(c), width(c))) -;; (c:DefSInt) : add(cmds, DefSInt(rename(name(c)), value(c), width(c))) -;; (c:DefWire) : add(cmds, DefWire(rename(name(c)), type(c))) -;; (c:DefRegister) : add(cmds, DefRegister(rename(name(c)), type(c))) -;; (c:DefMemory) : add(cmds, DefMemory(rename(name(c)), type(c), size(c))) -;; (c:DefInstance) : inline-module(mods, mods[name(module(c))], to-string(rename(name(c))), cmds) -;; (c:DoPrim) : add(cmds, DoPrim(rename(name(c)), op(c), map(inline-imm, args(c)), consts(c))) -;; (c:DefAccessor) : add(cmds, DefAccessor(rename(name(c)), inline-imm(source(c)), gender(c), inline-imm(index(c)))) -;; (c:Connect) : add(cmds, Connect(inline-imm(loc(c)), inline-imm(exp(c)))) -;; (c:Begin) : do(inline-command{_, mods, prefix, cmds}, body(c)) -;; (c:EmptyStmt) : c -;; (c) : error("Unsupported command") -;; -;;defn inline-port (p: Port, prefix: String) -> Stmt : -;; DefWire(cat-name(prefix, name(p)), type(p)) -;; -;;defn inline-module (mods: HashTable<Symbol, Module>, mod: Module, prefix: String, cmds: Vector<Stmt>) : -;; do(add{cmds, _}, map(inline-port{_, prefix}, ports(mod))) -;; inline-command(body(mod), mods, prefix, cmds) -;; -;;defn inline-modules (c: Circuit) -> Circuit : -;; val cmds = Vector<Stmt>() -;; val mods = HashTable<Symbol, Module>(symbol-hash) -;; for mod in modules(c) do : -;; mods[name(mod)] = mod -;; val top = mods[main(c)] -;; inline-command(body(top), mods, "", cmds) -;; val main* = Module(name(top), ports(top), Begin(to-list(cmds))) -;; Circuit(list(main*), name(top)) -;; -;; -;;;============= FLO PRINTER ====================================== -;;;;; TODO: -;;;;; not supported gt, lte -;; -;;defn flo-op-name (op:PrimOp) -> String : -;; switch {op == _} : -;; ADD-OP : "add" -;; ADD-MOD-OP : "add" -;; MINUS-OP : "sub" -;; SUB-MOD-OP : "sub" -;; MUL-OP : "mul" ;; todo: signed version -;; DIV-OP : "div" ;; todo: signed version -;; MOD-OP : "mod" ;; todo: signed version -;; SHIFT-LEFT-OP : "lsh" ;; todo: signed version -;; SHIFT-RIGHT-OP : "rsh" -;; PAD-OP : "pad" ;; todo: signed version -;; BIT-AND-OP : "and" -;; BIT-OR-OP : "or" -;; BIT-XOR-OP : "xor" -;; CONCAT-OP : "cat" -;; BIT-SELECT-OP : "rsh" -;; BITS-SELECT-OP : "rsh" -;; LESS-OP : "lt" ;; todo: signed version -;; LESS-EQ-OP : "lte" ;; todo: swap args -;; GREATER-OP : "gt" ;; todo: swap args -;; GREATER-EQ-OP : "gte" ;; todo: signed version -;; EQUAL-OP : "eq" -;; MUX-OP : "mux" -;; else : error $ string-join $ -;; ["Unable to print Primop: " op] -;; -;;defn emit (o:OutputStream, top:Symbol, ports:HashTable<Symbol, Port>, lits:HashTable<Symbol, DefUInt>, elt) : -;; match(elt) : -;; (e:String|Symbol|Int) : -;; print(o, e) -;; (e:Ref) : -;; if key?(lits, name(e)) : -;; val lit = lits[name(e)] -;; print-all(o, [value(lit) "'" width(lit)]) -;; else : -;; if key?(ports, name(e)) : -;; print-all(o, [top "::"]) -;; print(o, name(e)) -;; (e:IntWidth) : -;; print(o, value(e)) -;; (e:PrimOp) : -;; print(o, flo-op-name(e)) -;; (e) : -;; println-all(["EMIT " e]) -;; error("Unable to emit") -;; -;;defn emit-all (o:OutputStream, top:Symbol, ports:HashTable<Symbol, Port>, lits:HashTable<Symbol, DefUInt>, elts: Streamable) : -;; for e in elts do : emit(o, top, ports, lits, e) -;; -;;defn prim-width (type:Type) -> Width : -;; match(type) : -;; (t:UIntType) : width(t) -;; (t:SIntType) : width(t) -;; (t) : error("Bad prim width type") -;; -;;defn emit-command (o:OutputStream, cmd:Stmt, top:Symbol, lits:HashTable<Symbol, DefUInt>, regs:HashTable<Symbol, DefRegister>, accs:HashTable<Symbol, DefAccessor>, ports:HashTable<Symbol, Port>, outs:HashTable<Symbol, Port>) : -;; match(cmd) : -;; (c:DefUInt) : -;; lits[name(c)] = c -;; (c:DefSInt) : -;; emit-all(o, top, ports, lits, [name(c) " = " value(c) "'" width(c) "\n"]) -;; (c:DoPrim) : ;; NEED TO FIGURE OUT WHEN WIDTHS ARE NECESSARY AND EXTRACT -;; emit-all(o, top, ports, lits, [name(c) " = " op(c)]) -;; for arg in args(c) do : -;; print(o, " ") -;; emit(o, top, ports, lits, arg) -;; for const in consts(c) do : -;; print(o, " ") -;; emit(o, top, ports, lits, const) -;; print("\n") -;; (c:DefRegister) : -;; regs[name(c)] = c -;; (c:DefMemory) : -;; emit-all(o, top, ports, lits, [name(c) " : mem'" prim-width(type(c)) " " size(c) "\n"]) -;; (c:DefAccessor) : -;; accs[name(c)] = c -;; (c:Connect) : -;; val dst = name(loc(c) as Ref) -;; val src = name(exp(c) as Ref) -;; if key?(regs, dst) : -;; val reg = regs[dst] -;; emit-all(o, top, ports, lits, [dst " = reg'" prim-width(type(reg)) " 0'" prim-width(type(reg)) " " exp(c) "\n"]) -;; else if key?(accs, dst) : -;; val acc = accs[dst] -;; ;; assert(gender(acc) == OUTPUT) -;; emit-all(o, top, ports, lits, [dst " = wr " source(acc) " " index(acc) " " exp(c) "\n"]) -;; else if key?(outs, dst) : -;; val out = outs[dst] -;; emit-all(o, top, ports, lits, [top "::" dst " = out'" prim-width(type(out)) " " exp(c) "\n"]) -;; else if key?(accs, src) : -;; val acc = accs[src] -;; ;; assert(gender(acc) == INPUT) -;; emit-all(o, top, ports, lits, [dst " = rd " source(acc) " " index(acc) "\n"]) -;; else : -;; emit-all(o, top, ports, lits, [dst " = mov " exp(c) "\n"]) -;; (c:Begin) : -;; do(emit-command{o, _, top, lits, regs, accs, ports, outs}, body(c)) -;; (c:DefWire|EmptyStmt) : -;; print("") -;; (c) : -;; error("Unable to print command") -;; -;;defn emit-module (o:OutputStream, m:Module) : -;; val regs = HashTable<Symbol, DefRegister>(symbol-hash) -;; val accs = HashTable<Symbol, DefAccessor>(symbol-hash) -;; val lits = HashTable<Symbol, DefUInt>(symbol-hash) -;; val outs = HashTable<Symbol, Port>(symbol-hash) -;; val portz = HashTable<Symbol, Port>(symbol-hash) -;; for port in ports(m) do : -;; portz[name(port)] = port -;; if gender(port) == OUTPUT : -;; outs[name(port)] = port -;; else if name(port) == `reset : -;; print-all(o, [name(m) "::reset = rst\n"]) -;; else : -;; print-all(o, [name(m) "::" name(port) " = " "in'" prim-width(type(port)) "\n"]) -;; emit-command(o, body(m), name(m), lits, regs, accs, portz, outs) -;; -;;public defn emit-circuit (o:OutputStream, c:Circuit) : -;; emit-module(o, modules(c)[0]) ;============= DRIVER ====================================== @@ -2692,8 +1955,8 @@ public defn run-passes (c: Circuit, p: List<Char>) : if contains(p,'p') : do-stage("Initialize Registers", initialize-registers) if contains(p,'j') : do-stage("Expand Whens", expand-whens) if contains(p,'k') : do-stage("Infer Widths", infer-widths) + if contains(p,'n') : do-stage("Inline Instances", inline-instances) ;if contains(p,'n') : do-stage("Pad Widths", pad-widths) - ;if contains(p,'o') : do-stage("Inline Instances", inline-instances) println("Done!") |
