aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorazidar2015-04-13 19:14:06 -0700
committerazidar2015-04-13 19:14:06 -0700
commitf201c512295d9ddb8181839c3e8b4160017e8dfc (patch)
treeb2950bf186fca89fe5e6bfed15c9b5c9b7746bc5 /src
parentfaaf1249013ab2af6cfc0a16dacc738d84aaa21b (diff)
Stanza bug
Diffstat (limited to 'src')
-rw-r--r--src/main/stanza/passes.stanza861
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!")