aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorazidar2015-04-08 17:31:07 -0700
committerazidar2015-04-08 17:31:07 -0700
commit371afc84d857f1422451d8ec2972d7b98588739b (patch)
treed0d5c44c422502c7a7d3bfbad27950bc2f93e8f0
parente5b9f6ec710e8573ce262330731bebc7524296e5 (diff)
Fixed bug in lowering that incorrectly determined genders when subfielded
-rw-r--r--src/main/stanza/passes.stanza135
-rw-r--r--test/passes/expand-connect-indexed/bundle-vecs.fir20
-rw-r--r--test/passes/jacktest/bundlewire.fir4
-rw-r--r--test/passes/lower-to-ground/accessor.fir12
-rw-r--r--test/passes/lower-to-ground/bundle-vecs.fir24
-rw-r--r--test/passes/lower-to-ground/bundle.fir56
-rw-r--r--test/passes/lower-to-ground/nested-vec.fir28
-rw-r--r--test/passes/lower-to-ground/register.fir12
-rw-r--r--test/passes/resolve-genders/bigenders.fir13
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