aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TODO1
-rw-r--r--notes/notes.03.10.15.txt33
-rw-r--r--src/main/stanza/firrtl-ir.stanza10
-rw-r--r--src/main/stanza/ir-parser.stanza10
-rw-r--r--src/main/stanza/ir-utils.stanza14
-rw-r--r--src/main/stanza/passes.stanza197
-rw-r--r--test/passes/expand-accessors/accessor-mem.fir19
-rw-r--r--test/passes/expand-accessors/accessor-vec.fir19
-rw-r--r--test/passes/expand-accessors/one-when.fir20
-rw-r--r--test/passes/expand-accessors/two-when.fir57
10 files changed, 280 insertions, 100 deletions
diff --git a/TODO b/TODO
index 0f31afde..ee4332da 100644
--- a/TODO
+++ b/TODO
@@ -4,6 +4,7 @@ TODO
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
Update spec
add new field for sequential or combinational
add assertions
diff --git a/notes/notes.03.10.15.txt b/notes/notes.03.10.15.txt
new file mode 100644
index 00000000..dee8a537
--- /dev/null
+++ b/notes/notes.03.10.15.txt
@@ -0,0 +1,33 @@
+Lower to ground types
+
+simple declarations:
+ wire w : UInt[3]
+ ==>
+ wire temp1 : UInt
+ wire temp2 : UInt
+ wire temp3 : UInt
+
+ reg r : UInt[3] ;TODO
+
+bundle declarations:
+ wire w : {male data:SInt, female ready:UInt}
+ wire temp1 : SInt
+ wire temp2 : UInt
+
+other
+ wire w : {male data : SInt[3], female ready : UInt}
+ wire temp1 : SInt
+ wire temp2 : SInt
+ wire temp3 : SInt
+ wire temp4 : UInt
+
+ports:
+ input a : {m: data, m:valid, f:rdy}
+ ==>
+ input a1
+ input a2
+ output a3
+
+mem m : {m,
+
+key function: expand-exp(e:Expression) -> List<[Expression,Gender]>
diff --git a/src/main/stanza/firrtl-ir.stanza b/src/main/stanza/firrtl-ir.stanza
index 46235bd6..16e7096b 100644
--- a/src/main/stanza/firrtl-ir.stanza
+++ b/src/main/stanza/firrtl-ir.stanza
@@ -144,6 +144,12 @@ public defstruct ReadPort <: Expression :
mem: Expression
index: Expression
type: Type [multi => false]
+ enable: Expression
+public defstruct WritePort <: Expression :
+ mem: Expression
+ index: Expression
+ type: Type [multi => false]
+ enable: Expression
public defstruct Null <: Expression
public definterface Stmt
@@ -190,10 +196,6 @@ public defstruct Register <: Element :
public defstruct Memory <: Element :
type: Type [multi => false]
writers: List<WritePort>
-public defstruct WritePort :
- index: Expression
- value: Expression
- enable: Expression
public defstruct Node <: Element :
type: Type [multi => false]
value: Expression
diff --git a/src/main/stanza/ir-parser.stanza b/src/main/stanza/ir-parser.stanza
index 0334bca2..a9ea7c30 100644
--- a/src/main/stanza/ir-parser.stanza
+++ b/src/main/stanza/ir-parser.stanza
@@ -146,10 +146,6 @@ rd.defsyntax firrtl :
defrule element :
(reg ?name:#symbol : ?type:#type = Register (@do ?value:#exp ?en:#exp)) :
ut(name) => Register(type, value, en)
- (mem ?name:#symbol : ?type:#type = Memory
- (@do (?i:#exp => WritePort (@do ?value:#exp ?en:#exp) @...))) :
- val ports = map(WritePort, i, value, en)
- ut(name) => Memory(type, ports)
(node ?name:#symbol : ?type:#type = ?exp:#exp) :
ut(name) => Node(type, exp)
(inst ?name:#symbol = Instance (@do ?module:#exp
@@ -271,8 +267,10 @@ rd.defsyntax firrtl :
SIntValue(ut(value), IntWidth(ut(width)))
(SInt (@do ?value:#int)) :
SIntValue(ut(value), UnknownWidth())
- (ReadPort (@do ?mem:#exp ?index:#exp)) :
- ReadPort(mem, index, UnknownType())
+ (WritePort (@do ?mem:#exp ?index:#exp ?enable:#exp)) :
+ WritePort(mem, index, UnknownType(), enable)
+ (ReadPort (@do ?mem:#exp ?index:#exp ?enable:#exp)) :
+ ReadPort(mem, index, UnknownType(), enable)
(?op:#symbol (@do ?es:#exp ... ?ints:#int ...)) :
match(get?(operators, ut(op), false)) :
(op:PrimOp) :
diff --git a/src/main/stanza/ir-utils.stanza b/src/main/stanza/ir-utils.stanza
index 74e74679..47f6154b 100644
--- a/src/main/stanza/ir-utils.stanza
+++ b/src/main/stanza/ir-utils.stanza
@@ -139,7 +139,8 @@ defmethod print (o:OutputStream, e:Expression) :
print-all(o, [op(e) "("])
print-all(o, join(concat(args(e), consts(e)), ", "))
print(o, ")")
- (e:ReadPort) : print-all(o, ["ReadPort(" mem(e) ", " index(e) ")"])
+ (e:ReadPort) : print-all(o, ["ReadPort(" mem(e) ", " index(e) ", " enable(e) ")"])
+ (e:WritePort) : print-all(o, ["WritePort(" mem(e) ", " index(e) ", " enable(e) ")"])
(e:Null) : print-all(o, ["Null"])
print-debug(o,e)
@@ -194,9 +195,6 @@ defmethod print (o:OutputStream, e:Element) :
print(o, ")")
print-debug(o,e)
-defmethod print (o:OutputStream, p:WritePort) :
- print-all(o, [index(p) " => WritePort(" value(p) ", " enable(p) ")"])
-
defmethod print (o:OutputStream, t:Type) :
match(t) :
(t:UnknownType) :
@@ -278,7 +276,8 @@ defmethod map (f: Expression -> Expression, e:Expression) -> Expression :
(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))
+ (e:ReadPort) : ReadPort(f(mem(e)), f(index(e)), type(e), enable(e))
+ (e:WritePort) : WritePort(f(mem(e)), f(index(e)), type(e), enable(e))
(e) : e
public defmulti map<?T> (f: Expression -> Expression, e:?T&Element) -> T
@@ -286,10 +285,7 @@ defmethod map (f: Expression -> Expression, e:Element) -> Element :
match(e) :
(e:Register) :
Register(type(e), f(value(e)), f(enable(e)))
- (e:Memory) :
- val writers* = for w in writers(e) map :
- WritePort(f(index(w)), f(value(w)), f(enable(w)))
- Memory(type(e), writers*)
+ (e:Memory) : e
(e:Node) :
Node(type(e), f(value(e)))
(e:Instance) :
diff --git a/src/main/stanza/passes.stanza b/src/main/stanza/passes.stanza
index 222c386e..51176ff6 100644
--- a/src/main/stanza/passes.stanza
+++ b/src/main/stanza/passes.stanza
@@ -97,7 +97,7 @@ defn hasWidth (e:Expression|Stmt|Type|Element|Port|Field) :
e typeof UIntType|SIntType|UIntValue|SIntValue
defn hasType (e:Expression|Stmt|Type|Element|Port|Field) :
- e typeof Ref|Subfield|Index|DoPrim|ReadPort|WRef|WSubfield
+ e typeof Ref|Subfield|Index|DoPrim|WritePort|ReadPort|WRef|WSubfield
|WIndex|DefWire|DefRegister|DefMemory|Register
|Memory|Node|Instance|VectorType|Port|Field
@@ -521,7 +521,8 @@ defn infer-exp-types (e:Expression, l:List<KeyValue<Symbol,Type>>) -> Expression
(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:ReadPort) : ReadPort(mem(e),index(e),get-vector-subtype(type(mem(e))),enable(e))
+ (e:WritePort) : WritePort(mem(e),index(e),get-vector-subtype(type(mem(e))),enable(e))
(e:UIntValue|SIntValue|Null) : e
defn infer-types (s:Stmt, l:List<KeyValue<Symbol,Type>>) -> [Stmt, List<KeyValue<Symbol,Type>>] :
@@ -592,15 +593,14 @@ defn resolve-genders (c:Circuit) :
g
val entry = for kv in genders find :
key(kv) == n
- label<Gender> myret :
- match(entry) :
- (e:KeyValue<Symbol,Gender>) :
- val value = value(e)
- if value == UNKNOWN-GENDER and g == UNKNOWN-GENDER : myret(g)
- else if value != UNKNOWN-GENDER and g == UNKNOWN-GENDER : myret(value)
- else if value == UNKNOWN-GENDER and g != UNKNOWN-GENDER : myret(force-gender(n,g))
- else : myret(value)
- (e:False) : myret(force-gender(n,g))
+ match(entry) :
+ (e:KeyValue<Symbol,Gender>) :
+ val value = value(e)
+ if value == UNKNOWN-GENDER and g == UNKNOWN-GENDER : g
+ else if value != UNKNOWN-GENDER and g == UNKNOWN-GENDER : value
+ else if value == UNKNOWN-GENDER and g != UNKNOWN-GENDER : force-gender(n,g)
+ else : value
+ (e:False) : force-gender(n,g)
defn resolve-stmt (s:Stmt) -> Stmt :
match(s) :
@@ -629,7 +629,7 @@ defn resolve-genders (c:Circuit) :
(s:Conditionally) :
val pred* = resolve-expr(pred(s),MALE)
val conseq* = resolve-stmt(conseq(s))
- val alt* = resolve-stmt(conseq(s))
+ val alt* = resolve-stmt(alt(s))
Conditionally(pred*,conseq*,alt*)
(s) : map(resolve-stmt,s)
@@ -641,8 +641,8 @@ defn resolve-genders (c:Circuit) :
name(f) == n
match(field):
(f:Field) : gender(f)
- (f) : UNKNOWN-GENDER
- (b) : UNKNOWN-GENDER
+ (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) :
@@ -659,7 +659,7 @@ defn resolve-genders (c:Circuit) :
val exp* = resolve-expr(exp(e),desired)
val gender* = gender(exp*)
WIndex(exp*,value(e),type(e),gender*)
- (e) : map(resolve-expr{_,desired},e)
+ (e) : map(resolve-expr{_,MALE},e)
var module* = resolve-iter(m)
while not done? :
@@ -679,71 +679,106 @@ defn resolve-genders (c:Circuit) :
for m in modules(c) map :
resolve-genders(m,c)
-;;============== EXPAND VECS ================================
-;defstruct ManyConnect <: Stmt :
-; index: Expression
-; locs: List<Expression>
-; exp: Expression
-;
-;defstruct ConnectMany <: Stmt :
-; index: Expression
-; loc: Expression
-; exps: List<Expression>
-;
-;defmethod print (o:OutputStream, c:ManyConnect) :
-; print-all(o, [locs(c) "[" index(c) "] := " exp(c)])
-;defmethod print (o:OutputStream, c:ConnectMany) :
-; print-all(o, [loc(c) " := " exps(c) "[" index(c) "]"])
-;
-;defmethod map (f: Expression -> Expression, c:ManyConnect) :
-; ManyConnect(f(index(c)), map(f, locs(c)), f(exp(c)))
-;defmethod map (f: Expression -> Expression, c:ConnectMany) :
-; ConnectMany(f(index(c)), f(loc(c)), map(f, exps(c)))
-;
-;defn expand-accessors (m: Module) :
-; defn expand (c:Stmt) :
-; match(c) :
-; (c:WDefAccessor) :
-; ;Is the source a memory?
-; val mem? =
-; match(source(c)) :
-; (r:WRef) : kind(r) typeof MemKind
-; (r) : false
-;
-; if mem? :
-; c
-; else :
-; switch {dir(c) == _} :
-; INPUT :
-; Begin(list(
-; DefWire(name(c), type(src-type))
-; ManyConnect(index(c), elems, wire-ref)))
-; where :
-; val src-type = type(source(c)) as VectorType
-; val wire-ref = WRef(name(c), type(src-type), NodeKind(), OUTPUT)
-; val elems = to-list $
-; for i in 0 to size(src-type) stream :
-; WIndex(source(c), i, type(src-type), INPUT)
-; OUTPUT :
-; Begin(list(
-; DefWire(name(c), type(src-type))
-; ConnectMany(index(c), wire-ref, elems)))
-; where :
-; val src-type = type(source(c)) as VectorType
-; val wire-ref = WRef(name(c), type(src-type), NodeKind(), INPUT)
-; val elems = to-list $
-; for i in 0 to size(src-type) stream :
-; WIndex(source(c), i, type(src-type), OUTPUT)
-; (c) :
-; map(expand, c)
-; Module(name(m), ports(m), expand(body(m)))
-;
-;defn expand-accessors (c:Circuit) :
-; Circuit(modules*, main(c)) where :
-; val modules* = map(expand-accessors, modules(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
+; explicitly written out, then indexed. Depending on the gender
+; of the accessor, it is transformed into ManyConnect (male) or
+; ConnectMany (female)
+
+defstruct ManyConnect <: Stmt :
+ index: Expression
+ locs: List<Expression>
+ exp: Expression
+
+defstruct ConnectMany <: Stmt :
+ index: Expression
+ loc: Expression
+ exps: List<Expression>
+
+defmethod print (o:OutputStream, c:ManyConnect) :
+ print-all(o, [locs(c) "[" index(c) "] := " exp(c)])
+defmethod print (o:OutputStream, c:ConnectMany) :
+ print-all(o, [loc(c) " := " exps(c) "[" index(c) "]"])
+
+defmethod map (f: Expression -> Expression, c:ManyConnect) :
+ ManyConnect(f(index(c)), map(f, locs(c)), f(exp(c)))
+defmethod map (f: Expression -> Expression, c:ConnectMany) :
+ ConnectMany(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 :
+ 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))
+ else :
+ val value-type = contained-type(source(s))
+ val wire = DefWire(name(s),value-type)
+ switch {gender(s) == _} :
+ MALE : Begin(list(wire,connectmany)) where :
+ val exps = expand-vector(source(s))
+ val connectmany = ConnectMany(index(s),WRef(name(s),value-type,NodeKind(),FEMALE),exps)
+ FEMALE: Begin(list(wire,manyconnect)) where :
+ val locs = expand-vector(source(s))
+ val manyconnect = ManyConnect(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)
+
+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()))
+
+
;;=============== BUNDLE FLATTENING =========================
;defn prefix (prefix, suffix) :
; symbol-join([prefix "/" suffix])
@@ -2011,7 +2046,7 @@ public defn run-passes (c: Circuit, p: List<Char>) :
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("Resolve Genders", resolve-genders)
- ;if contains(p,'g') : do-stage("Expand Accessors", expand-accessors)
+ 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)
;if contains(p,'j') : do-stage("Expand Multi Connects", expand-multi-connects)
diff --git a/test/passes/expand-accessors/accessor-mem.fir b/test/passes/expand-accessors/accessor-mem.fir
new file mode 100644
index 00000000..32002d47
--- /dev/null
+++ b/test/passes/expand-accessors/accessor-mem.fir
@@ -0,0 +1,19 @@
+; RUN: firrtl %s abcdefg c | tee %s.out | FileCheck %s
+
+;CHECK: Expand Accessors
+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]
+ 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
+ z := j
+
+; CHECK: Finished Expand Accessors
diff --git a/test/passes/expand-accessors/accessor-vec.fir b/test/passes/expand-accessors/accessor-vec.fir
new file mode 100644
index 00000000..4314e062
--- /dev/null
+++ b/test/passes/expand-accessors/accessor-vec.fir
@@ -0,0 +1,19 @@
+; RUN: firrtl %s abcdefg c | tee %s.out | FileCheck %s
+
+;CHECK: Expand Accessors
+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]
+ 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
+ z := j
+
+; CHECK: Finished Expand Accessors
diff --git a/test/passes/expand-accessors/one-when.fir b/test/passes/expand-accessors/one-when.fir
new file mode 100644
index 00000000..2597c1d7
--- /dev/null
+++ b/test/passes/expand-accessors/one-when.fir
@@ -0,0 +1,20 @@
+; 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
new file mode 100644
index 00000000..87c8fc54
--- /dev/null
+++ b/test/passes/expand-accessors/two-when.fir
@@ -0,0 +1,57 @@
+; 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