diff options
| author | azidar | 2015-04-08 17:31:07 -0700 |
|---|---|---|
| committer | azidar | 2015-04-08 17:31:07 -0700 |
| commit | 371afc84d857f1422451d8ec2972d7b98588739b (patch) | |
| tree | d0d5c44c422502c7a7d3bfbad27950bc2f93e8f0 | |
| parent | e5b9f6ec710e8573ce262330731bebc7524296e5 (diff) | |
Fixed bug in lowering that incorrectly determined genders when subfielded
| -rw-r--r-- | src/main/stanza/passes.stanza | 135 | ||||
| -rw-r--r-- | test/passes/expand-connect-indexed/bundle-vecs.fir | 20 | ||||
| -rw-r--r-- | test/passes/jacktest/bundlewire.fir | 4 | ||||
| -rw-r--r-- | test/passes/lower-to-ground/accessor.fir | 12 | ||||
| -rw-r--r-- | test/passes/lower-to-ground/bundle-vecs.fir | 24 | ||||
| -rw-r--r-- | test/passes/lower-to-ground/bundle.fir | 56 | ||||
| -rw-r--r-- | test/passes/lower-to-ground/nested-vec.fir | 28 | ||||
| -rw-r--r-- | test/passes/lower-to-ground/register.fir | 12 | ||||
| -rw-r--r-- | test/passes/resolve-genders/bigenders.fir | 13 |
9 files changed, 166 insertions, 138 deletions
diff --git a/src/main/stanza/passes.stanza b/src/main/stanza/passes.stanza index 82187b7e..964ede74 100644 --- a/src/main/stanza/passes.stanza +++ b/src/main/stanza/passes.stanza @@ -585,6 +585,16 @@ 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 bundle-field-flip (n:Symbol,t:Type) -> Flip : + match(t) : + (b:BundleType) : + val field = for f in fields(b) find : + name(f) == n + match(field): + (f:Field) : flip(f) + (f) : error(string-join(["Could not find " n " in bundle "])) + (b) : error(string-join(["Accessing subfield " n " on a non-Bundle type."])) + defn resolve-genders (c:Circuit) : defn resolve-module (m:Module, genders:HashTable<Symbol,Gender>) -> Module : var done? = true @@ -641,16 +651,6 @@ defn resolve-genders (c:Circuit) : (s) : map(resolve-stmt,s) defn resolve-expr (e:Expression,desired:Gender) -> Expression : - defn bundle-field-flip (n:Symbol,t:Type) -> Flip : - match(t) : - (b:BundleType) : - val field = for f in fields(b) find : - name(f) == n - match(field): - (f:Field) : flip(f) - (f) : error(string-join(["Could not find " n " in bundle "])) - (b) : error(string-join(["Accessing subfield " n " on a non-Bundle type."])) - match(e) : (e:WRef) : val gender = get-gender(name(e),desired) @@ -771,6 +771,19 @@ defn lower (body:Stmt, table:HashTable<Symbol,List<KeyValue<Expression,Flip>>>) key(x) == y if contains? : ctable[y] = append(ctable[y],list(k)) else : ctable[y] = list(k) + defn is-instance (e:Expression) -> True|False : + match(e) : + (e:WRef) : kind(e) == InstanceKind() + (e) : false + defn calc-gender (g:Gender, e:Expression) -> Gender : + match(e) : + (e:WRef) : gender(e) + (e:WRegInit) : gender(e) + (e:WSubfield) : + if is-instance(exp(e)) : gender(e) + else : calc-gender(bundle-field-flip(name(e),type(exp(e))) * g,exp(e)) + (e:WIndex) : gender(e) + (e) : g match(s) : (s:DefWire) : Begin{_} $ @@ -787,8 +800,8 @@ defn lower (body:Stmt, table:HashTable<Symbol,List<KeyValue<Expression,Flip>>>) lower-stmt(s*) (s:Connect) : Begin{_} $ for (l in expand-expr(loc(s)), r in expand-expr(exp(s))) map : - val lgender = FEMALE * value(l) - val rgender = MALE * value(r) + val lgender = calc-gender(FEMALE,loc(s)) * value(l) + val rgender = calc-gender(MALE,exp(s)) * value(r) switch fn ([x,y]) : lgender == x and rgender == y : [FEMALE,MALE] : Connect(key(l),key(r)) [MALE,FEMALE] : Connect(key(r),key(l)) @@ -802,10 +815,11 @@ defn lower (body:Stmt, table:HashTable<Symbol,List<KeyValue<Expression,Flip>>>) add-to-table(name(key(l) as WRef),r,ctable) val ls = for l in expand-expr(loc(s)) map : - val lgender = FEMALE * value(l) + val cg = calc-gender(FEMALE,loc(s)) + val lgender = cg * value(l) var rgender = BI-GENDER val exps = for e in ctable[name(key(l) as WRef)] map : - rgender = rgender + (MALE * value(e)) + rgender = rgender + (swap(cg) * value(e)) key(e) switch fn ([x,y]) : lgender == x and rgender == y : [FEMALE,MALE] : ConnectFromIndexed(index(s),key(l),exps) @@ -818,10 +832,11 @@ defn lower (body:Stmt, table:HashTable<Symbol,List<KeyValue<Expression,Flip>>>) val ls = for r in expand-expr(exp(s)) map : val n = name(key(r) as WRef) - val rgender = MALE * value(r) + val cg = calc-gender(MALE,exp(s)) + val rgender = cg * value(r) var lgender = BI-GENDER val locs = for l in ctable[n] map : - lgender = lgender + (FEMALE * value(l)) + lgender = lgender + (swap(cg) * value(l)) key(l) switch fn ([x,y]) : lgender == x and rgender == y : [FEMALE,MALE] : ConnectToIndexed(index(s),locs,key(r)) @@ -1406,16 +1421,16 @@ defn expand-whens (c:Circuit) -> Circuit : ; Finally, you replace all width variables with the solved ; widths. -;defstruct VarWidth <: Width : -; name: Symbol -; -;defmethod print (o:OutputStream, w:VarWidth) : -; print(o,name(w)) -; -;;defn remove-var-widths (c:Circuit) -> Circuit : -; -;;defn solve-constraints (l:List<WCon>) -> HashTable<Symbol,Int> : -; +defstruct VarWidth <: Width : + name: Symbol + +defmethod print (o:OutputStream, w:VarWidth) : + print(o,name(w)) + +;defn remove-var-widths (c:Circuit) -> Circuit : + +;defn solve-constraints (l:List<WCon>) -> HashTable<Symbol,Int> : + ;defn gen-constraints (m:Module) -> List<WCon> : ; val v = Vector<WCon>() ; val h = HashTable<Symbol,Width>(symbol-hash) @@ -1432,39 +1447,39 @@ defn expand-whens (c:Circuit) -> Circuit : ; add(v,WGeq(w, ; defn gen-constraints (s:Stmt) -> Stmt : ; match(map(gen-constraints,s)) : -; -; -;defn remove-unknown-widths (c:Circuit) -> Circuit : -; defn remove-unknown-widths-wid (w:Width) -> Width : -; match(w) : -; (w:UnknownWidth) : VarWidth(gensym(`w)) -; (w) : w -; defn remove-unknown-widths-type (t:Type) -> Type : -; map{remove-unknown-widths-wid,_} $ -; map(remove-unknown-widths-type,t) -; defn remove-unknown-widths-exp (e:Expression) -> Expression : -; map{remove-unknown-widths-wid,_} $ -; map{remove-unknown-widths-type,_} $ -; map(remove-unknown-widths-exp,e) -; defn remove-unknown-widths-stmt (s:Stmt) -> Stmt : -; map{remove-unknown-widths-type,_} $ -; map{remove-unknown-widths-exp,_} $ -; map(remove-unknown-widths-stmt,s) -; val modules* = for m in modules(c) map : -; Module{name(m),_,body(m)} $ -; for p in ports(m) map : -; Port(name(p),direction(p),remove-unknown-widths-type(type(p))) -; -; val modules** = for m in modules* map : -; Module(name(m),ports(m),remove-unknown-widths-stmt(body(m))) -; Circuit(modules**,main(c)) -; -;defn infer-widths (c:Circuit) -> Circuit : -; val c* = remove-unknown-widths(c) -; c* -; ;val l = gen-constraints(c*) -; ;val h = solve-constraints(l) -; ;replace-var-widths(c*,h) + + +defn remove-unknown-widths (c:Circuit) -> Circuit : + defn remove-unknown-widths-wid (w:Width) -> Width : + match(w) : + (w:UnknownWidth) : VarWidth(gensym(`w)) + (w) : w + defn remove-unknown-widths-type (t:Type) -> Type : + map{remove-unknown-widths-wid,_} $ + map(remove-unknown-widths-type,t) + defn remove-unknown-widths-exp (e:Expression) -> Expression : + map{remove-unknown-widths-wid,_} $ + map{remove-unknown-widths-type,_} $ + map(remove-unknown-widths-exp,e) + defn remove-unknown-widths-stmt (s:Stmt) -> Stmt : + map{remove-unknown-widths-type,_} $ + map{remove-unknown-widths-exp,_} $ + map(remove-unknown-widths-stmt,s) + val modules* = for m in modules(c) map : + Module{name(m),_,body(m)} $ + for p in ports(m) map : + Port(name(p),direction(p),remove-unknown-widths-type(type(p))) + + val modules** = for m in modules* map : + Module(name(m),ports(m),remove-unknown-widths-stmt(body(m))) + Circuit(modules**,main(c)) + +defn infer-widths (c:Circuit) -> Circuit : + val c* = remove-unknown-widths(c) + c* + ;val l = gen-constraints(c*) + ;val h = solve-constraints(l) + ;replace-var-widths(c*,h) @@ -2298,7 +2313,7 @@ public defn run-passes (c: Circuit, p: List<Char>) : if contains(p,'i') : do-stage("Expand Indexed Connects", expand-connect-indexed) 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,'k') : do-stage("Infer Widths", infer-widths) ;if contains(p,'n') : do-stage("Pad Widths", pad-widths) ;if contains(p,'o') : do-stage("Inline Instances", inline-instances) diff --git a/test/passes/expand-connect-indexed/bundle-vecs.fir b/test/passes/expand-connect-indexed/bundle-vecs.fir index ce14c7ba..f3754a32 100644 --- a/test/passes/expand-connect-indexed/bundle-vecs.fir +++ b/test/passes/expand-connect-indexed/bundle-vecs.fir @@ -7,20 +7,20 @@ circuit top : wire j : UInt wire a : { x : UInt(32), flip y : UInt(32) }[2] - ; CHECK: wire a#0#x : UInt(32) - ; CHECK: wire a#0#y : UInt(32) - ; CHECK: wire a#1#x : UInt(32) - ; CHECK: wire a#1#y : UInt(32) + ; CHECK: wire a$0$x : UInt(32) + ; CHECK: wire a$0$y : UInt(32) + ; CHECK: wire a$1$x : UInt(32) + ; CHECK: wire a$1$y : UInt(32) accessor b = a[i] - ; CHECK: wire b#x : UInt(32) - ; CHECK: wire b#y : UInt(32) - ; CHECK: b#x := a#0#x + ; CHECK: wire b$x : UInt(32) + ; CHECK: wire b$y : UInt(32) + ; CHECK: b$x := a$0$x ; CHECK: when equal-uu(i, UInt(1)) : - ; CHECK: b#x := a#1#x - ; CHECK: a#0#y := b#y + ; CHECK: b$x := a$1$x + ; CHECK: a$0$y := b$y ; CHECK: when equal-uu(i, UInt(1)) : - ; CHECK: a#1#y := b#y + ; CHECK: a$1$y := b$y j := b ; CHECK: Finished Expand Indexed Connects diff --git a/test/passes/jacktest/bundlewire.fir b/test/passes/jacktest/bundlewire.fir index 0d0f0377..0356597e 100644 --- a/test/passes/jacktest/bundlewire.fir +++ b/test/passes/jacktest/bundlewire.fir @@ -1,10 +1,10 @@ -; RUN: firrtl %s abcefghipj c | tee %s.out | FileCheck %s +; RUN: firrtl %s abcefghipj cg | tee %s.out | FileCheck %s ; CHECK: Expand Whens circuit BundleWire : module BundleWire : - output in : { y : UInt(32), x : UInt(32) } + input in : { y : UInt(32), x : UInt(32) } output outs : { y : UInt(32), x : UInt(32) }[4] wire coords : { y : UInt(32), x : UInt(32) }[4] diff --git a/test/passes/lower-to-ground/accessor.fir b/test/passes/lower-to-ground/accessor.fir index e54868bc..8c12137f 100644 --- a/test/passes/lower-to-ground/accessor.fir +++ b/test/passes/lower-to-ground/accessor.fir @@ -7,19 +7,19 @@ circuit top : wire j : UInt(32) wire a : UInt(32)[4] - ; CHECK: wire a#0 : UInt(32) - ; CHECK: wire a#1 : UInt(32) - ; CHECK: wire a#2 : UInt(32) - ; CHECK: wire a#3 : UInt(32) + ; CHECK: wire a$0 : UInt(32) + ; CHECK: wire a$1 : UInt(32) + ; CHECK: wire a$2 : UInt(32) + ; CHECK: wire a$3 : UInt(32) accessor b = a[i] ; CHECK: wire b : UInt(32) - ; CHECK: b := (a#0 a#1 a#2 a#3)[i] + ; CHECK: b := (a$0 a$1 a$2 a$3)[i] j := b accessor c = a[i] ; CHECK: wire c : UInt(32) - ; CHECK: (a#0 a#1 a#2 a#3)[i] := c + ; CHECK: (a$0 a$1 a$2 a$3)[i] := c c := j mem p : UInt(32)[4] diff --git a/test/passes/lower-to-ground/bundle-vecs.fir b/test/passes/lower-to-ground/bundle-vecs.fir index a4ead6ed..f1b25854 100644 --- a/test/passes/lower-to-ground/bundle-vecs.fir +++ b/test/passes/lower-to-ground/bundle-vecs.fir @@ -7,23 +7,23 @@ circuit top : wire j : UInt wire a : { x : UInt(32), flip y : UInt(32) }[2] - ; CHECK: wire a#0#x : UInt(32) - ; CHECK: wire a#0#y : UInt(32) - ; CHECK: wire a#1#x : UInt(32) - ; CHECK: wire a#1#y : UInt(32) + ; CHECK: wire a$0$x : UInt(32) + ; CHECK: wire a$0$y : UInt(32) + ; CHECK: wire a$1$x : UInt(32) + ; CHECK: wire a$1$y : UInt(32) accessor b = a[i] - ; CHECK: wire b#x : UInt(32) - ; CHECK: wire b#y : UInt(32) - ; CHECK: b#x := (a#0#x a#1#x)[i] - ; CHECK: (a#0#y a#1#y)[i] := b#y + ; CHECK: wire b$x : UInt(32) + ; CHECK: wire b$y : UInt(32) + ; CHECK: b$x := (a$0$x a$1$x)[i] + ; CHECK: (a$0$y a$1$y)[i] := b$y j := b accessor c = a[i] - ; CHECK: wire c#x : UInt(32) - ; CHECK: wire c#y : UInt(32) - ; CHECK: (a#0#x a#1#x)[i] := c#x - ; CHECK: c#y := (a#0#y a#1#y)[i] + ; CHECK: wire c$x : UInt(32) + ; CHECK: wire c$y : UInt(32) + ; CHECK: (a$0$x a$1$x)[i] := c$x + ; CHECK: c$y := (a$0$y a$1$y)[i] c := j diff --git a/test/passes/lower-to-ground/bundle.fir b/test/passes/lower-to-ground/bundle.fir index 990b6b7f..2947eb8f 100644 --- a/test/passes/lower-to-ground/bundle.fir +++ b/test/passes/lower-to-ground/bundle.fir @@ -17,37 +17,37 @@ circuit top : ;CHECK: Lower To Ground ;CHECK: circuit top : ;CHECK: module m : -;CHECK: input a#x : UInt -;CHECK: output a#y : SInt -;CHECK: output b#x : UInt -;CHECK: input b#y : SInt +;CHECK: input a$x : UInt +;CHECK: output a$y : SInt +;CHECK: output b$x : UInt +;CHECK: input b$y : SInt ;CHECK: input reset : UInt(1) ;CHECK: module subtracter : -;CHECK: input c#x#0 : UInt -;CHECK: input c#x#1 : UInt -;CHECK: input c#x#2 : UInt -;CHECK: input c#x#3 : UInt -;CHECK: input c#x#4 : UInt -;CHECK: output c#y#x#0 : UInt -;CHECK: output c#y#x#1 : UInt -;CHECK: output c#y#x#2 : UInt -;CHECK: input c#y#y : SInt +;CHECK: input c$x$0 : UInt +;CHECK: input c$x$1 : UInt +;CHECK: input c$x$2 : UInt +;CHECK: input c$x$3 : UInt +;CHECK: input c$x$4 : UInt +;CHECK: output c$y$x$0 : UInt +;CHECK: output c$y$x$1 : UInt +;CHECK: output c$y$x$2 : UInt +;CHECK: input c$y$y : SInt ;CHECK: input reset : UInt(1) -;CHECK: wire a#x : UInt -;CHECK: wire a#y : SInt -;CHECK: wire b#x : UInt -;CHECK: wire b#y : SInt -;CHECK: a#x := b#x -;CHECK: b#y := a#y +;CHECK: wire a$x : UInt +;CHECK: wire a$y : SInt +;CHECK: wire b$x : UInt +;CHECK: wire b$y : SInt +;CHECK: a$x := b$x +;CHECK: b$y := a$y ;CHECK: inst i of m ;CHECK: i.reset := reset -;CHECK: i.a#x := a#x -;CHECK: a#y := i.a#y -;CHECK: b#x := i.b#x -;CHECK: i.b#y := b#y -;CHECK: wire d#0 : UInt -;CHECK: wire d#1 : UInt -;CHECK: wire d#2 : UInt -;CHECK: wire d#3 : UInt -;CHECK: wire d#4 : UInt +;CHECK: i.a$x := a$x +;CHECK: a$y := i.a$y +;CHECK: b$x := i.b$x +;CHECK: i.b$y := b$y +;CHECK: wire d$0 : UInt +;CHECK: wire d$1 : UInt +;CHECK: wire d$2 : UInt +;CHECK: wire d$3 : UInt +;CHECK: wire d$4 : UInt ;CHECK: Finished Lower To Ground diff --git a/test/passes/lower-to-ground/nested-vec.fir b/test/passes/lower-to-ground/nested-vec.fir index 8eafb8e8..4ab3ba9b 100644 --- a/test/passes/lower-to-ground/nested-vec.fir +++ b/test/passes/lower-to-ground/nested-vec.fir @@ -7,27 +7,27 @@ circuit top : wire j : { x : UInt(32), flip y : UInt(32) } wire a : { x : UInt(32), flip y : UInt(32) }[2] - ; CHECK: wire a#0#x : UInt(32) - ; CHECK: wire a#0#y : UInt(32) - ; CHECK: wire a#1#x : UInt(32) - ; CHECK: wire a#1#y : UInt(32) + ; CHECK: wire a$0$x : UInt(32) + ; CHECK: wire a$0$y : UInt(32) + ; CHECK: wire a$1$x : UInt(32) + ; CHECK: wire a$1$y : UInt(32) accessor b = a[i] - ; CHECK: wire b#x : UInt(32) - ; CHECK: wire b#y : UInt(32) - ; CHECK: b#x := (a#0#x a#1#x)[i] - ; CHECK: (a#0#y a#1#y)[i] := b#y + ; CHECK: wire b$x : UInt(32) + ; CHECK: wire b$y : UInt(32) + ; CHECK: b$x := (a$0$x a$1$x)[i] + ; CHECK: (a$0$y a$1$y)[i] := b$y j := b mem m : { x : UInt(32), flip y : UInt(32) }[2] - ; CHECK: mem m#x : UInt(32)[2] - ; CHECK: mem m#y : UInt(32)[2] + ; CHECK: mem m$x : UInt(32)[2] + ; CHECK: mem m$y : UInt(32)[2] accessor c = m[i] ; MALE - ; CHECK: accessor c#x = m#x[i] - ; CHECK: accessor c#y = m#y[i] - ; CHECK: c#x := j#x - ; CHECK: j#y := c#y + ; CHECK: accessor c$x = m$x[i] + ; CHECK: accessor c$y = m$y[i] + ; CHECK: c$x := j$x + ; CHECK: j$y := c$y c := j ; CHECK: Finished Lower To Ground diff --git a/test/passes/lower-to-ground/register.fir b/test/passes/lower-to-ground/register.fir index f270bacb..219996fb 100644 --- a/test/passes/lower-to-ground/register.fir +++ b/test/passes/lower-to-ground/register.fir @@ -11,11 +11,11 @@ wire q : { x : UInt, flip y : SInt } r1.init := q - ; CHECK: reg r1#x : UInt - ; CHECK: reg r1#y : SInt - ; CHECK: wire q#x : UInt - ; CHECK: wire q#y : SInt - ; CHECK: r1#x.init := q#x - ; CHECK: q#y := r1#y.init + ; CHECK: reg r1$x : UInt + ; CHECK: reg r1$y : SInt + ; CHECK: wire q$x : UInt + ; CHECK: wire q$y : SInt + ; CHECK: r1$x.init := q$x + ; CHECK: q$y := r1$y.init ; CHECK: Finished Lower To Ground diff --git a/test/passes/resolve-genders/bigenders.fir b/test/passes/resolve-genders/bigenders.fir new file mode 100644 index 00000000..4a516924 --- /dev/null +++ b/test/passes/resolve-genders/bigenders.fir @@ -0,0 +1,13 @@ +; RUN: firrtl %s abcdefghipj cg | tee %s.out | FileCheck %s + +;CHECK: Resolve Genders +circuit top : + module M : + input i : UInt(10) + output o : UInt(10) + wire w : {x : UInt(10), flip y : UInt(10)} + w.x := i + w.y := i + o := w.x + o := w.y +; CHECK: Finished Resolve Genders |
