diff options
| -rw-r--r-- | src/main/stanza/firrtl-ir.stanza | 15 | ||||
| -rw-r--r-- | src/main/stanza/firrtl-test-main.stanza | 1 | ||||
| -rw-r--r-- | src/main/stanza/ir-parser.stanza | 2 | ||||
| -rw-r--r-- | src/main/stanza/ir-utils.stanza | 6 | ||||
| -rw-r--r-- | src/main/stanza/passes.stanza | 334 |
5 files changed, 170 insertions, 188 deletions
diff --git a/src/main/stanza/firrtl-ir.stanza b/src/main/stanza/firrtl-ir.stanza index dc06e891..6cc5cc48 100644 --- a/src/main/stanza/firrtl-ir.stanza +++ b/src/main/stanza/firrtl-ir.stanza @@ -5,7 +5,11 @@ defpackage firrtl.ir2 : public definterface Direction public val INPUT = new Direction public val OUTPUT = new Direction -public val UNKNOWN-DIR = new Direction + +definterface Gender +public val MALE = new Gender +public val FEMALE = new Gender + public definterface Width public defstruct UnknownWidth <: Width @@ -115,7 +119,7 @@ public defmulti type (e:Expression) -> Type public defstruct Ref <: Expression : name: Symbol type: Type [multi => false] -public defstruct Field <: Expression : +public defstruct Subfield <: Expression : exp: Expression name: Symbol type: Type [multi => false] @@ -202,12 +206,17 @@ public defstruct UIntType <: Type : public defstruct SIntType <: Type : width: Width public defstruct BundleType <: Type : - ports: List<Port> + ports: List<Field> public defstruct VectorType <: Type : type: Type size: Int public defstruct UnknownType <: Type +public defstruct Field : + name: Symbol + gender: Gender + type: Type + public defstruct Port : name: Symbol direction: Direction diff --git a/src/main/stanza/firrtl-test-main.stanza b/src/main/stanza/firrtl-test-main.stanza index fe940a9f..80c5e257 100644 --- a/src/main/stanza/firrtl-test-main.stanza +++ b/src/main/stanza/firrtl-test-main.stanza @@ -22,6 +22,7 @@ defn set-printvars! (p:List<Char>) : if contains(p,'t') : PRINT-TYPES = true if contains(p,'k') : PRINT-KINDS = true if contains(p,'w') : PRINT-WIDTHS = true + if contains(p,'g') : PRINT-GENDERS = true if contains(p,'c') : PRINT-CIRCUITS = true defn main () : diff --git a/src/main/stanza/ir-parser.stanza b/src/main/stanza/ir-parser.stanza index cbd57f9b..f52abf13 100644 --- a/src/main/stanza/ir-parser.stanza +++ b/src/main/stanza/ir-parser.stanza @@ -155,7 +155,7 @@ rd.defsyntax firrtl : (?x:#exp . ?f:#int) : Index(x, ut(f), UnknownType()) (?x:#exp . ?f:#symbol) : - Field(x, ut(f), UnknownType()) + Subfield(x, ut(f), UnknownType()) (?x:#exp-form) : x diff --git a/src/main/stanza/ir-utils.stanza b/src/main/stanza/ir-utils.stanza index 9e8c63c5..298dd6a9 100644 --- a/src/main/stanza/ir-utils.stanza +++ b/src/main/stanza/ir-utils.stanza @@ -13,7 +13,7 @@ defmethod print (o:OutputStream, d:Direction) : switch {d == _} : INPUT : "input" OUTPUT: "output" - UNKNOWN-DIR : "unknown" + ;UNKNOWN-DIR : "unknown" defmethod print (o:OutputStream, w:Width) : print{o, _} $ @@ -123,7 +123,7 @@ defmethod print (o:OutputStream, op:PrimOp) : defmethod print (o:OutputStream, e:Expression) : match(e) : (e:Ref) : print(o, name(e)) - (e:Field) : print-all(o, [exp(e) "." name(e)]) + (e:Subfield) : print-all(o, [exp(e) "." name(e)]) (e:Index) : print-all(o, [exp(e) "." value(e)]) (e:UIntValue) : print-all(o, ["UInt(" value(e) ")"]) (e:SIntValue) : print-all(o, ["SInt(" value(e) ")"]) @@ -263,7 +263,7 @@ public defn map<?T> (f: Type -> Type, t:?T&Type) -> T : public defmulti map<?T> (f: Expression -> Expression, e:?T&Expression) -> T defmethod map (f: Expression -> Expression, e:Expression) -> Expression : match(e) : - (e:Field) : Field(f(exp(e)), name(e), type(e)) + (e:Subfield) : Subfield(f(exp(e)), name(e), type(e)) (e:Index) : Index(f(exp(e)), value(e), type(e)) (e:DoPrim) : DoPrim(op(e), map(f, args(e)), consts(e), type(e)) (e:ReadPort) : ReadPort(f(mem(e)), f(index(e)), type(e)) diff --git a/src/main/stanza/passes.stanza b/src/main/stanza/passes.stanza index 3cdb553b..02997ba1 100644 --- a/src/main/stanza/passes.stanza +++ b/src/main/stanza/passes.stanza @@ -24,35 +24,40 @@ defstruct ModuleKind <: Kind defstruct InstanceKind <: Kind defstruct StructuralMemKind <: Kind ; Separate kind because need special treatment +;val UNKNOWN-DIR = new Direction +val UNKNOWN-GENDER = new Gender +val BI-GENDER = new Gender + defstruct WRef <: Expression : name: Symbol type: Type [multi => false] kind: Kind - dir: Direction [multi => false] + gender: Gender [multi => false] -defstruct WField <: Expression : +defstruct WSubfield <: Expression : exp: Expression name: Symbol type: Type [multi => false] - dir: Direction [multi => false] + gender: Gender [multi => false] defstruct WIndex <: Expression : exp: Expression value: Int type: Type [multi => false] - dir: Direction [multi => false] + gender: Gender [multi => false] defstruct WDefAccessor <: Stmt : name: Symbol source: Expression index: Expression - dir: Direction + gender: Gender ;================ WORKING IR UTILS ========================= ;============== DEBUG STUFF ============================= public var PRINT-TYPES : True|False = false public var PRINT-KINDS : True|False = false public var PRINT-WIDTHS : True|False = false +public var PRINT-GENDERS : True|False = false public var PRINT-CIRCUITS : True|False = false ;=== Printers === defmethod print (o:OutputStream, k:Kind) : @@ -70,8 +75,11 @@ defmethod print (o:OutputStream, k:Kind) : defn hasWidth (e:Expression|Stmt|Type|Element|Port) : e typeof UIntType|SIntType|UIntValue|SIntValue +defn hasWidth (e:Expression|Stmt|Type|Element|Port) : + e typeof UIntType|SIntType|UIntValue|SIntValue + defn hasType (e:Expression|Stmt|Type|Element|Port) : - e typeof Ref|Field|Index|DoPrim|ReadPort|WRef|WField + e typeof Ref|Subfield|Index|DoPrim|ReadPort|WRef|WSubfield |WIndex|DefWire|DefRegister|DefMemory|Register |Memory|Node|Instance|VectorType|Port @@ -99,7 +107,7 @@ defmethod print (o:OutputStream, e:WRef) : print(o,name(e)) print-debug(o,e as ?) -defmethod print (o:OutputStream, e:WField) : +defmethod print (o:OutputStream, e:WSubfield) : print-all(o,[exp(e) "." name(e)]) print-debug(o,e as ?) @@ -111,8 +119,8 @@ defmethod print (o:OutputStream, s:WDefAccessor) : print-all(o,[dir(s) " accessor " name(s) " = " source(s) "[" index(s) "]"]) print-debug(o,s) -defmethod map (f: Expression -> Expression, e: WField) : - WField(f(exp(e)), name(e), type(e), dir(e)) +defmethod map (f: Expression -> Expression, e: WSubfield) : + WSubfield(f(exp(e)), name(e), type(e), dir(e)) defmethod map (f: Expression -> Expression, e: WIndex) : WIndex(f(exp(e)), value(e), type(e), dir(e)) @@ -121,25 +129,25 @@ defmethod map (f: Expression -> Expression, c:WDefAccessor) : WDefAccessor(name(c), f(source(c)), f(index(c)), dir(c)) ;================= DIRECTION =============================== -defmulti dir (e:Expression) -> Direction +defmulti dir (e:Expression) -> Gender defmethod dir (e:Expression) : OUTPUT ;================= Bring to Working IR ======================== -; Returns a new Circuit with Refs, Fields, Indexes and DefAccessors +; Returns a new Circuit with Refs, Subfields, Indexes and DefAccessors ; replaced with IR-internal nodes that contain additional -; information (kind, direction) +; information (kind, gender) defn to-working-ir (c:Circuit) : defn to-exp (e:Expression) : match(map(to-exp,e)) : - (e:Ref) : WRef(name(e), type(e), NodeKind(), UNKNOWN-DIR) - (e:Field) : WField(exp(e), name(e), type(e), UNKNOWN-DIR) - (e:Index) : WIndex(exp(e), value(e), type(e), UNKNOWN-DIR) + (e:Ref) : WRef(name(e), type(e), NodeKind(), UNKNOWN-GENDER) + (e:Subfield) : WSubfield(exp(e), name(e), type(e), UNKNOWN-GENDER) + (e:Index) : WIndex(exp(e), value(e), type(e), UNKNOWN-GENDER) (e) : e defn to-stmt (s:Stmt) : match(map(to-exp,s)) : - (s:DefAccessor) : WDefAccessor(name(s),source(s),index(s), UNKNOWN-DIR) + (s:DefAccessor) : WDefAccessor(name(s),source(s),index(s), UNKNOWN-GENDER) (s) : map(to-stmt,s) Circuit(modules*, main(c)) where : @@ -226,14 +234,14 @@ defn make-explicit-reset (c:Circuit) : defn route-reset (s:Stmt) -> Stmt : match(s) : (s:DefInstance) : - val iref = WField(WRef(name(s), UnknownType(), InstanceKind(), UNKNOWN-DIR),`reset,UnknownType(),UNKNOWN-DIR) - val pref = WRef(`reset, UnknownType(), PortKind(), INPUT) + val iref = WSubfield(WRef(name(s), UnknownType(), InstanceKind(), UNKNOWN-GENDER),`reset,UnknownType(),UNKNOWN-GENDER) + val pref = WRef(`reset, UnknownType(), PortKind(), MALE) Begin(to-list([s,Connect(iref,pref)])) (s) : map(route-reset,s) var ports! = ports(m) if not contains?(explicit-reset,name(m)) : - ports! = append(ports(m),list(Port(`reset,INPUT,UIntType(IntWidth(1))))) + ports! = append(ports(m),list(Port(`reset,MALE,UIntType(IntWidth(1))))) val body! = route-reset(body(m)) Module(name(m),ports!,body!) @@ -262,14 +270,14 @@ defn initialize-registers (c:Circuit) : defn add-when (s:Stmt,renames:HashTable<Symbol,Symbol>) -> Stmt : var inits = List<Stmt>() for kv in renames do : - val refreg = WRef(key(kv),UnknownType(),RegKind(),UNKNOWN-DIR) - val refwire = WRef(value(kv),UnknownType(),NodeKind(),UNKNOWN-DIR) + val refreg = WRef(key(kv),UnknownType(),RegKind(),UNKNOWN-GENDER) + val refwire = WRef(value(kv),UnknownType(),NodeKind(),UNKNOWN-GENDER) val connect = Connect(refreg,refwire) inits = append(inits,list(connect)) if empty?(inits) : s else : - val pred = WRef(`reset, UnknownType(), PortKind(), UNKNOWN-DIR) + val pred = WRef(`reset, UnknownType(), PortKind(), UNKNOWN-GENDER) val when-reset = Conditionally(pred,Begin(inits),Begin(List<Stmt>())) Begin(list(s,when-reset)) @@ -279,11 +287,11 @@ defn initialize-registers (c:Circuit) : map(rename-stmt,s) defn rename-expr (e:Expression) -> Expression : match(e) : - (e:WField) : + (e:WSubfield) : if name(e) == `init and register?(exp(e)) : ;TODO Error if l does not contain register val new-name = l[name(exp(e) as WRef)] - WRef(new-name,UnknownType(),NodeKind(),UNKNOWN-DIR) + WRef(new-name,UnknownType(),NodeKind(),UNKNOWN-GENDER) else : e (e) : map(rename-expr,e) defn register? (e:Expression) -> True|False : @@ -311,7 +319,7 @@ defn initialize-registers (c:Circuit) : [Begin(body!),renames] where : val defreg = s val defwire = DefWire(wire-name,type(s)) - val conwire = Connect(WRef(wire-name,UnknownType(),NodeKind(),UNKNOWN-DIR),Null()) + val conwire = Connect(WRef(wire-name,UnknownType(),NodeKind(),UNKNOWN-GENDER),Null()) val body! = list(defreg,defwire,conwire) (s:Conditionally) : [Conditionally(pred(s),initialize-scope(conseq(s)),initialize-scope(alt(s))),empty-hash] @@ -469,10 +477,8 @@ defn get-type (b:Symbol,l:List<KeyValue<Symbol,Type>>) -> Type : val ma = for kv in l find : b == key(kv) if ma != false : val ret = value(ma as KeyValue<Symbol,Type>) - ;println-all(["Found! Returning " ret " for " b]) ret else : - ;println-all(["Not found! Returning " UnknownType() " for " b]) UnknownType() defn bundle-field-type (v:Type,s:Symbol) -> Type : @@ -492,7 +498,7 @@ defn infer-exp-types (e:Expression, l:List<KeyValue<Symbol,Type>>) -> Expression val r = map(infer-exp-types{_,l},e) match(r) : (e:WRef) : WRef(name(e), get-type(name(e),l),kind(e),dir(e)) - (e:WField) : WField(exp(e),name(e), bundle-field-type(type(exp(e)),name(e)),dir(e)) + (e:WSubfield) : WSubfield(exp(e),name(e), bundle-field-type(type(exp(e)),name(e)),dir(e)) (e:WIndex) : WIndex(exp(e),value(e), get-vector-subtype(type(exp(e))),dir(e)) (e:DoPrim) : DoPrim(op(e),args(e),consts(e),get-primop-rettype(e)) (e:ReadPort) : ReadPort(mem(e),index(e),get-vector-subtype(type(mem(e)))) @@ -540,126 +546,92 @@ defn infer-types (c:Circuit) -> Circuit : ;============= INFER DIRECTIONS ============================ -;defn flip (d:Direction) : -; switch {d == _} : -; INPUT : OUTPUT -; OUTPUT : INPUT -; else : d -; -;defn times (d1:Direction, d2:Direction) : -; if d1 == INPUT : flip(d2) -; else : d2 -; -;defn lookup-port (ports: Streamable<Port>, port-name: Symbol) : -; for port in ports find : -; name(port) == port-name -; -;defn bundle-field-dir (t:Type, n:Symbol) -> Direction : -; match(t) : -; (t:BundleType) : -; match(lookup-port(ports(t), n)) : -; (p:Port) : direction(p) -; (p) : UNKNOWN-DIR -; (t) : UNKNOWN-DIR -; -;defn infer-dirs (m:Module) : -; ;=== Direction of all Binders === -; val BI-DIR = new Direction -; val directions = HashTable<Symbol,Direction>(symbol-hash) -; defn find-dirs (c:Stmt) : -; match(c) : -; (c:LetRec) : -; for entry in entries(c) do : -; directions[key(entry)] = OUTPUT -; find-dirs(body(c)) -; (c:DefWire) : -; directions[name(c)] = BI-DIR -; (c:DefRegister) : -; directions[name(c)] = BI-DIR -; (c:DefInstance) : -; directions[name(c)] = OUTPUT -; (c:DefMemory) : -; directions[name(c)] = BI-DIR -; (c:WDefAccessor) : -; directions[name(c)] = dir(c) -; (c) : -; do(find-dirs, children(c)) -; for p in ports(m) do : -; directions[name(p)] = flip(direction(p)) -; find-dirs(body(m)) -; -; ;=== Fix Point Status === -; var changed? = false -; -; ;=== Infer directions of Expression === -; defn infer-exp (e:Expression, desired:Direction) : -; match(e) : -; (e:WRef) : -; val dir* = let : -; if kind(e) typeof ModuleKind : -; OUTPUT -; else : -; val old-dir = directions[name(e)] -; switch {old-dir == _} : -; BI-DIR : -; desired -; UNKNOWN-DIR : -; if directions[name(e)] != desired : -; directions[name(e)] = desired -; changed? = true -; desired -; else : -; old-dir -; WRef(name(e), type(e), kind(e), dir*) -; (e:WField) : -; val port-dir = bundle-field-dir(type(exp(e)), name(e)) -; val exp* = infer-exp(exp(e), port-dir * desired) -; WField(exp*, name(e), type(e), port-dir * dir(exp*)) -; (e:WIndex) : -; val exp* = infer-exp(exp(e), desired) -; WIndex(exp*, value(e), type(e), dir(exp*)) -; (e) : -; map(infer-exp{_, OUTPUT}, e) -; -; ;=== Infer directions of Stmts === -; defn infer-comm (c:Stmt) : -; match(c) : -; (c:LetRec) : -; val c* = map(infer-exp{_, OUTPUT}, c) -; LetRec(entries(c*), infer-comm(body(c))) -; (c:DefInstance) : -; DefInstance(name(c), -; infer-exp(module(c), OUTPUT)) -; (c:WDefAccessor) : -; val d = directions[name(c)] -; WDefAccessor(name(c), -; infer-exp(source(c), d), -; infer-exp(index(c), OUTPUT), -; d) -; (c:Conditionally) : -; Conditionally(infer-exp(pred(c), OUTPUT), -; infer-comm(conseq(c)), -; infer-comm(alt(c))) -; (c:Connect) : -; Connect(infer-exp(loc(c), INPUT), infer-exp(exp(c), OUTPUT)) -; (c) : -; map(infer-comm, c) -; -; ;=== Iterate until fix point === -; defn* fixpoint (c:Stmt) : -; changed? = false -; val c* = infer-comm(c) -; if changed? : fixpoint(c*) -; else : c* -; -; Module(name(m), ports(m), body*) where : -; val body* = fixpoint(body(m)) -; -;defn infer-directions (c:Circuit) : -; Circuit(modules*, main(c)) where : -; val modules* = map(infer-dirs, modules(c)) -; -; +; To ensure a proper circuit, we must ensure that assignments +; only work on expressions that can be assigned to. Similarly, +; we must ensure that only expressions that can be read from +; are used to assign from. This invariant requires each +; expression's gender to be inferred. +; Various elements can be bi-gender (e.g. wires) and can +; thus be treated as either female or male. Conversely, some +; elements are single-gender (e.g. accessors, ports). +; Because accessor gender is not known during declaration, +; this pass requires iterating until a fixed point is reached. + +defn infer-genders (c:Circuit) : + defn resolve (body:Stmt, kinds:HashTable<Symbol,Kind>) : + defn resolve-stmt (s:Stmt) -> Stmt : + match(s) + ; (s:LetRec) : s ; TODO get rid of this + ; (s:DefInstance) : genders[name(s)] = MALE + ; (s:DefMemory) : genders[name(s)] = BI-GENDER ;TODO WHY?? + ; (s:WDefAccessor) : genders[name(s)] = gender(s) + ; (s) : false + ; map(find-stmt,s) + + ;defn resolve-expr (e:Expression) -> Expression : + ; match(e) : + ; (e:WRef) : WRef(name(e),type(e),kinds[name(e)],dir(e)) + ; (e) : map(resolve-expr,e) + + ;resolve-stmt(body) + + defn find (m:Module, genders:HashTable<Symbol,Gender>) : + defn find-stmt (s:Stmt) -> Stmt : + match(s) + (s:LetRec) : s ; TODO get rid of this + (s:DefWire) : genders[name(s)] = BI-GENDER + (s:DefRegister) : genders[name(s)] = BI-GENDER + (s:DefInstance) : genders[name(s)] = MALE + (s:DefMemory) : genders[name(s)] = BI-GENDER ;TODO WHY?? + (s:WDefAccessor) : genders[name(s)] = gender(s) + (s) : false + map(find-stmt,s) + + kinds[name(m)] = ModuleKind() + for p in ports(m) do : + kinds[name(p)] = PortKind() + find-stmt(body(m)) + + defn resolve-genders (m:Module, c:Circuit) -> Module : + val genders = HashTable<Symbol,Genders>(symbol-hash) + for m in modules(c) do : + genders[name(m)] = flip(to-field(ports(m))) + find(m,genders) + val [body*,done?] = resolve(body(m),kinds) + val module* = Module(name(m),ports(m),body*) + if done? : module* + else : resolve-genders(module,c) + + Circuit(modules*, main(c)) where : + val modules* = + for m in modules(c) map : + resolve-genders(m,c) + +;first pass, probably will delete +defn iter-infer-genders (m:Module,l:HashTable<Symbol, Gender>) -> [Circuit, True|False] : + var all-done? = false + val body* = + for m in modules(c) map : + val [m*,done?] = iter-infer-genders(m) + all-done? = all-done? and done? + m* + [Circuit(modules*,name(c)),all-done?] + + +defn iter-infer-genders (c:Circuit) -> [Circuit, True|False] : + var all-done? = false + val modules* = + for m in modules(c) map : + val [m*,done?] = iter-infer-genders(m) + all-done? = all-done? and done? + m* + [Circuit(modules*,name(c)),all-done?] + +defn infer-genders (c:Circuit) -> Circuit : + val [c*,done?] = iter-infer-genders(c) + if done? : c* + else : infer-genders(c*) + ;;============== EXPAND VECS ================================ ;defstruct ManyConnect <: Stmt : ; index: Expression @@ -731,7 +703,7 @@ defn infer-types (c:Circuit) -> Circuit : ; ;defn prefix-ports (pre:Symbol, ports:List<Port>) : ; for p in ports map : -; Port(prefix(pre, name(p)), direction(p), type(p)) +; Port(prefix(pre, name(p)), gender(p), type(p)) ; ;defn flatten-ports (port:Port) -> List<Port> : ; match(type(port)) : @@ -739,11 +711,11 @@ defn infer-types (c:Circuit) -> Circuit : ; val ports = map-append(flatten-ports, ports(t)) ; for p in ports map : ; Port(prefix(name(port), name(p)), -; direction(port) * direction(p), +; gender(port) * gender(p), ; type(p)) ; (t:VectorType) : ; val type* = flatten-type(t) -; flatten-ports(Port(name(port), direction(port), type*)) +; flatten-ports(Port(name(port), gender(port), type*)) ; (t:Type) : ; list(port) ; @@ -817,7 +789,7 @@ defn infer-types (c:Circuit) -> Circuit : ; ;Collapse all field/index expressions ; defn collapse-exp (e:Expression) -> Expression : ; match(e) : -; (e:WField) : +; (e:WSubfield) : ; match(collapse-exp(exp(e))) : ; (ei:WRef) : ; if kind(ei) typeof InstanceKind : @@ -825,11 +797,11 @@ defn infer-types (c:Circuit) -> Circuit : ; else : ; WRef(name*, type(e), kind(ei), dir(e)) where : ; val name* = prefix(name(ei), name(e)) -; (ei:WField) : -; WField(exp(ei), name*, type(e), dir(e)) where : +; (ei:WSubfield) : +; WSubfield(exp(ei), name*, type(e), dir(e)) where : ; val name* = prefix(name(ei), name(e)) ; (e:WIndex) : -; collapse-exp(WField(exp(e), name, type(e), dir(e))) where : +; collapse-exp(WSubfield(exp(e), name, type(e), dir(e))) where : ; val name = to-symbol(value(e)) ; (e) : ; map(collapse-exp, e) @@ -839,8 +811,8 @@ defn infer-types (c:Circuit) -> Circuit : ; match(type(e)) : ; (t:BundleType) : ; for p in ports(t) map : -; val dir* = direction(p) * dir(e) -; collapse-exp(WField(e, name(p), type(p), dir*)) +; val dir* = gender(p) * dir(e) +; collapse-exp(WSubfield(e, name(p), type(p), dir*)) ; (t) : ; list(collapse-exp(e)) ; @@ -881,7 +853,7 @@ defn infer-types (c:Circuit) -> Circuit : ; for (p in ports(t), src in srcs) map : ; WDefAccessor(name*, src, index(c), dir*) where : ; val name* = prefix(name(c), name(p)) -; val dir* = direction(p) * dir(c) +; val dir* = gender(p) * dir(c) ; (t) : ; c ; (c:Connect) : @@ -970,7 +942,7 @@ defn infer-types (c:Circuit) -> Circuit : ; match(e1, e2) : ; (e1:WRef, e2:WRef) : ; name(e1) == name(e2) -; (e1:WField, e2:WField) : +; (e1:WSubfield, e2:WSubfield) : ; name(e1) == name(e2) and ; key-eqv?(exp(e1), exp(e2)) ; (e1, e2) : @@ -1039,10 +1011,10 @@ defn infer-types (c:Circuit) -> Circuit : ; val module-type = type(module(c)) as BundleType ; val input-ports = to-list $ ; for p in ports(module-type) filter : -; direction(p) == INPUT +; gender(p) == INPUT ; val inst-ref = WRef(name(c), module-type, InstanceKind(), OUTPUT) ; for p in input-ports map : -; WField(inst-ref, name(p), type(p), INPUT) => VoidValue() +; WSubfield(inst-ref, name(p), type(p), INPUT) => VoidValue() ; append(entries, env) ; (c:DefMemory) : ; add(commands, c) @@ -1086,7 +1058,7 @@ defn infer-types (c:Circuit) -> Circuit : ; val env0 = let : ; val output-ports = to-list $ ; for p in ports(m) filter : -; direction(p) == OUTPUT +; gender(p) == OUTPUT ; for p in output-ports map : ; val port-ref = WRef(name(p), type(p), PortKind(), INPUT) ; port-ref => VoidValue() @@ -1127,7 +1099,7 @@ defn infer-types (c:Circuit) -> Circuit : ; match(kind(loc)) : ; (k:PortKind) : add(port-connects, c) ; (k) : connected[name(loc)] = exp(c) -; (loc:WField) : +; (loc:WSubfield) : ; val inst = exp(loc) as WRef ; val entry = name(loc) => exp(c) ; inst-ports[name(inst)] = List(entry, get?(inst-ports, name(inst), List())) @@ -1319,7 +1291,7 @@ defn infer-types (c:Circuit) -> Circuit : ; val ports* = ; for p in ports(m) map : ; val type* = add-width-vars(type(p)) -; Port(name(p), direction(p), type*) +; Port(name(p), gender(p), type*) ; mod-types[name(m)] = BundleType(ports*) ; Module(name(m), ports*, body(m)) ; @@ -1335,7 +1307,7 @@ defn infer-types (c:Circuit) -> Circuit : ; match(kind(e)) : ; (k:ModuleKind) : put-type(e, mod-types[name(e)]) ; (k) : put-type(e, types[name(e)]) -; (e:WField) : +; (e:WSubfield) : ; val t = bundle-field-type(type(exp(e)), name(e)) ; put-width(e, width!(t)) ; (e:UIntValue) : @@ -1371,7 +1343,7 @@ defn infer-types (c:Circuit) -> Circuit : ; val mod-type = type(infer-exp-width(module(el))) as BundleType ; val type = BundleType $ to-list $ ; for p in ports(mod-type) filter : -; direction(p) == OUTPUT +; gender(p) == OUTPUT ; put-type(el, type) ; ; ;Add vars to environment @@ -1468,7 +1440,7 @@ defn infer-types (c:Circuit) -> Circuit : ; map(fill-exp, c) ; ; defn fill-port (p:Port) : -; Port(name(p), direction(p), fill-type(type(p))) +; Port(name(p), gender(p), fill-type(type(p))) ; ; defn fill-mod (m:Module) : ; Module(name(m), ports*, body*) where : @@ -1614,7 +1586,7 @@ defn infer-types (c:Circuit) -> Circuit : ; ; val inputs = ; for p in ports(m) map-append : -; if direction(p) == INPUT : +; 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)) @@ -1626,7 +1598,7 @@ defn infer-types (c:Circuit) -> Circuit : ; defn inline-instances (m:Module) : ; defn rename-exp (e:Expression) : ; match(e) : -; (e:WField) : +; (e:WSubfield) : ; val inst-exp = exp(e) as WRef ; val name* = prefix(name(inst-exp), name(e)) ; WRef(name*, type(e), NodeKind(), dir(e)) @@ -1674,7 +1646,7 @@ defn infer-types (c:Circuit) -> Circuit : ; ;defn* root-ref (i:Immediate) : ; match(i) : -; (f:Field) : root-ref(imm(f)) +; (f:Subfield) : root-ref(imm(f)) ; (ind:Index) : root-ref(imm(ind)) ; (r) : r ; @@ -1775,11 +1747,11 @@ defn infer-types (c:Circuit) -> Circuit : ;;defn shim (i:Immediate) -> Immediate : ;; match(i) : ;; (i:RegData) : -;; Ref(name(i), direction(i), type(i)) +;; Ref(name(i), gender(i), type(i)) ;; (i:InstPort) : -;; val inst = Ref(name(i), UNKNOWN-DIR, UnknownType()) -;; Field(inst, port(i), direction(i), type(i)) -;; (i:Field) : +;; 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 @@ -1809,10 +1781,10 @@ defn infer-types (c:Circuit) -> Circuit : ;; defn inline-name (i:Immediate) -> Symbol : ;; match(i) : ;; (r:Ref) : rename(name(r)) -;; (f:Field) : cat-name(inline-name(imm(f)), name(f)) +;; (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), direction(i), type(i)) +;; 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))) @@ -1821,7 +1793,7 @@ defn infer-types (c:Circuit) -> Circuit : ;; (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)), direction(c), inline-imm(index(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 @@ -1934,14 +1906,14 @@ defn infer-types (c:Circuit) -> Circuit : ;; 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(direction(acc) == OUTPUT) +;; ;; 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(direction(acc) == INPUT) +;; ;; 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"]) @@ -1960,7 +1932,7 @@ defn infer-types (c:Circuit) -> Circuit : ;; val portz = HashTable<Symbol, Port>(symbol-hash) ;; for port in ports(m) do : ;; portz[name(port)] = port -;; if direction(port) == OUTPUT : +;; if gender(port) == OUTPUT : ;; outs[name(port)] = port ;; else if name(port) == `reset : ;; print-all(o, [name(m) "::reset = rst\n"]) @@ -1991,7 +1963,7 @@ public defn run-passes (c: Circuit, p: List<Char>) : if contains(p,'c') : do-stage("Make Explicit Reset", make-explicit-reset) if contains(p,'d') : do-stage("Initialize Registers", initialize-registers) if contains(p,'e') : do-stage("Infer Types", infer-types) - ;if contains(p,'f') : do-stage("Infer Directions", infer-directions) + ;if contains(p,'f') : do-stage("Infer Genders", infer-genders) ;if contains(p,'g') : do-stage("Expand Accessors", expand-accessors) ;if contains(p,'h') : do-stage("Flatten Bundles", flatten-bundles) ;if contains(p,'i') : do-stage("Expand Bundles", expand-bundles) |
