diff options
| author | azidar | 2015-03-05 17:16:46 -0800 |
|---|---|---|
| committer | azidar | 2015-03-05 17:16:46 -0800 |
| commit | 0f3a31df12584207204054215867d84890a98a62 (patch) | |
| tree | 7ee995f901cc95520ec6dd37474264c915bbc99c /src | |
| parent | b06eba574c7a67df062d50ea03ca7d7a9524c2a3 (diff) | |
Finished part of infer gender, tests not committed
Diffstat (limited to 'src')
| -rw-r--r-- | src/main/stanza/firrtl-ir.stanza | 6 | ||||
| -rw-r--r-- | src/main/stanza/ir-parser.stanza | 10 | ||||
| -rw-r--r-- | src/main/stanza/ir-utils.stanza | 20 | ||||
| -rw-r--r-- | src/main/stanza/passes.stanza | 233 |
4 files changed, 170 insertions, 99 deletions
diff --git a/src/main/stanza/firrtl-ir.stanza b/src/main/stanza/firrtl-ir.stanza index 6cc5cc48..46235bd6 100644 --- a/src/main/stanza/firrtl-ir.stanza +++ b/src/main/stanza/firrtl-ir.stanza @@ -6,9 +6,11 @@ public definterface Direction public val INPUT = new Direction public val OUTPUT = new Direction -definterface Gender +public definterface Gender public val MALE = new Gender public val FEMALE = new Gender +public val UNKNOWN-GENDER = new Gender +public val BI-GENDER = new Gender public definterface Width @@ -206,7 +208,7 @@ public defstruct UIntType <: Type : public defstruct SIntType <: Type : width: Width public defstruct BundleType <: Type : - ports: List<Field> + fields: List<Field> public defstruct VectorType <: Type : type: Type size: Int diff --git a/src/main/stanza/ir-parser.stanza b/src/main/stanza/ir-parser.stanza index f52abf13..0334bca2 100644 --- a/src/main/stanza/ir-parser.stanza +++ b/src/main/stanza/ir-parser.stanza @@ -87,6 +87,12 @@ rd.defsyntax firrtl : (module ?name:#symbol : (?ports:#port ... ?body:#comm ...)) : Module(ut(name), ports, Begin(body)) + defrule field : + (male ?name:#symbol : ?type:#type) : + Field(ut(name), MALE, type) + (female ?name:#symbol : ?type:#type) : + Field(ut(name), FEMALE, type) + defrule port : (input ?name:#symbol : ?type:#type) : Port(ut(name), INPUT, type) @@ -104,8 +110,8 @@ rd.defsyntax firrtl : SIntType(IntWidth(ut(width))) (SInt) : SIntType(UnknownWidth()) - ({?ports:#port ...}) : - BundleType(ports) + ({?fields:#field ...}) : + BundleType(fields) defrule comm : (wire ?name:#symbol : ?type:#type) : diff --git a/src/main/stanza/ir-utils.stanza b/src/main/stanza/ir-utils.stanza index 298dd6a9..74e74679 100644 --- a/src/main/stanza/ir-utils.stanza +++ b/src/main/stanza/ir-utils.stanza @@ -5,9 +5,17 @@ defpackage firrtl.ir-utils : ;============== DEBUG STUFF ============================= -public defmulti print-debug (o:OutputStream, e:Expression|Stmt|Type|Element|Port) -> False +public defmulti print-debug (o:OutputStream, e:Expression|Stmt|Type|Element|Port|Field) -> False ;============== PRINTERS =================================== +defmethod print (o:OutputStream, g:Gender) : + print{o, _} $ + switch {g == _} : + MALE : "male" + FEMALE: "female" + BI-GENDER : "bi" + UNKNOWN-GENDER: "unknown" + defmethod print (o:OutputStream, d:Direction) : print{o, _} $ switch {d == _} : @@ -203,12 +211,16 @@ defmethod print (o:OutputStream, t:Type) : (w) : print-all(o, ["SInt(" width(t) ")"]) (t:BundleType) : print(o, "{") - print-all(o, join(ports(t), ", ")) + print-all(o, join(fields(t), ", ")) print(o, "}") (t:VectorType) : print-all(o, [type(t) "[" size(t) "]"]) print-debug(o,t) +defmethod print (o:OutputStream, f:Field) : + print-all(o, [gender(f) " " name(f) " : " type(f)]) + print-debug(o,f) + defmethod print (o:OutputStream, p:Port) : print-all(o, [direction(p) " " name(p) " : " type(p)]) print-debug(o,p) @@ -252,8 +264,8 @@ public defn map<?T> (f: Type -> Type, t:?T&Type) -> T : match(t) : (t:T&BundleType) : BundleType $ - for p in ports(t) map : - Port(name(p), direction(p), f(type(p))) + for p in fields(t) map : + Field(name(p), gender(p), f(type(p))) (t:T&VectorType) : VectorType(f(type(t)), size(t)) (t) : diff --git a/src/main/stanza/passes.stanza b/src/main/stanza/passes.stanza index 02997ba1..a0cf1aa3 100644 --- a/src/main/stanza/passes.stanza +++ b/src/main/stanza/passes.stanza @@ -25,26 +25,24 @@ 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 - gender: Gender [multi => false] + gender: Gender defstruct WSubfield <: Expression : exp: Expression name: Symbol type: Type [multi => false] - gender: Gender [multi => false] + gender: Gender defstruct WIndex <: Expression : exp: Expression value: Int type: Type [multi => false] - gender: Gender [multi => false] + gender: Gender defstruct WDefAccessor <: Stmt : name: Symbol @@ -53,6 +51,22 @@ defstruct WDefAccessor <: Stmt : gender: Gender ;================ WORKING IR UTILS ========================= + +defn times (f1:Gender,f2:Gender) -> Gender : + if (f1 == UNKNOWN-GENDER) : UNKNOWN-GENDER + else if (f2 == UNKNOWN-GENDER) : UNKNOWN-GENDER + else if (f1 == MALE) : f2 + else if (f2 == MALE) : f1 + else if (f1 == FEMALE and f2 == FEMALE) : MALE + else if (f1 == BI-GENDER) : f2 + else if (f2 == BI-GENDER) : f1 + else : UNKNOWN-GENDER + +defn to-field (p:Port) -> Field : + if direction(p) == OUTPUT : Field(name(p),FEMALE,type(p)) + else if direction(p) == INPUT : Field(name(p),MALE,type(p)) + else : Field(name(p),UNKNOWN-GENDER,type(p)) + ;============== DEBUG STUFF ============================= public var PRINT-TYPES : True|False = false public var PRINT-KINDS : True|False = false @@ -72,26 +86,27 @@ defmethod print (o:OutputStream, k:Kind) : (k:InstanceKind) : "inst" (k:StructuralMemKind) : "smem" -defn hasWidth (e:Expression|Stmt|Type|Element|Port) : - e typeof UIntType|SIntType|UIntValue|SIntValue +defn hasGender (e:Expression|Stmt|Type|Element|Port|Field) : + e typeof Field|WRef|WSubfield|WIndex|WDefAccessor -defn hasWidth (e:Expression|Stmt|Type|Element|Port) : +defn hasWidth (e:Expression|Stmt|Type|Element|Port|Field) : e typeof UIntType|SIntType|UIntValue|SIntValue -defn hasType (e:Expression|Stmt|Type|Element|Port) : +defn hasType (e:Expression|Stmt|Type|Element|Port|Field) : e typeof Ref|Subfield|Index|DoPrim|ReadPort|WRef|WSubfield |WIndex|DefWire|DefRegister|DefMemory|Register - |Memory|Node|Instance|VectorType|Port + |Memory|Node|Instance|VectorType|Port|Field -defn hasKind (e:Expression|Stmt|Type|Element|Port) : +defn hasKind (e:Expression|Stmt|Type|Element|Port|Field) : e typeof WRef -defn any-debug? (e:Expression|Stmt|Type|Element|Port) : +defn any-debug? (e:Expression|Stmt|Type|Element|Port|Field) : + (hasGender(e) and PRINT-GENDERS) or (hasType(e) and PRINT-TYPES) or (hasWidth(e) and PRINT-WIDTHS) or (hasKind(e) and PRINT-KINDS) -defmethod print-debug (o:OutputStream, e:Expression|Stmt|Type|Element|Port) : +defmethod print-debug (o:OutputStream, e:Expression|Stmt|Type|Element|Port|Field) : defn wipe-width (t:Type) -> Type : match(t) : (t:UIntType) : UIntType(UnknownWidth()) @@ -102,6 +117,7 @@ defmethod print-debug (o:OutputStream, e:Expression|Stmt|Type|Element|Port) : if PRINT-KINDS and hasKind(e) : print-all(o,["<k:" kind(e as ?) ">"]) if PRINT-TYPES and hasType(e) : print-all(o,["<t:" wipe-width(type(e as ?)) ">"]) if PRINT-WIDTHS and hasWidth(e): print-all(o,["<w:" width(e as ?) ">"]) + if PRINT-GENDERS and hasGender(e): print-all(o,["<g:" gender(e as ?) ">"]) defmethod print (o:OutputStream, e:WRef) : print(o,name(e)) @@ -116,22 +132,22 @@ defmethod print (o:OutputStream, e:WIndex) : print-debug(o,e as ?) defmethod print (o:OutputStream, s:WDefAccessor) : - print-all(o,[dir(s) " accessor " name(s) " = " source(s) "[" index(s) "]"]) + print-all(o,["accessor " name(s) " = " source(s) "[" index(s) "]"]) print-debug(o,s) defmethod map (f: Expression -> Expression, e: WSubfield) : - WSubfield(f(exp(e)), name(e), type(e), dir(e)) + WSubfield(f(exp(e)), name(e), type(e), gender(e)) defmethod map (f: Expression -> Expression, e: WIndex) : - WIndex(f(exp(e)), value(e), type(e), dir(e)) + WIndex(f(exp(e)), value(e), type(e), gender(e)) defmethod map (f: Expression -> Expression, c:WDefAccessor) : - WDefAccessor(name(c), f(source(c)), f(index(c)), dir(c)) + WDefAccessor(name(c), f(source(c)), f(index(c)), gender(c)) ;================= DIRECTION =============================== -defmulti dir (e:Expression) -> Gender -defmethod dir (e:Expression) : - OUTPUT +;defmulti gender (e:Expression) -> Gender +;defmethod gender (e:Expression) : + ;MALE ;================= Bring to Working IR ======================== ; Returns a new Circuit with Refs, Subfields, Indexes and DefAccessors @@ -169,7 +185,7 @@ defn resolve-kinds (c:Circuit) : defn resolve-expr (e:Expression) -> Expression : match(e) : - (e:WRef) : WRef(name(e),type(e),kinds[name(e)],dir(e)) + (e:WRef) : WRef(name(e),type(e),kinds[name(e)],gender(e)) (e) : map(resolve-expr,e) resolve-stmt(body) @@ -241,7 +257,7 @@ defn make-explicit-reset (c:Circuit) : var ports! = ports(m) if not contains?(explicit-reset,name(m)) : - ports! = append(ports(m),list(Port(`reset,MALE,UIntType(IntWidth(1))))) + ports! = append(ports(m),list(Port(`reset,INPUT,UIntType(IntWidth(1))))) val body! = route-reset(body(m)) Module(name(m),ports!,body!) @@ -471,7 +487,7 @@ defn get-primop-rettype (e:DoPrim) -> Type : BITS-SELECT-OP : u() defn type (m:Module) -> Type : - BundleType(ports(m)) + BundleType(for p in ports(m) map : to-field(p)) defn get-type (b:Symbol,l:List<KeyValue<Symbol,Type>>) -> Type : val ma = for kv in l find : b == key(kv) @@ -484,8 +500,8 @@ defn get-type (b:Symbol,l:List<KeyValue<Symbol,Type>>) -> Type : defn bundle-field-type (v:Type,s:Symbol) -> Type : match(v) : (v:BundleType) : - val ft = for p in ports(v) find : name(p) == s - if ft != false : type(ft as Port) + val ft = for p in fields(v) find : name(p) == s + if ft != false : type(ft as Field) else : UnknownType() (v) : UnknownType() @@ -497,9 +513,9 @@ defn get-vector-subtype (v:Type) -> Type : 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: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:WRef) : WRef(name(e), get-type(name(e),l),kind(e),gender(e)) + (e:WSubfield) : WSubfield(exp(e),name(e), bundle-field-type(type(exp(e)),name(e)),gender(e)) + (e:WIndex) : WIndex(exp(e),value(e), get-vector-subtype(type(exp(e))),gender(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)))) (e:UIntValue|SIntValue|Null) : e @@ -538,14 +554,14 @@ defn infer-types (m:Module, l:List<KeyValue<Symbol,Type>>) -> Module : defn infer-types (c:Circuit) -> Circuit : val l = for m in modules(c) map : - name(m) => BundleType(ports(m)) + name(m) => BundleType(map(to-field,ports(m))) ;println-all(l) Circuit{ _, main(c) } $ for m in modules(c) map : infer-types(m,l) -;============= INFER DIRECTIONS ============================ +;============= RESOLVE ACCESSOR GENDER ============================ ; 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 @@ -557,81 +573,116 @@ defn infer-types (c:Circuit) -> Circuit : ; 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-accessor-genders (c:Circuit) : + defn resolve (body:Stmt, genders:HashTable<Symbol,Gender>) : + println(genders) 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>) : + match(map(resolve-expr,s)) : + (s:WDefAccessor) : + println(genders[name(s)]) + WDefAccessor(name(s),source(s),index(s),genders[name(s)]) + (s) : map(resolve-stmt,s) + defn resolve-expr (e:Expression) -> Expression : + match(map(resolve-expr,e)) : + (e:WRef) : WRef(name(e),type(e),kind(e),genders[name(e)]) + (e:WSubfield) : + val field = for f in fields(type(e) as BundleType) find : + name(f) == name(e) + find-expr-gender(exp(e), gender(field as Field) * desired) * gender(field as Field) + (e:WIndex) : find-expr-gender(exp(e),desired) + (e:WSubfield) : WSubfield(exp(e),name(e),type(e),genders[name(e)]) + (e:WIndex) : WIndex(exp(e),value(e),type(e)[name(e)]) + (e) : e + resolve-stmt(body) + + defn find-module (m:Module, genders:HashTable<Symbol,Gender>) -> HashTable<Symbol,Gender> : + if find-iter(m,genders) : genders + else : find-module(m,genders) + defn find-iter (m:Module, genders:HashTable<Symbol,Gender>) -> True|False : + var done? = true + println(genders) + defn try-add (n:Symbol,g:Gender) -> Gender : + val entry = for kv in genders find : + key(kv) == n + label<Gender> myret : + if entry == false : + genders[n] = g + done? = false + myret(g) + else : + val value = value(entry as KeyValue<Symbol,Gender>) + if value == UNKNOWN-GENDER and g == UNKNOWN-GENDER : myret(g) + if value != UNKNOWN-GENDER and g == UNKNOWN-GENDER : myret(value) + if value == UNKNOWN-GENDER and g != UNKNOWN-GENDER : + genders[n] = g + done? = false + myret(g) + if value != UNKNOWN-GENDER and g != UNKNOWN-GENDER : myret(value) + UNKNOWN-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 + match(s) : + (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 + (s:DefNode) : + try-add(name(s),find-expr-gender(value(s),UNKNOWN-GENDER)) + (s:WDefAccessor) : + find-expr-gender(index(s),MALE) + val sourcegender = find-expr-gender(source(s),try-add(name(s),UNKNOWN-GENDER)) + val mygender = try-add(name(s),sourcegender) + println-all(["For " name(s) " got " mygender]) + mygender + (s:Connect) : + find-expr-gender(loc(s),FEMALE) + find-expr-gender(exp(s),MALE) + (s:Conditionally) : + find-expr-gender(pred(s),MALE) + (s) : s map(find-stmt,s) - kinds[name(m)] = ModuleKind() + defn find-expr-gender (e:Expression,desired:Gender) -> Gender : + match(e) : + (e:WRef) : + val added = try-add(name(e),desired) + if added == BI-GENDER : + desired + else : added + (e:WSubfield) : + val field = for f in fields(type(e) as BundleType) find : + name(f) == name(e) + find-expr-gender(exp(e), gender(field as Field) * desired) * gender(field as Field) + (e:WIndex) : find-expr-gender(exp(e),desired) + (e:UIntValue) : MALE + (e:SIntValue) : MALE + (e:DoPrim) : MALE + (e:ReadPort) : MALE + (e:Null) : MALE + (e) : MALE + for p in ports(m) do : - kinds[name(p)] = PortKind() + genders[name(p)] = gender(to-field(p)) find-stmt(body(m)) + done? defn resolve-genders (m:Module, c:Circuit) -> Module : - val genders = HashTable<Symbol,Genders>(symbol-hash) + val genders = HashTable<Symbol,Gender>(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) + genders[name(m)] = FEMALE ;; TODO Should I add this? + find-module(m,genders) + val body* = resolve(body(m),genders) + Module(name(m),ports(m),body*) 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 @@ -1963,7 +2014,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 Genders", infer-genders) + if contains(p,'f') : do-stage("Resolve Accessor Genders", resolve-accessor-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) |
