diff options
| -rw-r--r-- | Makefile | 14 | ||||
| -rw-r--r-- | TODO | 28 | ||||
| -rw-r--r-- | notes/notes.03.16.15.txt | 24 | ||||
| -rw-r--r-- | notes/notes.03.18.15.txt | 52 | ||||
| -rw-r--r-- | notes/stanza-cheatsheet.txt | 8 | ||||
| -rw-r--r-- | src/main/stanza/passes.stanza | 326 | ||||
| -rw-r--r-- | test/passes/expand-accessors/accessor-mem.fir | 12 | ||||
| -rw-r--r-- | test/passes/expand-accessors/accessor-vec.fir | 20 | ||||
| -rw-r--r-- | test/passes/expand-accessors/one-when.fir | 20 | ||||
| -rw-r--r-- | test/passes/expand-accessors/two-when.fir | 57 | ||||
| -rw-r--r-- | test/passes/expand-whens/one-when.fir | 15 | ||||
| -rw-r--r-- | test/passes/expand-whens/two-when.fir | 28 | ||||
| -rw-r--r-- | test/passes/lower-to-ground/accessor.fir | 33 | ||||
| -rw-r--r-- | test/passes/lower-to-ground/bundle-vecs.fir | 31 | ||||
| -rw-r--r-- | test/passes/lower-to-ground/bundle.fir | 53 | ||||
| -rw-r--r-- | test/passes/lower-to-ground/nested-vec.fir | 34 |
16 files changed, 564 insertions, 191 deletions
@@ -1,10 +1,14 @@ # Installs stanza into /usr/local/bin # TODO Talk to Patrick to fill this in + root_dir ?= $(PWD) test_dir ?= $(root_dir)/test firrtl_dir ?= $(root_dir)/src/main/stanza -all: build check +all-noise: + ${MAKE} all || ${MAKE} fail + +all: build check done install: cd src/lib && unzip stanzam.zip @@ -22,3 +26,11 @@ check: clean: rm -f $(test_dir)/*/*/*.out rm -f $(test_dir)/*/*.out + +done: + say "done" + +fail: + say "fail" + +.PHONY: all install build-deploy build check clean fail succeed @@ -1,10 +1,16 @@ TODO - Figure out how widths propogate for all updated primops - Remove letrec. Add to expressions: Register(input,en), ReadPort(mem,index,enable), WritePort(mem,index,enable) - Add bit-reduce-and etc to primops - Write pass to rename identifiers (alpha-transform) - Add partial bulk connect + Figure out how widths propogate for all updated primops (Adam) + Remove letrec. Add to expressions: Register(input,en), ReadPort(mem,index,enable), WritePort(mem,index,enable) (Patrick) + Add bit-reduce-and etc to primops (Jonathan) + Write pass to rename identifiers (alpha-transform) (Adam) + Add partial bulk connect (Scott, Stephen) + Add FIFOs to the IR (Palmer) + Registers/Memories only have data and enable fields, which can be written/read from. These are set by the front-end. This will probably have to wait (Palmer) + Multi-streams for print statements (Jack) + Consider def female node. (Patrick) + Think about supporting memories (Scott) + Update spec add new field for sequential or combinational add assertions @@ -25,3 +31,15 @@ Tests: Error if declare anything other than module in circuit Error if incorrectly assign stuff, like use = instead of := Error: Node not parsed for stmts + +Male node: +defnode n = e +==> +wire n +n := e + +Female node: +defnode n = e +==> +wire n +e := n diff --git a/notes/notes.03.16.15.txt b/notes/notes.03.16.15.txt new file mode 100644 index 00000000..d017a015 --- /dev/null +++ b/notes/notes.03.16.15.txt @@ -0,0 +1,24 @@ +Why did we remove the letrec? + +Why was it there? A way to express all the enables and input values without the need for the when statement, and also allows you to analyze the graph without worrying about last connect semantics, and allows you to analyze the graph without worrying about compound datatypes, known widths, known genders. + +Now we have a way to do it without this. We introduced the Register expression and read/writeport expressions, which enable you to declare them as a function of their inputs and enables. We expand all datatypes into their ground types. Lastly, we express the graph such that for every wire declaration, we ensure that there is only ever one connect to each wire. + +lowered form and higher form + + +Add FIFOs to the IR - major semantics work. +Write a pass expecting to be used on high firrtl, (in current firrtl it could break because we add new constructs) but is used on low firrtl. + +Front-end will write to special r.enable value that it will assign 1 to whenever r is written (or if a mem, read). + +Registers now have 2 fields, .data and .enable. Declare: +reg r : { pckg : {enable} , valid} +r.data := blah ; which has type {pckg : {enable, valid}} +r.enable := UInt(1) +bleh := r.data +; no enable required + +Memories require enables on both reads and writes. + + diff --git a/notes/notes.03.18.15.txt b/notes/notes.03.18.15.txt new file mode 100644 index 00000000..7fdb1c3b --- /dev/null +++ b/notes/notes.03.18.15.txt @@ -0,0 +1,52 @@ +WHEN EXPANSION + +Goal: +reg r +wire w +when p1 : + w := b + r.init := x + when p2 : + w := c + r := d +r := e + +==> + +1. Remove last connect semantics +2. Remove conditional blocks +3. Eliminate concept of scoping + +Exp | Value +-------------- +r | e +w | mux(p1,mux(p2,c,b),null) +r.init | mux(p1,x,null) + +==> + +Symbolic Value - what can appear in value column +sv = e + | null + | svmux(e,sv1,sv2) + +State: +{ + r => void + r.init => p1 + w => svmux(e,_,_) +} + +==> + +Build two tables, one mapping symbols to symbolic values, and another mapping symbols to declared types + +if w is a wire: +merge {r=>x, w=>y} with {r=>x} under p : {r=>svmux(p,x,x), w=>y} + +if s is a reg: +merge {r=>x,s=>y} with {r=>x} under p : {r=>svmux(p,x,x), s=>svmux(p,y,void)} + + + + diff --git a/notes/stanza-cheatsheet.txt b/notes/stanza-cheatsheet.txt index 09342997..215fafbd 100644 --- a/notes/stanza-cheatsheet.txt +++ b/notes/stanza-cheatsheet.txt @@ -55,3 +55,11 @@ list(a) -> a list(a,b) -> a,b println-all([a b c]) + +to extract values (with correct type-age) from a tuple: +val x = [1 "hi"] +val [a,b] = x +a typeof Int +b typeof String + +to combine symbols: symbol-join diff --git a/src/main/stanza/passes.stanza b/src/main/stanza/passes.stanza index ece7287e..fe048cfb 100644 --- a/src/main/stanza/passes.stanza +++ b/src/main/stanza/passes.stanza @@ -56,6 +56,17 @@ defstruct WDefAccessor <: Stmt : ;================ WORKING IR UTILS ========================= +defn plus (g1:Gender,g2:Gender) -> Gender : + switch fn ([x,y]) : g1 == x and g2 == y : + [FEMALE,MALE] : UNKNOWN-GENDER + [MALE,FEMALE] : UNKNOWN-GENDER + [MALE,MALE] : MALE + [FEMALE,FEMALE] : FEMALE + [BI-GENDER,MALE] : MALE + [BI-GENDER,FEMALE] : FEMALE + [MALE,BI-GENDER] : MALE + [FEMALE,BI-GENDER] : FEMALE + defn swap (g:Gender) -> Gender : switch {_ == g} : UNKNOWN-GENDER : UNKNOWN-GENDER @@ -63,15 +74,32 @@ defn swap (g:Gender) -> Gender : FEMALE : MALE BI-GENDER : BI-GENDER -defn times (g:Gender,flip:Flip) -> Gender : +defn swap (f:Flip) -> Flip : + switch {_ == f} : + DEFAULT : REVERSE + REVERSE : DEFAULT + +defn swap (d:Direction) -> Direction : + switch {_ == d} : + OUTPUT : INPUT + INPUT : OUTPUT + +defn times (flip:Flip,d:Direction) -> Direction : flip * d +defn times (d:Direction,flip:Flip) -> Direction : switch {_ == flip} : - DEFAULT : g - REVERSE : swap(g) + DEFAULT : d + REVERSE : swap(d) +defn times (g:Gender,flip:Flip) -> Gender : flip * g defn times (flip:Flip,g:Gender) -> Gender : switch {_ == flip} : DEFAULT : g REVERSE : swap(g) + +defn times (f1:Flip,f2:Flip) -> Flip : + switch {_ == f2} : + DEFAULT : f1 + REVERSE : swap(f1) defn to-field (p:Port) -> Field : Field(name(p),REVERSE,type(p)) @@ -79,6 +107,11 @@ defn to-field (p:Port) -> Field : else if direction(p) == INPUT : Field(name(p),DEFAULT,type(p)) else : error("Shouldn't be here") +defn to-dir (g:Gender) -> Direction : + switch {_ == g} : + MALE : INPUT + FEMALE : OUTPUT + defmulti gender (e:Expression) -> Gender defmethod gender (e:Expression) : MALE ; TODO, why was this OUTPUT before? It makes sense as male, not female @@ -91,6 +124,10 @@ defmethod print (o:OutputStream, g:Gender) : BI-GENDER : "bi" UNKNOWN-GENDER: "unknown" +defmethod type (exp:UIntValue) -> Type : UIntType(width(exp)) +defmethod type (exp:SIntValue) -> Type : SIntType(width(exp)) +defmethod type (exp:Null) -> Type : UnknownType() + ;============== DEBUG STUFF ============================= public var PRINT-TYPES : True|False = false public var PRINT-KINDS : True|False = false @@ -580,8 +617,7 @@ defn infer-types (c:Circuit) -> Circuit : Circuit{ _, main(c) } $ for m in modules(c) map : infer-types(m,l) - - + ;============= RESOLVE ACCESSOR GENDER ============================ ; To ensure a proper circuit, we must ensure that assignments ; only work on expressions that can be assigned to. Similarly, @@ -696,16 +732,12 @@ defn resolve-genders (c:Circuit) : resolve-genders(m,c) ;;============== EXPAND ACCESSORS ================================ -; This pass expands accessors into either ReadPort/WritePort if it -; accesses a memory, or a ManyConnect/ConnectMany otherwise. -; If accessing a memory, female accessors turn into WritePorts and -; male accessors turn into ReadPorts. The enable signals are -; calculated by ANDing all predicates of all parent nested whens -; at the sight of the accessor declaration -; If not accessing a memory, all elements of the vector are +; This pass expands non-memory accessors into ConnectToIndexed or +; ConnectFromIndexed. All elements of the vector are ; explicitly written out, then indexed. Depending on the gender ; of the accessor, it is transformed into ConnectToIndexed (male) or ; ConnectFromIndexed (female) +; Eg: defstruct ConnectToIndexed <: Stmt : index: Expression @@ -728,72 +760,37 @@ defmethod map (f: Expression -> Expression, c:ConnectFromIndexed) : ConnectFromIndexed(f(index(c)), f(loc(c)), map(f, exps(c))) defn expand-vector (e:Expression) -> List<Expression> : - match(e) : - (e:WRef) : - match(type(e)) : - (t:VectorType) : - var l = list() - for i in 0 to size(t) do : - l = List(WIndex(e,i,type(t),gender(e)),l) - l - (t) : error("Shouldn't be here, TODO") - (e) : error("Shouldn't be here, TODO") - -defn contained-type (e:Expression) -> Type : - match(e) : - (e:WRef) : - match(type(e)) : - (t:VectorType) : type(t) - (t) : error("Shouldn't be here, TODO") - (t) : error("Shouldn't be here, TODO") - -defn and-all (l:List<Expression>) -> Expression : - if length(l) == 0 : UIntValue(1,IntWidth(1)) - else : DoPrim(BIT-AND-OP,list(l[0],and-all(tail(l))),list(),UIntType(IntWidth(1))) - -defn expand-stmt (s:Stmt,preds:List<Expression>) -> Stmt : + val t = type(e) as VectorType + for i in 0 to size(t) map-append : + list(WIndex(e,i,type(t),gender(e as ?))) ;always be WRef|WSubfield|WIndex + +defn expand-stmt (s:Stmt) -> Stmt : match(s) : (s:WDefAccessor) : println-all(["Matched WDefAcc with " name(s)]) val mem? = match(source(s)) : (e:WRef) : kind(e) typeof MemKind (e) : false - if mem? : - val enable = and-all(preds) - val value-type = contained-type(source(s)) - val wire = DefWire(name(s),value-type) - switch {gender(s) == _} : - MALE : - val read = ReadPort(source(s),index(s),value-type,enable) - val connect = Connect(WRef(name(s),value-type,NodeKind(),FEMALE),read) - Begin(list(wire,connect)) - FEMALE: - val write = WritePort(source(s),index(s),value-type,enable) - val connect = Connect(write,WRef(name(s),value-type,NodeKind(),MALE)) - Begin(list(wire,connect)) + if mem? : s else : - val value-type = contained-type(source(s)) - val wire = DefWire(name(s),value-type) + val vtype = type(type(source(s)) as VectorType) + val wire = DefWire(name(s),vtype) switch {gender(s) == _} : - MALE : Begin(list(wire,connectmany)) where : - val exps = expand-vector(source(s)) - val connectmany = ConnectFromIndexed(index(s),WRef(name(s),value-type,NodeKind(),FEMALE),exps) - FEMALE: Begin(list(wire,manyconnect)) where : - val locs = expand-vector(source(s)) - val manyconnect = ConnectToIndexed(index(s),locs,WRef(name(s),value-type,NodeKind(),MALE)) - (s:Conditionally) : - val conseq* = expand-stmt(conseq(s),List(pred(s),preds)) - val alt-pred = DoPrim(EQUAL-UU-OP,list(UIntValue(0,IntWidth(1)),pred(s)),list(),UIntType(IntWidth(1))) - val alt* = expand-stmt(alt(s),List(alt-pred,preds)) - Conditionally(pred(s),conseq*,alt*) - (s) : map(expand-stmt{_,preds},s) + MALE : Begin{list(wire,_)} $ ConnectFromIndexed( + index(s), + WRef(name(wire),vtype,NodeKind(),FEMALE), + expand-vector(source(s))) + FEMALE: Begin{list(wire,_)} $ ConnectToIndexed( + index(s), + expand-vector(source(s)), + WRef(name(wire),vtype,NodeKind(),MALE)) + (s) : map(expand-stmt,s) defn expand-accessors (c:Circuit) : Circuit(modules*, main(c)) where : val modules* = for m in modules(c) map : - Module(name(m),ports(m),expand-stmt(body(m),list())) - + Module(name(m),ports(m),expand-stmt(body(m))) ;;=============== LOWERING TO GROUND TYPES ============================= ; All non-ground (elevated) types (Vectors, Bundles) are expanded out to @@ -802,37 +799,174 @@ defn expand-accessors (c:Circuit) : ; to the lowered ground expression names and genders. This allows ; references to be resolved. -;defn build-table (t:Type,f:Flip,l:List<KeyValue<Symbol,Flip>>) -> List<KeyValue<Symbol,Flip>> : -; match (t) : -; (t:BundleType) : -; for field in fields(t) map : -; match(type(field)) : -; (t:BundleType) : append(l,lower-type(t,f * flip(field),l)) -; (t:VectorType) : append(l,lower-type(t,f * flip(field),l)) -; (t) : List(KeyValue(gensym(),f * flip(field))) -; (t:VectorType) : -; match(type(f)) : -; (t:BundleType) : append(l,lower-type(t,f,l)) -; (t:VectorType) : append(l,lower-type(t,f,l)) -; (t) : -; for i in size(t) map : -; List(KeyValue(gensym(),f)) -; (t) : l -; -;defn build-table (ports:List<Port>) -> HashMap<Symbol,List<[Symbol,Gender]>> : -; for p in ports do : -; match(type(p)) : -; (t:BundleType) : -; -;defn lower-module (m:Module,c:Circuit) -> Module : -; -; -;defn lower-to-ground (c:Circuit) : -; Circuit(modules*, main(c)) where : -; val modules* = -; for m in modules(c) map : -; lower-module(m,c) +defn num-elems (t:Type) -> Int : + match(t) : + (t:BundleType) : + var sum = 0 + for f in fields(t) do : + sum = sum + num-elems(type(f)) + sum + (t:VectorType) : size(t) * num-elems(type(t)) + (t) : 1 + +defn index-of-elem (t:BundleType, s:Symbol) -> Int : + var sum = 0 + label<Int> ret : + for f in fields(t) do : + if s == name(f) : ret(sum) + else : sum = sum + num-elems(type(f)) + error("Shouldn't be here") + +defn lower-ports (m:Module, table:HashTable<Symbol,List<KeyValue<Expression,Flip>>>) -> List<Port> : + val entries = table[name(m)] + val directions = + for p in ports(m) map-append : + to-list(for i in 0 to num-elems(type(p)) stream : direction(p)) + for (kv in entries, d in directions) map : + val exp = key(kv) as WRef + val dir* = d * value(kv) + Port(name(exp),dir*,type(exp)) + +defn lower (body:Stmt, table:HashTable<Symbol,List<KeyValue<Expression,Flip>>>) -> Stmt : + defn lower-stmt (s:Stmt) -> Stmt : + defn add-to-table (y:Symbol,k:KeyValue<Expression,Flip>,ctable:HashTable<Symbol,List<KeyValue<Expression,Flip>>>) : + val contains? = for x in ctable any? : + key(x) == y + if contains? : ctable[y] = append(ctable[y],list(k)) + else : ctable[y] = list(k) + match(s) : + (s:DefWire) : Begin{_} $ + for t in table[name(s)] map : + DefWire(name(key(t) as WRef),type(key(t))) + (s:DefRegister) : Begin{_} $ + for t in table[name(s)] map : + DefRegister(name(key(t) as WRef),type(key(t))) + (s:DefInstance) : s + (s:DefNode) : + val s* = Begin $ list( + DefWire(name(s),type(value(s))), + Connect(WRef(name(s),type(value(s)),NodeKind(),UNKNOWN-GENDER),value(s))) + 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) + switch fn ([x,y]) : lgender == x and rgender == y : + [FEMALE,MALE] : Connect(key(l),key(r)) + [MALE,FEMALE] : Connect(key(r),key(l)) + (s:WDefAccessor) : Begin{_} $ + for (l in table[name(s)], r in expand-expr(source(s))) map: + WDefAccessor(name(key(l) as WRef),key(r),index(s),value(r) * gender(s)) + (s:ConnectFromIndexed) : Begin(ls) where : + val ctable = HashTable<Symbol,List<KeyValue<Expression,Flip>>>(symbol-hash) + for e in exps(s) do : + for (r in expand-expr(e),l in expand-expr(loc(s))) do : + 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) + var rgender = BI-GENDER + val exps = for e in ctable[name(key(l) as WRef)] map : + rgender = rgender + (MALE * value(e)) + key(e) + switch fn ([x,y]) : lgender == x and rgender == y : + [FEMALE,MALE] : ConnectFromIndexed(index(s),key(l),exps) + [MALE,FEMALE] : ConnectToIndexed(index(s),exps,key(l)) + (s:ConnectToIndexed) : Begin(ls) where : + val ctable = HashTable<Symbol,List<KeyValue<Expression,Flip>>>(symbol-hash) + for ls in locs(s) do : + for (l in expand-expr(ls),r in expand-expr(exp(s))) do : + add-to-table(name(key(r) as WRef),l,ctable) + val ls = + for r in expand-expr(exp(s)) map : + val n = name(key(r) as WRef) + val rgender = MALE * value(r) + var lgender = BI-GENDER + val locs = for l in ctable[n] map : + lgender = lgender + (FEMALE * value(l)) + key(l) + switch fn ([x,y]) : lgender == x and rgender == y : + [FEMALE,MALE] : ConnectToIndexed(index(s),locs,key(r)) + [MALE,FEMALE] : ConnectFromIndexed(index(s),key(r),locs) + (s:DefMemory) : Begin{_} $ + for t in table[name(s)] map : + DefMemory(name(key(t) as WRef),VectorType(type(key(t)),size(type(s)))) + (s) : map(lower-stmt,s) + + defn expand-expr (e:Expression) -> List<KeyValue<Expression,Flip>> : + match(e) : + (e:WRef) : table[name(e)] + (e:WSubfield) : + val exps = expand-expr(exp(e)) + val begin = index-of-elem(type(exp(e)) as BundleType,name(e)) + val len = num-elems(type(e)) + headn(tailn(exps,begin),len) + (e:WIndex) : + val exps = expand-expr(exp(e)) + val len = num-elems(type(e)) + headn(tailn(exps,len * value(e)),len) + (e) : list(KeyValue(e, DEFAULT)) + + println(table) + lower-stmt(body) + +defn get-entries (n:Symbol,t:Type) -> List<KeyValue<WRef,Flip>> : + defn uniquify (w:WRef) -> WRef : + val name* = symbol-join([n "#" name(w)]) + WRef(name*,type(w),kind(w),gender(w)) + match(t) : + (t:BundleType) : + for f in fields(t) map-append : + val es = get-entries(name(f),type(f)) + for e in es map : + uniquify(key(e)) => value(e) * flip(f) + (t:VectorType) : + for i in 0 to size(t) map-append : + val es = get-entries(to-symbol(i),type(t)) + for e in es map : + uniquify(key(e)) => value(e) + (t) : list(KeyValue(WRef(n,t,NodeKind(),UNKNOWN-GENDER),DEFAULT)) + +defn lower-module (m:Module,table:HashTable<Symbol,List<KeyValue<Expression,Flip>>>) -> Module : + defn build-table-ports (ports:List<Port>) : + for p in ports do : + table[name(p)] = get-entries(name(p),type(p)) + + defn build-table-stmt (stmt:Stmt) -> Stmt: + match(stmt) : + (s:DefWire) : table[name(s)] = get-entries(name(s),type(s)) + (s:DefRegister) : table[name(s)] = get-entries(name(s),type(s)) + (s:DefInstance) : + val r = WRef(name(s),type(module(s)),InstanceKind(),FEMALE) + val ports = table[name(module(s) as WRef)] + table[name(s)] = + for w in ports map-append : + list(KeyValue(WSubfield(r,name(key(w) as WRef),type(key(w) as WRef),UNKNOWN-GENDER), value(w))) + (s:DefMemory) : table[name(s)] = get-entries(name(s),type(type(s) as VectorType)) + (s:DefNode) : table[name(s)] = get-entries(name(s),type(value(s))) + (s:WDefAccessor) : table[name(s)] = get-entries(name(s),type(type(source(s)) as VectorType)) + (s) : map(build-table-stmt,s) + stmt + + build-table-ports(ports(m)) + build-table-stmt(body(m)) + Module(name(m),ports*,body*) where : + val body* = lower(body(m),table) + val ports* = lower-ports(m,table) + +defn lower-to-ground (c:Circuit) -> Circuit : + val table = HashTable<Symbol,List<KeyValue<Expression,Flip>>>(symbol-hash) + defn build-table-module (m:Module) -> ? : + table[name(m)] = for p in ports(m) map-append : get-entries(name(p),type(p)) + + for m in modules(c) map : + build-table-module(m) + + Circuit(modules*, main(c)) where : + val modules* = + for m in modules(c) map : + lower-module(m,table) ;defn prefix (prefix, suffix) : ; symbol-join([prefix "/" suffix]) @@ -2101,7 +2235,7 @@ public defn run-passes (c: Circuit, p: List<Char>) : if contains(p,'e') : do-stage("Infer Types", infer-types) if contains(p,'f') : do-stage("Resolve Genders", resolve-genders) if contains(p,'g') : do-stage("Expand Accessors", expand-accessors) - ;if contains(p,'h') : do-stage("Flatten Bundles", flatten-bundles) + if contains(p,'h') : do-stage("Lower To Ground", lower-to-ground) ;if contains(p,'i') : do-stage("Expand Bundles", expand-bundles) ;if contains(p,'j') : do-stage("Expand Multi Connects", expand-multi-connects) ;if contains(p,'k') : do-stage("Expand Whens", expand-whens) diff --git a/test/passes/expand-accessors/accessor-mem.fir b/test/passes/expand-accessors/accessor-mem.fir index 32002d47..01257279 100644 --- a/test/passes/expand-accessors/accessor-mem.fir +++ b/test/passes/expand-accessors/accessor-mem.fir @@ -5,15 +5,15 @@ circuit top : module top : mem m : UInt(32)[10][10][10] wire i : UInt - accessor a = m[i] ;CHECK: a := ReadPort(m, i, UInt(1)) - accessor b = a[i] ;CHECK: b := (a.9 a.8 a.7 a.6 a.5 a.4 a.3 a.2 a.1 a.0)[i] - accessor c = b[i] ;CHECK: c := (b.9 b.8 b.7 b.6 b.5 b.4 b.3 b.2 b.1 b.0)[i] + accessor a = m[i] ;CHECK: accessor a = m[i] + accessor b = a[i] ;CHECK: b := (a.0 a.1 a.2 a.3 a.4 a.5 a.6 a.7 a.8 a.9)[i] + accessor c = b[i] ;CHECK: c := (b.0 b.1 b.2 b.3 b.4 b.5 b.6 b.7 b.8 b.9)[i] wire j : UInt j := c - accessor x = m[i] ;CHECK: WritePort(m, i, UInt(1)) := x - accessor y = x[i] ;CHECK: (x.9 x.8 x.7 x.6 x.5 x.4 x.3 x.2 x.1 x.0)[i] := y - accessor z = y[i] ;CHECK: (y.9 y.8 y.7 y.6 y.5 y.4 y.3 y.2 y.1 y.0)[i] := z + accessor x = m[i] ;CHECK: accessor x = m[i] + accessor y = x[i] ;CHECK: (x.0 x.1 x.2 x.3 x.4 x.5 x.6 x.7 x.8 x.9)[i] := y + accessor z = y[i] ;CHECK: (y.0 y.1 y.2 y.3 y.4 y.5 y.6 y.7 y.8 y.9)[i] := z z := j ; CHECK: Finished Expand Accessors diff --git a/test/passes/expand-accessors/accessor-vec.fir b/test/passes/expand-accessors/accessor-vec.fir index 4314e062..599abb8f 100644 --- a/test/passes/expand-accessors/accessor-vec.fir +++ b/test/passes/expand-accessors/accessor-vec.fir @@ -5,15 +5,23 @@ circuit top : module top : wire m : UInt(32)[10][10][10] wire i : UInt - accessor a = m[i] ;CHECK: a := (m.9 m.8 m.7 m.6 m.5 m.4 m.3 m.2 m.1 m.0)[i] - accessor b = a[i] ;CHECK: b := (a.9 a.8 a.7 a.6 a.5 a.4 a.3 a.2 a.1 a.0)[i] - accessor c = b[i] ;CHECK: c := (b.9 b.8 b.7 b.6 b.5 b.4 b.3 b.2 b.1 b.0)[i] + accessor a = m[i] ;CHECK: a := (m.0 m.1 m.2 m.3 m.4 m.5 m.6 m.7 m.8 m.9)[i] + accessor b = a[i] ;CHECK: b := (a.0 a.1 a.2 a.3 a.4 a.5 a.6 a.7 a.8 a.9)[i] + accessor c = b[i] ;CHECK: c := (b.0 b.1 b.2 b.3 b.4 b.5 b.6 b.7 b.8 b.9)[i] wire j : UInt j := c - accessor x = m[i] ;CHECK: (m.9 m.8 m.7 m.6 m.5 m.4 m.3 m.2 m.1 m.0)[i] := x - accessor y = x[i] ;CHECK: (x.9 x.8 x.7 x.6 x.5 x.4 x.3 x.2 x.1 x.0)[i] := y - accessor z = y[i] ;CHECK: (y.9 y.8 y.7 y.6 y.5 y.4 y.3 y.2 y.1 y.0)[i] := z + accessor x = m[i] ;CHECK: (m.0 m.1 m.2 m.3 m.4 m.5 m.6 m.7 m.8 m.9)[i] := x + accessor y = x[i] ;CHECK: (x.0 x.1 x.2 x.3 x.4 x.5 x.6 x.7 x.8 x.9)[i] := y + accessor z = y[i] ;CHECK: (y.0 y.1 y.2 y.3 y.4 y.5 y.6 y.7 y.8 y.9)[i] := z z := j + wire p : {n : UInt(32)[10]} + accessor q = p.n[i] ;CHECK: (p.n.0 p.n.1 p.n.2 p.n.3 p.n.4 p.n.5 p.n.6 p.n.7 p.n.8 p.n.9)[i] := q + q := j + + wire r : {m : UInt(32)}[10] + accessor s = r[i] ;CHECK: s := (r.0 r.1 r.2 r.3 r.4 r.5 r.6 r.7 r.8 r.9)[i] + j := s.m + ; CHECK: Finished Expand Accessors diff --git a/test/passes/expand-accessors/one-when.fir b/test/passes/expand-accessors/one-when.fir deleted file mode 100644 index 2597c1d7..00000000 --- a/test/passes/expand-accessors/one-when.fir +++ /dev/null @@ -1,20 +0,0 @@ -; RUN: firrtl %s abcdefg c | tee %s.out | FileCheck %s - -;CHECK: Expand Accessors -circuit top : - module top : - mem m : UInt(1)[2] - wire i : UInt(1) - wire p : UInt(1) - when p : - accessor a = m[i] ;CHECK: a := ReadPort(m, i, bit-and(p, UInt(1))) - i := a - accessor b = m[i] ;CHECK: WritePort(m, i, bit-and(p, UInt(1))) := b - b := i - else : - accessor c = m[i] ;CHECK: c := ReadPort(m, i, bit-and(equal-uu(UInt(0), p), UInt(1))) - i := c - accessor d = m[i] ;CHECK: WritePort(m, i, bit-and(equal-uu(UInt(0), p), UInt(1))) := d - d := i - -; CHECK: Finished Expand Accessors diff --git a/test/passes/expand-accessors/two-when.fir b/test/passes/expand-accessors/two-when.fir deleted file mode 100644 index 87c8fc54..00000000 --- a/test/passes/expand-accessors/two-when.fir +++ /dev/null @@ -1,57 +0,0 @@ -; RUN: firrtl %s abcdefg c | tee %s.out | FileCheck %s - -;CHECK: Expand Accessors -circuit top : - module top : - mem m : UInt(1)[2] - wire i : UInt(1) - wire p : UInt(1) - when p : - wire p2 : UInt(1) - when p2 : - accessor a = m[i] - i := a - accessor b = m[i] - b := i - ;CHECK : wire a : UInt(1) - ;CHECK : a := ReadPort(m, i, bit-and(p2, bit-and(p, UInt(1)))) - ;CHECK : i := a - ;CHECK : wire b : UInt(1) - ;CHECK : WritePort(m, i, bit-and(p2, bit-and(p, UInt(1)))) := b - ;CHECK : b := i - else : - accessor c = m[i] - i := c - accessor d = m[i] - d := i - ;CHECK : wire c : UInt(1) - ;CHECK : c := ReadPort(m, i, bit-and(equal-uu(UInt(0), p2), bit-and(p, UInt(1)))) - ;CHECK : i := c - ;CHECK : wire d : UInt(1) - ;CHECK : WritePort(m, i, bit-and(equal-uu(UInt(0), p2), bit-and(p, UInt(1)))) := d - ;CHECK : d := i - else : - when p2 : - accessor w = m[i] - i := w - accessor x = m[i] - x := i - ;CHECK : wire w : UInt(1) - ;CHECK : w := ReadPort(m, i, bit-and(p2, bit-and(equal-uu(UInt(0), p), UInt(1)))) - ;CHECK : i := w - ;CHECK : wire x : UInt(1) - ;CHECK : WritePort(m, i, bit-and(p2, bit-and(equal-uu(UInt(0), p), UInt(1)))) := x - ;CHECK : x := i - else : - accessor y = m[i] - i := y - accessor z = m[i] - z := i - ;CHECK : wire y : UInt(1) - ;CHECK : y := ReadPort(m, i, bit-and(equal-uu(UInt(0), p2), bit-and(equal-uu(UInt(0), p), UInt(1)))) - ;CHECK : i := y - ;CHECK : wire z : UInt(1) - ;CHECK : WritePort(m, i, bit-and(equal-uu(UInt(0), p2), bit-and(equal-uu(UInt(0), p), UInt(1)))) := z - ;CHECK : z := i - -; CHECK: Finished Expand Accessors diff --git a/test/passes/expand-whens/one-when.fir b/test/passes/expand-whens/one-when.fir new file mode 100644 index 00000000..78c59493 --- /dev/null +++ b/test/passes/expand-whens/one-when.fir @@ -0,0 +1,15 @@ +circuit top : + module top : + mem m : UInt(1)[2] + wire i : UInt(1) + wire p : UInt(1) + when p : + accessor a = m[i] + i := a + accessor b = m[i] + b := i + else : + accessor c = m[i] + i := c + accessor d = m[i] + d := i diff --git a/test/passes/expand-whens/two-when.fir b/test/passes/expand-whens/two-when.fir new file mode 100644 index 00000000..16fae1e2 --- /dev/null +++ b/test/passes/expand-whens/two-when.fir @@ -0,0 +1,28 @@ +circuit top : + module top : + mem m : UInt(1)[2] + wire i : UInt(1) + wire p : UInt(1) + when p : + wire p2 : UInt(1) + when p2 : + accessor a = m[i] + i := a + accessor b = m[i] + b := i + else : + accessor c = m[i] + i := c + accessor d = m[i] + d := i + else : + when p2 : + accessor w = m[i] + i := w + accessor x = m[i] + x := i + else : + accessor y = m[i] + i := y + accessor z = m[i] + z := i diff --git a/test/passes/lower-to-ground/accessor.fir b/test/passes/lower-to-ground/accessor.fir new file mode 100644 index 00000000..56171246 --- /dev/null +++ b/test/passes/lower-to-ground/accessor.fir @@ -0,0 +1,33 @@ +; RUN: firrtl %s abcdefgh c | tee %s.out | FileCheck %s + +; CHECK: Lower To Ground +circuit top : + module m : + wire i : UInt + wire j : UInt + + 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) + + accessor b = a[i] + ; CHECK: wire b : UInt(32) + ; 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 + c := j + + mem p : UInt(32)[10] + accessor t = p[i] + ; CHECK: accessor t = p[i] + j := t + accessor r = p[i] + ; CHECK: accessor r = p[i] + r := j + +; CHECK: Finished Lower To Ground diff --git a/test/passes/lower-to-ground/bundle-vecs.fir b/test/passes/lower-to-ground/bundle-vecs.fir new file mode 100644 index 00000000..a4ead6ed --- /dev/null +++ b/test/passes/lower-to-ground/bundle-vecs.fir @@ -0,0 +1,31 @@ +; RUN: firrtl %s abcdefgh c | tee %s.out | FileCheck %s + +; CHECK: Lower To Ground +circuit top : + module q : + wire i : UInt + 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) + + 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 + 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] + c := j + + +; CHECK: Finished Lower To Ground + diff --git a/test/passes/lower-to-ground/bundle.fir b/test/passes/lower-to-ground/bundle.fir new file mode 100644 index 00000000..990b6b7f --- /dev/null +++ b/test/passes/lower-to-ground/bundle.fir @@ -0,0 +1,53 @@ +; RUN: firrtl %s abcdefgh c | tee %s.out | FileCheck %s + +circuit top : + module m : + input a : { x : UInt, flip y: SInt} + output b : { x : UInt, flip y: SInt} + module subtracter : + input c : { x : UInt[5], flip y : { x : UInt[3], flip y : SInt } } + wire a : { x : UInt, flip y : SInt} + wire b : { x : UInt, flip y : SInt} + a := b + inst i of m + i.a := a + b := i.b + wire d : UInt[5] + +;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 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 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: 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: Finished Lower To Ground diff --git a/test/passes/lower-to-ground/nested-vec.fir b/test/passes/lower-to-ground/nested-vec.fir new file mode 100644 index 00000000..8eafb8e8 --- /dev/null +++ b/test/passes/lower-to-ground/nested-vec.fir @@ -0,0 +1,34 @@ +; RUN: firrtl %s abcdefgh c | tee %s.out | FileCheck %s + +; CHECK: Lower To Ground +circuit top : + module q : + wire i : UInt + 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) + + 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 + 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] + + 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 + c := j + +; CHECK: Finished Lower To Ground + |
