aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorazidar2015-07-06 17:45:06 -0700
committerazidar2015-07-14 11:29:55 -0700
commit68f7ac42d01c88bcc0c77c919587618673658c76 (patch)
tree054c3a2fdb710b187664fb9e7212046f12ec2ef2
parent8d6c83072cd60ecc376d81eb9a48ccf0f67e57f6 (diff)
Still partial commit, many tests pass. Many tests fail.
-rw-r--r--spec/spec.tex12
-rw-r--r--src/main/stanza/compilers.stanza60
-rw-r--r--src/main/stanza/errors.stanza29
-rw-r--r--src/main/stanza/firrtl-ir.stanza4
-rw-r--r--src/main/stanza/firrtl-test-main.stanza5
-rw-r--r--src/main/stanza/flo.stanza87
-rw-r--r--src/main/stanza/ir-parser.stanza17
-rw-r--r--src/main/stanza/ir-utils.stanza26
-rw-r--r--src/main/stanza/passes.stanza138
-rw-r--r--src/main/stanza/verilog.stanza210
-rw-r--r--test/passes/expand-accessors/accessor-mem.fir14
-rw-r--r--test/passes/expand-accessors/accessor-vec.fir34
-rw-r--r--test/passes/expand-connect-indexed/bundle-vecs.fir2
-rw-r--r--test/passes/expand-whens/bundle-init.fir4
-rw-r--r--test/passes/expand-whens/nested-whens.fir10
-rw-r--r--test/passes/expand-whens/one-when.fir11
-rw-r--r--test/passes/expand-whens/partial-init.fir10
-rw-r--r--test/passes/expand-whens/reg-wdoc.fir1
-rw-r--r--test/passes/expand-whens/scoped-reg.fir1
-rw-r--r--test/passes/expand-whens/two-when.fir21
-rw-r--r--test/passes/infer-types/bundle.fir7
21 files changed, 329 insertions, 374 deletions
diff --git a/spec/spec.tex b/spec/spec.tex
index 647eb471..6c5038cd 100644
--- a/spec/spec.tex
+++ b/spec/spec.tex
@@ -80,7 +80,7 @@ After a custom pass, the resulting circuit should undergo lowering prior to pass
\section{Acknowledgements - IN PROGRESS}
The FIRRTL language could not have been developed without the help of many of the faculty and students in the ASPIRE lab, including but not limited to XXXX.
-We'd also like to thank our sponsors XXXX, and the UC Berkeley University.
+We'd also like to thank our sponsors XXXX, and the University of California, Berkeley.
\section{FIRRTL Language Definition}
@@ -333,7 +333,7 @@ Additionally, the type for a memory must be completely specified and cannot cont
It is an error to specify any other type for a memory.
However, the internal type to the vector type may be a non-ground type, with the caveat that the internal type, if a bundle type, cannot contain any reverse fields.
-A memory cannot be explicitly initialized using a special FIRRTL construct ? the circuit itself must contain the proper logic to initialize the memory.
+A memory cannot be explicitly initialized using a special FIRRTL construct - the circuit itself must contain the proper logic to initialize the memory.
\subsection{Nodes}
A node is simply a named intermediate value in a circuit, and is akin to a pointer in the C programming language.
@@ -550,7 +550,7 @@ This is to facilitate writing transformational passes, by ensuring that the comp
Inside a when, a connection to a component is conditional only if the component is declared outside the when statement.
If the component is both declared and connected to inside a when, the connection is {\em not} conditional on that when.
-Conceptually, a when creates a mux between the stuff outside and the stuff inside ? it acts as type of "conditional barrier".
+Conceptually, a when creates a mux between the stuff outside and the stuff inside - it acts as type of "conditional barrier".
Thus, if you draw a line between a component's declaration and a connection to it, that connection is dependent on all intersected when predicates being true.
The following example shows a {\em conditional} connection inside a when statement, where the register \pd{r} is assigned the value of 42 only if \pds{enable} is true.
@@ -1094,7 +1094,7 @@ Inlined lowered form is essentially a flat netlist which specifies every compone
\item This is impossible to detect, so turns into a silent failure
\item If annotations are used for actual manipulations of circuits later on, this could be the cause of a bug that is exceptionally hard to solve
\item Thus, annotation producer/consumer keeps external data structure mapping names to annotations
-\item Pass writers must do all they can to preserve names ? can provide transform for names that annotation users can run on their tables
+\item Pass writers must do all they can to preserve names - can provide transform for names that annotation users can run on their tables
\item If a name is mangled, the annotation consumer can ERROR. Then, they need to look at the pass to see how their annotations should propagate.
\end{enumerate}
@@ -1297,8 +1297,8 @@ Standardizing how names gets mangled requires a lot of thought, and we didn't fe
For now, names have to be unique, and it is the front-end's responsibility to do this.
\item Why allow declaring components in when statements?
-We want the important property that a module is just a box of components inside ? for any jumble of components, you can always lace them in the box, and it will preserve the semantics.
-You need to declare wires inside whens ? because generators could run within a when in a front-end.
+We want the important property that a module is just a box of components inside - for any jumble of components, you can always lace them in the box, and it will preserve the semantics.
+You need to declare wires inside whens - because generators could run within a when in a front-end.
You should always be able to pull them into a module if we want.
Now its inconsistent if you can't declare registers in the scope.
diff --git a/src/main/stanza/compilers.stanza b/src/main/stanza/compilers.stanza
index 2f6329dc..a3b04a94 100644
--- a/src/main/stanza/compilers.stanza
+++ b/src/main/stanza/compilers.stanza
@@ -3,40 +3,40 @@ defpackage firrtl/compiler :
import verse
import firrtl/passes
import firrtl/errors
- import firrtl/flo
+; import firrtl/flo
import firrtl/verilog
import firrtl/ir2
import firrtl/ir-utils
-public defstruct StandardFlo <: Compiler :
- file: String with: (as-method => true)
-public defmethod passes (c:StandardFlo) -> List<Pass> :
- to-list $ [
- CheckHighForm(expand-delin)
- ;; TempElimination()
- ToWorkingIR()
- MakeExplicitReset()
- ResolveKinds()
- CheckKinds()
- InferTypes()
- CheckTypes()
- ResolveGenders()
- CheckGenders()
- ExpandAccessors()
- LowerToGround()
- ExpandIndexedConnects()
- ExpandWhens()
- InferWidths()
- Pad()
- Inline()
- SplitExp()
- ToRealIR()
- SpecialRename(`#,`_)
- SpecialRename(`$,`::)
- CheckHighForm(`::)
- CheckLowForm()
- Flo(file(c))
- ]
+;public defstruct StandardFlo <: Compiler :
+; file: String with: (as-method => true)
+;public defmethod passes (c:StandardFlo) -> List<Pass> :
+; to-list $ [
+; CheckHighForm(expand-delin)
+; ;; TempElimination()
+; ToWorkingIR()
+; MakeExplicitReset()
+; ResolveKinds()
+; CheckKinds()
+; InferTypes()
+; CheckTypes()
+; ResolveGenders()
+; CheckGenders()
+; ExpandAccessors()
+; LowerToGround()
+; ExpandIndexedConnects()
+; ExpandWhens()
+; InferWidths()
+; Pad()
+; Inline()
+; SplitExp()
+; ToRealIR()
+; SpecialRename(`#,`_)
+; SpecialRename(`$,`::)
+; CheckHighForm(`::)
+; CheckLowForm()
+; Flo(file(c))
+; ]
public defstruct StandardVerilog <: Compiler :
file: String with: (as-method => true)
diff --git a/src/main/stanza/errors.stanza b/src/main/stanza/errors.stanza
index 8c47d112..e726fd00 100644
--- a/src/main/stanza/errors.stanza
+++ b/src/main/stanza/errors.stanza
@@ -247,7 +247,7 @@ public defn check-high-form (c:Circuit,sym:Symbol) -> Circuit :
defn check-valid-loc (info:FileInfo,e:Expression) -> False :
match(e) :
- (e:UIntValue|SIntValue|DoPrim|ReadPort|Register) :
+ (e:UIntValue|SIntValue|DoPrim) :
add(errors,InvalidLOC(info))
(e) : false
@@ -403,20 +403,7 @@ public defn check-kinds (c:Circuit) -> Circuit :
(e:WIndex) : check-is-mem(info,exp(e))
(e) : false
- defn check-kinds-e (info:FileInfo,e:Expression) -> False :
- do(check-kinds-e{info,_},e)
- match(e) :
- (e:ReadPort) :
- check-is-mem(info,mem(e))
- check-not-mem(info,index(e))
- check-not-mem(info,enable(e))
- (e:WritePort) :
- check-is-mem(info,mem(e))
- check-not-mem(info,index(e))
- check-not-mem(info,enable(e))
- (e) : do(check-not-mem{info,_},e)
defn check-kinds-s (s:Stmt) -> False :
- do(check-kinds-e{info(s),_:Expression},s)
match(s) :
(s:DefNode) : check-not-mem(info(s),value(s))
(s:DefAccessor) : check-not-mem(info(s),index(s))
@@ -649,11 +636,19 @@ defn InferDirection (info:FileInfo,name:Symbol) :
[info ": Accessor " name " has a direction that requires inference."]
;---------------- Helper Functions --------------
-defn dir-to-gender (d:Direction) -> Gender :
+defn dir-to-gender (d:PortDirection) -> Gender :
switch {_ == d} :
INPUT : MALE
OUTPUT : FEMALE
+defn gender (s:DefAccessor) -> Gender :
+ switch {_ == acc-dir(s)} :
+ READ : MALE
+ WRITE : FEMALE
+ INFER : UNKNOWN-GENDER
+ RDWR : BI-GENDER
+
+
;----------------- Check Genders Pass ---------------------
public defn check-genders (c:Circuit) -> Circuit :
@@ -697,7 +692,7 @@ public defn check-genders (c:Circuit) -> Circuit :
(s:DefMemory) : genders[name(s)] = BI-GENDER
(s:DefInstance) : genders[name(s)] = MALE
(s:DefAccessor) :
- if dir(s) == INFER : add(errors,InferDirection(info(s),name(s)))
+ if acc-dir(s) == INFER : add(errors,InferDirection(info(s),name(s)))
check-gender(info(s),genders,index(s),MALE)
check-gender(info(s),genders,source(s),gender(s))
genders[name(s)] = gender(s)
@@ -813,7 +808,7 @@ public defn check-low-form (c:Circuit) -> Circuit :
(s:OnReset) : add(errors,NoOnReset(info(s)))
(s:BulkConnect) : add(errors,NoBulkConnect(info(s)))
(s:Connect) :
- check-correct-exp(info(s),e)
+ check-correct-exp(info(s),exp(s))
match(loc(s)) :
(e:Ref|Subfield) :
val n* = to-symbol $ to-string $ e
diff --git a/src/main/stanza/firrtl-ir.stanza b/src/main/stanza/firrtl-ir.stanza
index 92f955b9..b698bae2 100644
--- a/src/main/stanza/firrtl-ir.stanza
+++ b/src/main/stanza/firrtl-ir.stanza
@@ -116,10 +116,10 @@ public defstruct DefNode <: Stmt : ;LOW
value: Expression
public defstruct DefAccessor <: Stmt :
info: FileInfo with: (as-method => true)
- dir: AccDirection
name: Symbol
source: Expression
index: Expression
+ acc-dir: AccDirection
public defstruct Conditionally <: Stmt :
info: FileInfo with: (as-method => true)
pred: Expression
@@ -161,7 +161,7 @@ public defstruct Field :
public defstruct Port :
info: FileInfo
name: Symbol
- pkind: PKind
+ direction: PortDirection
type: Type
public definterface Module
diff --git a/src/main/stanza/firrtl-test-main.stanza b/src/main/stanza/firrtl-test-main.stanza
index beb288b1..374fe438 100644
--- a/src/main/stanza/firrtl-test-main.stanza
+++ b/src/main/stanza/firrtl-test-main.stanza
@@ -11,7 +11,7 @@
#include("primop.stanza")
#include("errors.stanza")
#include("compilers.stanza")
-#include("flo.stanza")
+;#include("flo.stanza")
#include("verilog.stanza")
;Custom Packages
@@ -80,7 +80,8 @@ defn main () :
run-passes(c,get-passes(to-list(pass-names)))
else :
switch {_ == compiler} :
- "flo" : run-passes(c,StandardFlo(output as String))
+ ;"flo" : run-passes(c,StandardFlo(output as String))
+ "flo" : run-passes(c,StandardVerilog(output as String))
"verilog" : run-passes(c,StandardVerilog(output as String))
"verilute" : run-passes(c,InstrumentedVerilog(output as String,to-list $ pass-args))
else : error("Invalid compiler flag")
diff --git a/src/main/stanza/flo.stanza b/src/main/stanza/flo.stanza
index fd000e20..cf15638d 100644
--- a/src/main/stanza/flo.stanza
+++ b/src/main/stanza/flo.stanza
@@ -5,93 +5,6 @@ defpackage firrtl/flo :
import firrtl/ir2
import firrtl/passes
-;========== Pad Widths ==================
-
-public defstruct Pad <: Pass
-public defmethod pass (b:Pad) -> (Circuit -> Circuit) : pad-widths
-public defmethod name (b:Pad) -> String : "Pad Widths"
-
-defn int-width! (t:Type) -> Int :
- match(width!(t)) :
- (w:IntWidth) : width(w)
- (w) : error("Non-int width")
-
-defn set-width (desired:Int,t:Type) -> Type :
- match(t) :
- (t:UIntType) : UIntType(IntWidth(desired))
- (t:SIntType) : SIntType(IntWidth(desired))
- (t) : error("Non-ground type")
-
-defn pad-widths-e (desired:Int,e:Expression) -> Expression :
- defn trim (desired:Int, e:Expression) :
- ;; println-all(["TRIM " desired " e " e])
- DoPrim(BITS-SELECT-OP,list(e),list(desired - 1, 0),set-width(desired,type(e)))
- defn pad (desired:Int, e:Expression) :
- ;; println-all(["PAD " desired " e " e])
- DoPrim(PAD-OP,list(e),list(desired),set-width(desired,type(e)))
- defn trim-pad (desired:Int, e:Expression) :
- val i = int-width!(type(e))
- if i > desired : trim(desired, e)
- else if i == desired : e
- else : pad(desired, e)
- defn self-pad-widths-e (e:Expression) -> Expression :
- pad-widths-e(int-width!(type(e)), e)
- ;; println-all(["PAD-E " desired " " e])
- match(e) :
- (e:DoPrim) :
- val new-desired = reduce(max, 0, map(int-width!{type(_)}, args(e)))
- ;; println-all([" NEW DESIRED " new-desired])
- val e* =
- if contains?([CONCAT-OP, DYN-SHIFT-RIGHT-OP, DYN-SHIFT-LEFT-OP], op(e)) :
- DoPrim(op(e), map(self-pad-widths-e, args(e)), consts(e), type(e))
- else if contains?([MUX-OP], op(e)) :
- DoPrim(op(e), list(pad-widths-e(1, args(e)[0]), pad-widths-e(new-desired, args(e)[1]), pad-widths-e(new-desired, args(e)[2])), consts(e), type(e))
- else :
- map(pad-widths-e{new-desired,_},e)
- trim-pad(desired, e*)
- (e:WRef|WSubfield|WIndex) :
- trim-pad(desired, e)
- (e:UIntValue) :
- val i = int-width!(type(e))
- if i > desired : trim(desired, e)
- else : UIntValue(value(e),IntWidth(desired))
- (e:SIntValue) :
- val i = int-width!(type(e))
- if i > desired : trim(desired, e)
- else : SIntValue(value(e),IntWidth(desired))
- (e:Register) :
- val value* = pad-widths-e(desired, value(e))
- Register(type(value*), value*, pad-widths-e(1, enable(e)))
- (e:ReadPort) :
- if int-width!(type(e)) != desired : error("ReadPort has different width than desired")
- else : ReadPort(mem(e), self-pad-widths-e(index(e)), type(e), pad-widths-e(1, enable(e)))
- (e:WritePort) :
- if int-width!(type(e)) != desired : error("WritePort has different width than desired")
- else : WritePort(mem(e), self-pad-widths-e(index(e)), type(e), pad-widths-e(1, enable(e)))
- (e) : error(to-string $ e)
-
-defn pad-widths-s (s:Stmt) -> Stmt :
- ;; println-all(["PAD-S " s])
- match(map(pad-widths-s,s)) :
- (s:Connect) :
- val i = int-width!(type(loc(s)))
- val loc* = pad-widths-e(i,loc(s))
- val exp* = pad-widths-e(i,exp(s))
- Connect(info(s),loc*,exp*)
- (s:DefNode) :
- val i = int-width!(type(value(s)))
- val exp* = pad-widths-e(i,value(s))
- DefNode(info(s),name(s),exp*)
- (s) :
- s
-
-public defn pad-widths (c:Circuit) -> Circuit :
- Circuit{info(c),_,main(c)} $
- for m in modules(c) map :
- match(m) :
- (m:ExModule) : m
- (m:InModule) : InModule(info(m),name(m),ports(m),pad-widths-s(body(m)))
-
;============= Flo Backend ================
public defstruct Flo <: Pass :
diff --git a/src/main/stanza/ir-parser.stanza b/src/main/stanza/ir-parser.stanza
index 374cf58c..f85ff7c9 100644
--- a/src/main/stanza/ir-parser.stanza
+++ b/src/main/stanza/ir-parser.stanza
@@ -131,6 +131,10 @@ defsyntax firrtl :
FPE(form, "Expected a vector type here.") when t not-typeof VectorType
t
+ ;Error if not an accessor direction
+ accdir! = (?a:#accdir) : a
+ accdir! != () : FPE(form, "Expected an accessor direction here.")
+
;Error if not an expression
exp! = (?e:#exp) : e
exp! != () : FPE(form, "Expected an expression here.")
@@ -196,6 +200,12 @@ defsyntax firrtl :
field = (flip ?name:#id! #:! ?type:#type!) : Field(name, REVERSE, type)
field = (?name:#id #:! ?type:#type!) : Field(name, DEFAULT, type)
+ defrule accdir :
+ accdir = (read) : READ
+ accdir = (write) : WRITE
+ accdir = (infer) : INFER
+ accdir = (rdwr) : RDWR
+
defrule width :
width = (?x:#int) : IntWidth(x)
width = (?) : UnknownWidth()
@@ -208,12 +218,15 @@ defsyntax firrtl :
stmt = (smem ?name:#id! #:! ?t:#vectype!) : DefMemory(first-info(form),name, t, true)
stmt = (inst ?name:#id! #of! ?m:#ref!) : DefInstance(first-info(form),name, m)
stmt = (node ?name:#id! #=! ?e:#exp!) : DefNode(first-info(form),name, e)
- stmt = (accessor ?name:#id! #=! ?s:#exp![?i:#exp$]) : DefAccessor(first-info(form),name, s, i)
+ stmt = (on-reset ?x:#exp := ?y:#exp!) : OnReset(first-info(form),x, y)
+ stmt = (read accessor ?name:#id! #=! ?s:#exp![?i:#exp$]) : DefAccessor(first-info(form),name, s, i,READ)
+ stmt = (write accessor ?name:#id! #=! ?s:#exp![?i:#exp$]) : DefAccessor(first-info(form),name, s, i,WRITE)
+ stmt = (infer accessor ?name:#id! #=! ?s:#exp![?i:#exp$]) : DefAccessor(first-info(form),name, s, i,INFER)
+ stmt = (rdwr accessor ?name:#id! #=! ?s:#exp![?i:#exp$]) : DefAccessor(first-info(form),name, s, i,RDWR)
stmt = (?s:#stmt/when) : s
stmt = (?x:#exp := ?y:#exp!) : Connect(first-info(form),x, y)
stmt = (?x:#exp <> ?y:#exp!) : BulkConnect(first-info(form),x, y)
- stmt = (on-reset ?x:#exp := ?y:#exp!) : OnReset(first-info(form),x, y)
stmt = ((?s:#stmt ?ss:#stmt ... ?rest ...)) :
if not empty?(rest) :
diff --git a/src/main/stanza/ir-utils.stanza b/src/main/stanza/ir-utils.stanza
index e29bf4ac..8e65005f 100644
--- a/src/main/stanza/ir-utils.stanza
+++ b/src/main/stanza/ir-utils.stanza
@@ -98,7 +98,15 @@ defmethod print (o:OutputStream, d:Flip) :
DEFAULT : ""
REVERSE: "flip"
-defmethod print (o:OutputStream, d:Direction) :
+defmethod print (o:OutputStream, d:AccDirection) :
+ print{o, _} $
+ switch {d == _} :
+ READ : "read"
+ WRITE: "write"
+ INFER: "infer"
+ RDWR: "rdwr"
+
+defmethod print (o:OutputStream, d:PortDirection) :
print{o, _} $
switch {d == _} :
INPUT : "input"
@@ -177,12 +185,16 @@ defmethod print (o:OutputStream, c:Stmt) :
(c:DefNode) :
print-all(o,["node " name(c) " = " value(c)])
(c:DefAccessor) :
- print-all(o,["accessor " name(c) " = " source(c) "[" index(c) "]"])
+ print-all(o,[acc-dir(c) " accessor " name(c) " = " source(c) "[" index(c) "]"])
(c:Conditionally) :
- print-all(o, ["when " pred(c) " :"])
- print-debug(o,c)
- print(o,"\n")
- print(io,conseq(c))
+ if conseq(c) typeof Begin :
+ print-all(o, ["when " pred(c) " :"])
+ print-debug(o,c)
+ print(o,"\n")
+ print(io,conseq(c))
+ else :
+ print-all(o, ["when " pred(c) " : " conseq(c)])
+ print-debug(o,c)
if alt(c) not-typeof EmptyStmt :
print(o, "\nelse :")
print(io, "\n")
@@ -277,7 +289,7 @@ defmethod map (f: Expression -> Expression, e:Expression) -> Expression :
public defmulti map<?T> (f: Expression -> Expression, c:?T&Stmt) -> T
defmethod map (f: Expression -> Expression, c:Stmt) -> Stmt :
match(c) :
- (c:DefAccessor) : DefAccessor(info(c),name(c), f(source(c)), f(index(c)))
+ (c:DefAccessor) : DefAccessor(info(c),name(c), f(source(c)), f(index(c)),acc-dir(c))
(c:DefNode) : DefNode(info(c),name(c), f(value(c)))
(c:DefInstance) : DefInstance(info(c),name(c), f(module(c)))
(c:Conditionally) : Conditionally(info(c),f(pred(c)), conseq(c), alt(c))
diff --git a/src/main/stanza/passes.stanza b/src/main/stanza/passes.stanza
index 86ef5b26..d170ee1c 100644
--- a/src/main/stanza/passes.stanza
+++ b/src/main/stanza/passes.stanza
@@ -27,7 +27,8 @@ public val standard-passes = to-list $ [
Inline()
SplitExp()
CheckLowForm()
- ToRealIR() ]
+ ToRealIR()
+ Pad() ]
;=============== WORKING IR ================================
public definterface Kind
public defstruct WireKind <: Kind
@@ -108,13 +109,13 @@ defn swap (f:Flip) -> Flip :
DEFAULT : REVERSE
REVERSE : DEFAULT
-defn swap (d:Direction) -> Direction :
+defn swap (d:PortDirection) -> PortDirection :
switch {_ == d} :
OUTPUT : INPUT
INPUT : OUTPUT
-public defn times (flip:Flip,d:Direction) -> Direction : flip * d
-public defn times (d:Direction,flip:Flip) -> Direction :
+public defn times (flip:Flip,d:PortDirection) -> PortDirection : flip * d
+public defn times (d:PortDirection,flip:Flip) -> PortDirection :
switch {_ == flip} :
DEFAULT : d
REVERSE : swap(d)
@@ -135,13 +136,13 @@ defn to-field (p:Port) -> Field :
else if direction(p) == INPUT : Field(name(p),REVERSE,type(p))
else : error("Shouldn't be here")
-defn to-dir (g:Gender) -> Direction :
+defn to-dir (g:Gender) -> PortDirection :
switch {_ == g} :
MALE : INPUT
FEMALE : OUTPUT
defn gender (s:DefAccessor) -> Gender :
- switch {_ == dir(s)} :
+ switch {_ == acc-dir(s)} :
READ : MALE
WRITE : FEMALE
INFER : UNKNOWN-GENDER
@@ -331,6 +332,8 @@ defn to-working-ir (c:Circuit) :
(e:Subfield) : WSubfield(exp(e), name(e), type(e), UNKNOWN-GENDER)
(e:Index) : WIndex(exp(e), value(e), type(e), UNKNOWN-GENDER)
(e) : e
+ defn to-stmt (s:Stmt) -> Stmt :
+ map{to-stmt,_} $ map(to-exp,s)
Circuit(info(c),modules*, main(c)) where :
val modules* =
@@ -1345,7 +1348,7 @@ public defn expand-whens (c:Circuit) -> Circuit :
if direction(p) == OUTPUT :
val ref = WRef(name(p),type(p),PortKind(),FEMALE)
if has-nul?(table[name(p)]) :
- add(errors,RefNotInitialized(info(p), name(p))
+ add(errors,RefNotInitialized(info(p), name(p)))
else : add{cons,_} $ Connect(FileInfo(),ref,to-exp(table[name(p)]) as Expression)
defn expand-whens (s:Stmt, table:HashTable<Symbol,SymbolicValue>,decs:Vector<Stmt>,cons:Vector<Stmt>) -> Stmt :
@@ -1355,7 +1358,7 @@ public defn expand-whens (c:Circuit) -> Circuit :
add(decs,s)
val ref = WRef(name(s),type(s),NodeKind(),FEMALE)
if has-nul?(table[name(s)]) :
- add(errors,RefNotInitialized(info(s), name(s))
+ add(errors,RefNotInitialized(info(s), name(s)))
else : add{cons,_} $ Connect(info(s),ref,to-exp(table[name(s)]) as Expression)
(s:DefRegister) :
add(decs,s)
@@ -1364,12 +1367,12 @@ public defn expand-whens (c:Circuit) -> Circuit :
(e:Expression) :
val ref = WRef(name(s),type(s),NodeKind(),FEMALE)
val en = to-exp(optimize $ get-write-enable(table[name(s)])) as Expression
- if en == UIntValue(1,UnknownWidth()) :
+ if en == UIntValue(to-long(1),UnknownWidth()) :
add{cons,_} $ Connect(info(s),ref,e)
else :
- add{cons,_} $ Conditionally(en,Connect(info(s),ref,e),EmptyStmt())
+ add{cons,_} $ Conditionally(info(s),en,Connect(info(s),ref,e),EmptyStmt())
(e:False) :
- add(errors,RefNotConnected(info(s), name(s))
+ add(errors,RefNotConnected(info(s), name(s)))
(s:DefAccessor) :
add(decs,s)
val t = type(type(source(s)) as VectorType)
@@ -1380,12 +1383,12 @@ public defn expand-whens (c:Circuit) -> Circuit :
match(e) :
(e:Expression) :
val en = (to-exp $ optimize $ get-write-enable(table[n])) as Expression
- if en == UIntValue(1,UnknownWidth()) :
+ if en == UIntValue(to-long(1),UnknownWidth()) :
add{cons,_} $ Connect(info(s),ref,e)
else :
- add{cons,_} $ Conditionally(en,Connect(info(s),ref,e),EmptyStmt())
+ add{cons,_} $ Conditionally(info(s),en,Connect(info(s),ref,e),EmptyStmt())
(e:False) :
- add(errors,RefNotConnected(info(s), n)
+ add(errors,RefNotConnected(info(s), n))
(s:DefInstance) :
add(decs,s)
for f in fields(type(module(s)) as BundleType) map :
@@ -1396,7 +1399,7 @@ public defn expand-whens (c:Circuit) -> Circuit :
val ref = WRef(x,type(module(s)),InstanceKind(),FEMALE)
val sref = WSubfield(ref,f,bundle-field-type(type(module(s)),f),FEMALE)
if has-nul?(table[n]) :
- add(errors,RefNotInitialized(info(s), n)
+ add(errors,RefNotInitialized(info(s), n))
else : add{cons,_} $ Connect(info(s),sref,to-exp(table[n]) as Expression)
(s:Connect|Conditionally|OnReset|Begin|EmptyStmt) : false
s
@@ -1407,7 +1410,7 @@ public defn expand-whens (c:Circuit) -> Circuit :
(m:InModule) :
val assign = HashTable<Symbol,SymbolicValue>(symbol-hash)
val resets = HashTable<Symbol,SymbolicValue>(symbol-hash)
- ;val flattn = HashTable<Symbol,True|False>(symbol-hash)
+ val flattn = HashTable<Symbol,True|False>(symbol-hash)
for p in ports(m) do :
if direction(p) == OUTPUT :
@@ -1434,10 +1437,12 @@ public defn expand-whens (c:Circuit) -> Circuit :
expand-whens(body(m),table,decs,cons)
InModule(info(m),name(m),ports(m),Begin(append(to-list(decs),to-list(cons))))
- Circuit(info(c),modules*, main(c)) where :
+ val c* = Circuit(info(c),modules*, main(c)) where :
val modules* =
for m in modules(c) map :
expand-whens(m)
+ throw(PassExceptions(errors)) when not empty?(errors)
+ c*
;;================ INFER WIDTHS =============================
@@ -1657,6 +1662,8 @@ defn gen-constraints (m:Module, h:HashTable<Symbol,Type>, v:Vector<WGeq>) -> Mod
defn gen-constraints-s (s:Stmt) -> Stmt :
match(map(gen-constraints-s,s)) :
(s:DefWire) : DefWire(info(s),name(s),h[name(s)])
+ (s:DefRegister) : DefRegister(info(s),name(s),h[name(s)])
+ (s:DefAccessor) : DefAccessor(info(s),name(s),gen-constraints(source(s)),gen-constraints(index(s)), acc-dir(s))
(s:DefInstance) : DefInstance(info(s),name(s),gen-constraints(module(s)))
(s:DefMemory) : DefMemory(info(s),name(s),h[name(s)] as VectorType,seq?(s))
(s:DefNode) :
@@ -1675,7 +1682,7 @@ defn gen-constraints (m:Module, h:HashTable<Symbol,Type>, v:Vector<WGeq>) -> Mod
val p = gen-constraints(pred(s))
add(v,WGeq(width!(type(p)),IntWidth(1)))
add(v,WGeq(IntWidth(1),width!(type(p))))
- Conditionally(info(s),p,conseq(s),alt(s))
+ map(gen-constraints-s,Conditionally(info(s),p,conseq(s),alt(s)))
(s) : s
defn gen-constraints (e:Expression) -> Expression :
@@ -1711,8 +1718,11 @@ defn build-environment (c:Circuit,m:Module,h:HashTable<Symbol,Type>) -> HashTabl
defn build-environment (s:Stmt) -> False :
match(s) :
(s:DefWire) : h[name(s)] = remove-unknowns(type(s))
+ (s:DefRegister) : h[name(s)] = remove-unknowns(type(s))
(s:DefInstance) : h[name(s)] = h[name(module(s) as WRef)]
(s:DefMemory) : h[name(s)] = remove-unknowns(type(s))
+ (s:DefAccessor) :
+ h[name(s)] = remove-unknowns(type(type(source(s)) as VectorType))
(s:DefNode) : h[name(s)] = remove-unknowns(type(value(s)))
(s) : false
do(build-environment,s)
@@ -1749,7 +1759,9 @@ defn reduce-var-widths (c:Circuit,h:HashTable<Symbol,Width>) -> Circuit :
(w:MinusWidth) : apply(solve(arg1(w)),solve(arg2(w)),{_ - _})
(w:ExpWidth) : apply(2,solve(arg1(w)),{pow(_,_) - 1})
(w:IntWidth) : width(w)
- (w) : error("Shouldn't be here")
+ (w) :
+ println(w)
+ error("Shouldn't be here")
val s = solve(w)
if s typeof Int : IntWidth(s as Int)
@@ -1892,14 +1904,16 @@ defn split-exp (c:Circuit) :
add(v,DefNode(info,n*,e))
WRef(n*,type(e),NodeKind(),UNKNOWN-GENDER)
(e) : e
+ defn f (s:Stmt) -> False: split-exp-s(s,v,sh)
match(s) :
(s:Begin) :
- defn f (s:Stmt) -> False: split-exp-s(s,v,sh)
do(f,s)
- (s:Conditionally) : error("Shouldn't be here")
+ (s:Conditionally) :
+ add(v,map(split-exp-e{_,false,info(s)},s))
+ do(f,s)
(s:Connect) :
match(loc(s)) :
- (e:WritePort) : add(v,map(split-exp-e{_,full-name(exp(s)),info(s)},s))
+ ;(e:WritePort) : add(v,map(split-exp-e{_,full-name(exp(s)),info(s)},s))
(e) : add(v,map(split-exp-e{_,full-name(loc(s)),info(s)},s))
(s:DefNode) : add(v,map(split-exp-e{_,name(s),info(s)},s))
(s) : add(v,map(split-exp-e{_,false,info(s)},s))
@@ -1937,7 +1951,6 @@ defn to-real-ir (c:Circuit) :
(e) : e
defn to-stmt (s:Stmt) :
match(map(to-exp,s)) :
- (e:DefAccessor) : error("Shouldn't be here")
(e:ConnectToIndexed) : error("Shouldn't be here")
(e:ConnectFromIndexed) : error("Shouldn't be here")
(e) : map(to-stmt,e)
@@ -1996,7 +2009,7 @@ public defn special-rename (original-sym:Symbol,new-sym:Symbol,c:Circuit) :
(s:DefInstance) : DefInstance(info(s),rename(name(s)),module(s))
(s:DefMemory) : DefMemory(info(s),rename(name(s)),type(s),seq?(s))
(s:DefNode) : DefNode(info(s),rename(name(s)),value(s))
- (s:DefAccessor) : DefAccessor(info(s),rename(name(s)),source(s),index(s))
+ (s:DefAccessor) : DefAccessor(info(s),rename(name(s)),source(s),index(s),acc-dir(s))
(s) : map(to-stmt,s)
defn to-port (p:Port) -> Port : Port(info(p),rename(name(p)),direction(p),type(p))
@@ -2009,3 +2022,80 @@ public defn special-rename (original-sym:Symbol,new-sym:Symbol,c:Circuit) :
(m:ExModule) : m
+;========== Pad Widths ==================
+
+public defstruct Pad <: Pass
+public defmethod pass (b:Pad) -> (Circuit -> Circuit) : pad-widths
+public defmethod name (b:Pad) -> String : "Pad Widths"
+
+defn int-width! (t:Type) -> Int :
+ match(width!(t)) :
+ (w:IntWidth) : width(w)
+ (w) : error("Non-int width")
+
+defn set-width (desired:Int,t:Type) -> Type :
+ match(t) :
+ (t:UIntType) : UIntType(IntWidth(desired))
+ (t:SIntType) : SIntType(IntWidth(desired))
+ (t) : error("Non-ground type")
+
+defn pad-widths-e (desired:Int,e:Expression) -> Expression :
+ defn trim (desired:Int, e:Expression) :
+ ;; println-all(["TRIM " desired " e " e])
+ DoPrim(BITS-SELECT-OP,list(e),list(desired - 1, 0),set-width(desired,type(e)))
+ defn pad (desired:Int, e:Expression) :
+ ;; println-all(["PAD " desired " e " e])
+ DoPrim(PAD-OP,list(e),list(desired),set-width(desired,type(e)))
+ defn trim-pad (desired:Int, e:Expression) :
+ val i = int-width!(type(e))
+ if i > desired : trim(desired, e)
+ else if i == desired : e
+ else : pad(desired, e)
+ defn self-pad-widths-e (e:Expression) -> Expression :
+ pad-widths-e(int-width!(type(e)), e)
+ ;; println-all(["PAD-E " desired " " e])
+ match(e) :
+ (e:DoPrim) :
+ val new-desired = reduce(max, 0, map(int-width!{type(_)}, args(e)))
+ ;; println-all([" NEW DESIRED " new-desired])
+ val e* =
+ if contains?([CONCAT-OP, DYN-SHIFT-RIGHT-OP, DYN-SHIFT-LEFT-OP], op(e)) :
+ DoPrim(op(e), map(self-pad-widths-e, args(e)), consts(e), type(e))
+ else if contains?([MUX-OP], op(e)) :
+ DoPrim(op(e), list(pad-widths-e(1, args(e)[0]), pad-widths-e(new-desired, args(e)[1]), pad-widths-e(new-desired, args(e)[2])), consts(e), type(e))
+ else :
+ map(pad-widths-e{new-desired,_},e)
+ trim-pad(desired, e*)
+ (e:WRef|WSubfield|WIndex) :
+ trim-pad(desired, e)
+ (e:UIntValue) :
+ val i = int-width!(type(e))
+ if i > desired : trim(desired, e)
+ else : UIntValue(value(e),IntWidth(desired))
+ (e:SIntValue) :
+ val i = int-width!(type(e))
+ if i > desired : trim(desired, e)
+ else : SIntValue(value(e),IntWidth(desired))
+ (e) : error(to-string $ e)
+
+defn pad-widths-s (s:Stmt) -> Stmt :
+ ;; println-all(["PAD-S " s])
+ match(map(pad-widths-s,s)) :
+ (s:Connect) :
+ val i = int-width!(type(loc(s)))
+ val loc* = pad-widths-e(i,loc(s))
+ val exp* = pad-widths-e(i,exp(s))
+ Connect(info(s),loc*,exp*)
+ (s:DefNode) :
+ val i = int-width!(type(value(s)))
+ val exp* = pad-widths-e(i,value(s))
+ DefNode(info(s),name(s),exp*)
+ (s) : s
+
+public defn pad-widths (c:Circuit) -> Circuit :
+ Circuit{info(c),_,main(c)} $
+ for m in modules(c) map :
+ match(m) :
+ (m:ExModule) : m
+ (m:InModule) : InModule(info(m),name(m),ports(m),pad-widths-s(body(m)))
+
diff --git a/src/main/stanza/verilog.stanza b/src/main/stanza/verilog.stanza
index 0e04df8a..0367c333 100644
--- a/src/main/stanza/verilog.stanza
+++ b/src/main/stanza/verilog.stanza
@@ -4,43 +4,6 @@ defpackage firrtl/verilog :
import firrtl/ir-utils
import firrtl/ir2
-public defstruct RemoveSeqMem <: Pass
-public defmethod pass (b:RemoveSeqMem) -> (Circuit -> Circuit) : remove-smem{_}
-public defmethod name (b:RemoveSeqMem) -> String : "Remove SeqMem"
-public defmethod short-name (b:RemoveSeqMem) -> String : "remove-smem"
-
-
-;============ Utilz =============
-
-;============ Remove Seq Mem =============
-
-defn remove-smem (m:InModule) -> InModule :
- val hash = get-sym-hash(m)
- val smems = Vector<Symbol>()
- defn remove-smem-s (s:Stmt) -> Stmt :
- map{remove-smem-s,_} $ match(s) :
- (s:DefMemory) :
- if seq?(s) : add(smems,name(s))
- DefMemory(info(s),name(s),type(s),false)
- (s:DefAccessor) :
- if dir(s) == WRITE and contains?(smems, name(source(s) as Ref)) :
- val regged-index = firrtl-gensym(name(index(s) as Ref),hash)
- val ref = Ref(regged-index,type(index(s)))
- Begin $ to-list $
- [ DefRegister(info(s),regged-index,type(index(s)))
- Connect(ref,index(s))
- DefAccessor(info(s),dir(s),name(s),source(s),ref) ]
- else : s
- (s) : s
-
- InModule(info(m),name(m),ports(m),remove-smem-s(body(m),hash))
-
-public defn remove-smem (c:Circuit) -> Circuit :
- for m in modules(c) do :
- match(m) :
- (m:InModule) : remove-smem(m)
- (m:ExModule) : m
-
;============ VERILOG ==============
public defstruct Verilog <: Pass :
@@ -49,10 +12,6 @@ public defmethod pass (b:Verilog) -> (Circuit -> Circuit) : emit-verilog{file(b)
public defmethod name (b:Verilog) -> String : "To Verilog"
public defmethod short-name (b:Verilog) -> String : "To Verilog"
-defstruct DecAndConnect :
- dec : Stmt
- con : Connect
-
;============ Utilz =============
defn width! (w:Width) -> Int :
match(w) :
@@ -105,9 +64,6 @@ defn emit (e:Expression) -> String :
(e:SIntValue) : string-join $ [width!(type(e)) "'sd" value(e)]
(e:Subfield) : error("Non-supported expression")
(e:Index) : error("Non-supported expression")
- (e:Register) : error("Non-supported expression")
- (e:ReadPort) : error("Non-supported expression")
- (e:WritePort) : error("Non-supported expression")
(e:DoPrim) :
val sargs = map(emit-as-type{_,type(e)},args(e))
val xargs = map(emit-signed-if-any{_,args(e)},args(e))
@@ -184,18 +140,20 @@ defn get-name (e:Expression) -> Symbol :
(e) : error("Shouldn't be here")
defn emit-module (m:InModule) :
- val decs = HashTable<Symbol,Stmt>(sym-hash) ; all declarations
- val cons = HashTable<Symbol,Stmt>(sym-hash) ; all connections
+ val decs = HashTable<Symbol,Stmt>(symbol-hash) ; all declarations
+ val cons = HashTable<Symbol,Expression>(symbol-hash) ; all connections
+ val ens = HashTable<Symbol,Expression>(symbol-hash) ; all enables
defn build-table (m:InModule) :
defn build-table (s:Stmt) -> Stmt :
match(map(build-table,map(remove-subfield,s))) :
- (s:DefWire|DefReg|DefAccessor|DefMemory|DefNode|DefInstance) : decs[name(s)] = s
+ (s:DefWire|DefRegister|DefAccessor|DefMemory|DefNode|DefInstance) : decs[name(s)] = s
(s:Conditionally) :
val n = get-name(loc(conseq(s) as Connect))
- cons[n] = s
+ ens[n] = pred(s)
+ cons[n] = exp(conseq(s) as Connect)
(s:Connect) :
val n = get-name(loc(s))
- cons[n] = s
+ cons[n] = exp(s)
(s) : false
s
build-table(body(m))
@@ -211,135 +169,59 @@ defn emit-module (m:InModule) :
val sh = get-sym-hash(m)
- for (sym -> dec) in decs do :
- match(value(dec)) :
- (dec:DefWire) :
- add(wires,["wire " get-width(type(s)) " " name(s) ";"])
- emit-blocking-connect(cons[sym])
- (dec:DefRegister) :
- add(regs,["reg " get-width(type(s)) " " name(s) ";"])
- emit-nonblocking-connect(cons[sym])
- (dec:DefMemory) :
+ for x in decs do :
+ val sym = key(x)
+ match(value(x)) :
+ (s:DefWire) :
+ add(wires,["wire " get-width(type(s)) " " sym ";"])
+ add(assigns,["assign " sym " = " emit(cons[sym]) ";"])
+ (s:DefRegister) :
+ add(regs,["reg " get-width(type(s)) " " sym ";"])
+ if key?(ens,sym) :
+ add(updates,["if(" emit(ens[sym]) ") begin"])
+ add(updates,[" " sym " <= " emit(cons[sym]) ";"])
+ add(updates,["end"])
+ else :
+ add(updates,[sym " <= " emit(cons[sym]) ";"])
+ (s:DefMemory) :
val vtype = type(s) as VectorType
- add(regs,["reg " get-width(type(vtype)) " " name(s) " [0:" size(vtype) "];"])
+ add(regs,["reg " get-width(type(vtype)) " " sym " [0:" size(vtype) "];"])
add(inits,["for (initvar = 0; initvar < " size(vtype) "; initvar = initvar+1)"])
- add(inits,[" " name(s) "[initvar] = {" width!(type(vtype)) "{$random}};"])
+ add(inits,[" " sym "[initvar] = {" width!(type(vtype)) "{$random}};"])
(s:DefNode) :
- add(wires,["wire " get-width(type(value(s))) " " name(s) ";"])
- add(assigns,["assign " name(s) " = " emit(value(s)) ";"])
+ add(wires,["wire " get-width(type(value(s))) " " sym ";"])
+ add(assigns,["assign " sym " = " emit(value(s)) ";"])
(s:DefInstance) :
- inst-ports[name(s)] = Vector<Streamable>()
- insts[name(s)] = name(module(s) as Ref)
+ inst-ports[sym] = Vector<Streamable>()
+ insts[sym] = name(module(s) as Ref)
for f in fields(type(module(s)) as BundleType) do :
- val n* = to-symbol $ string-join $ [name(s) "_" name(f)]
+ val n* = to-symbol $ string-join $ [sym "_" name(f)]
add(wires,["wire " get-width(type(f)) " " n* ";"])
- add(inst-ports[name(s)], ["." name(f) "( " n* " )"])
+ add(inst-ports[sym], ["." name(f) "( " n* " )"])
(s:DefAccessor) :
- switch {_ == dir(s)} :
+ switch {_ == acc-dir(s)} :
READ :
val mem-declaration = decs[name(source(s) as Ref)]
- val con = cons[sym]
- if seq?(mem-declaration) :
+ if seq?(mem-declaration as DefMemory) :
+ ; to make it sequential, register the index for an additional cycle
val index* = Ref(firrtl-gensym(name(index(s) as Ref),sh),type(index(s)))
- add(regs,[ "reg " get-width(type(index*)) " " name(index*) ";"]) ; to make it sequential, register the index for an additional cycle
+ add(regs,[ "reg " get-width(type(index*)) " " name(index*) ";"])
add(inits,[name(index*) " = {" width!(type(index*)) "{$random}};"])
add(updates,[name(index*) " <= " emit(index(s)) ";"])
- add(assigns,["assign " n " = " emit(mem(s)) "[" emit(index*) "];"])
- else :
- add(assigns,["assign " n " = " emit(mem(s)) "[" emit(index(s)) "];"])
-
-
-
-
- defn emit-blocking-connect (s:Stmt) :
- match(s) :
- (s:Connect) : add(assigns,["assign " emit(loc(s)) " = " emit(exp(s)) ";"])
- (s:Conditionally) : error("Shouldn't be here")
- defn emit-nonblocking-connect (s:Stmt) :
- match(s) :
- (s:Connect) :
- add(updates,[n " <= " emit(value(reg)) ";"])
- (s:Conditionally) :
- match(conseq(s)) :
- (c:Connect) :
- add(updates,["if(" emit(pred(s)) ") begin"])
- add(updates,[" " emit(loc(c) " <= " emit(exp(c)) ";"])
- add(updates,["end"])
- (c) : error("Shouldn't be here")
- (s) : error("Shouldn't be here")
-
-; add(updates,["if(" en ") begin"])
-; add(updates,[" " emit(mem(wp)) "[" emit(index(wp)) "] <= " emit(exp(s)) ";"])
-; add(updates,["end"])
-; else :
-; if exp(s) typeof Register :
-; val n = name(loc(s) as Ref)
-; val reg = exp(s) as Register
-; add(inits,[n " = {" width!(type(reg)) "{$random}};"])
-; add(updates,["if(" emit(enable(reg)) ") begin"])
-; add(updates,[" " n " <= " emit(value(reg)) ";"])
-; add(updates,["end"])
-; else if exp(s) typeof ReadPort :
-; val n = name(loc(s) as Ref)
-; val rp = exp(s) as ReadPort
-; match(h[name(mem(rp) as Ref)]) :
-; (k:SeqMemKind) :
-; val index* = Ref(firrtl-gensym(name(index(rp) as Ref),sh),type(index(rp)))
-; add(regs,[ "reg " get-width(type(index*)) " " name(index*) ";"])
-; add(inits,[name(index*) " = {" width!(type(index*)) "{$random}};"])
-; add(updates,["if(" emit(enable(rp)) ") begin"])
-; add(updates,[" " name(index*) " <= " emit(index(rp)) ";"])
-; add(updates,["end"])
-; add(assigns,["assign " n " = " emit(mem(rp)) "[" emit(index*) "];"])
-; (k:ComMemKind) :
-; add(assigns,["assign " n " = " emit(mem(rp)) "[" emit(index(rp)) "];"])
-; else :
-; add(assigns,["assign " emit(loc(s)) " = " emit(exp(s)) ";"])
-
- defn emit-s (s:Stmt) :
- match(s) :
- (s:DefWire) :
- add(wires,["wire " get-width(type(s)) " " name(s) ";"])
- add(assigns,["assign " emit(loc(s)) " = " emit(exp(s)) ";"])
+ ; emit read accessor
+ add(assigns,["assign " sym " = " emit(source(s)) "[" emit(index*) "];"])
+ else :
+ ; emit read accessor
+ add(assigns,["assign " sym " = " emit(source(s)) "[" emit(index(s)) "];"])
+ WRITE :
+ if key?(ens,sym) :
+ add(updates,["if(" emit(ens[sym]) ") begin"])
+ add(updates,[" " emit(source(s)) "[" emit(index(s)) "] <= " emit(cons[sym]) ";"])
+ add(updates,["end"])
+ else :
+ add(updates,[emit(source(s)) "[" emit(index(s)) "] <= " emit(cons[sym]) ";"])
- (s:DefRegister) : add(regs,["reg " get-width(type(s)) " " name(s) ";"])
- (s:DefAccessor) :
- switch {_ == dir(s)} :
- READ :
- match(h[name(source(s) as Ref)]) :
- (k:SeqMemKind) :
- val index* = Ref(firrtl-gensym(name(index(rp) as Ref),sh),type(index(rp)))
- add(regs,[ "reg " get-width(type(index*)) " " name(index*) ";"])
- add(inits,[name(index*) " = {" width!(type(index*)) "{$random}};"])
- add(updates,["if(" emit(enable(rp)) ") begin"])
- add(updates,[" " name(index*) " <= " emit(index(rp)) ";"])
- add(updates,["end"])
- add(assigns,["assign " n " = " emit(mem(rp)) "[" emit(index*) "];"])
- (k:ComMemKind) :
- add(assigns,["assign " n " = " emit(mem(rp)) "[" emit(index(rp)) "];"])
- (s:DefInstance) :
- inst-ports[name(s)] = Vector<Streamable>()
- insts[name(s)] = name(module(s) as Ref)
- for f in fields(type(module(s)) as BundleType) do :
- val n* = to-symbol $ string-join $ [name(s) "_" name(f)]
- add(wires,["wire " get-width(type(f)) " " n* ";"])
- add(inst-ports[name(s)], ["." name(f) "( " n* " )"])
- (s:DefMemory) :
- val vtype = type(s) as VectorType
- add(regs,["reg " get-width(type(vtype)) " " name(s) " [0:" size(vtype) "];"])
- add(inits,["for (initvar = 0; initvar < " size(vtype) "; initvar = initvar+1)"])
- add(inits,[" " name(s) "[initvar] = {" width!(type(vtype)) "{$random}};"])
- (s:DefNode) :
- add(wires,["wire " get-width(type(value(s))) " " name(s) ";"])
- add(assigns,["assign " name(s) " = " emit(value(s)) ";"])
- (s:Begin) : do(emit-s, body(s))
- (s:Conditionally) : emit-pred-connect(pred(s),conseq(s) as Connect)
- (s:Connect) : emit-pred-connect(UIntValue(1,1),s)
- (s) : s
-
-
-
;==== Actually printing module =====
val port-indent = " "
print-all(["module " name(m) "(input clk, input reset,\n"])
diff --git a/test/passes/expand-accessors/accessor-mem.fir b/test/passes/expand-accessors/accessor-mem.fir
index eb396bcf..0daec379 100644
--- a/test/passes/expand-accessors/accessor-mem.fir
+++ b/test/passes/expand-accessors/accessor-mem.fir
@@ -6,15 +6,17 @@ circuit top :
cmem m : UInt<32>[2][2][2]
wire i : UInt<4>
i := UInt(1)
- accessor a = m[i] ;CHECK: accessor a = m[i]
- accessor b = a[i] ;CHECK: b := (a[0] a[1])[i]
- accessor c = b[i] ;CHECK: c := (b[0] b[1])[i]
+ infer accessor a = m[i] ;CHECK: read accessor a = m[i]
+ infer accessor b = a[i] ;CHECK: b := (a[0] a[1])[i]
+ infer accessor c = b[i] ;CHECK: c := (b[0] b[1])[i]
wire j : UInt
j := c
- accessor x = m[i] ;CHECK: accessor x = m[i]
- accessor y = x[i] ;CHECK: (x[0] x[1])[i] := y
- accessor z = y[i] ;CHECK: (y[0] y[1])[i] := z
+ infer accessor x = m[i] ;CHECK: write accessor x = m[i]
+ infer accessor y = x[i] ;CHECK: (x[0] x[1])[i] := y
+ y[0] := UInt(1)
+ y[1] := UInt(1)
+ infer accessor z = y[i] ;CHECK: (y[0] y[1])[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 81c44d1b..5cdad6c7 100644
--- a/test/passes/expand-accessors/accessor-vec.fir
+++ b/test/passes/expand-accessors/accessor-vec.fir
@@ -4,25 +4,43 @@
circuit top :
module top :
wire m : UInt<32>[2][2][2]
+ m[0][0][0] := UInt(1)
+ m[1][0][0] := UInt(1)
+ m[0][1][0] := UInt(1)
+ m[1][1][0] := UInt(1)
+ m[0][0][1] := UInt(1)
+ m[1][0][1] := UInt(1)
+ m[0][1][1] := UInt(1)
+ m[1][1][1] := UInt(1)
wire i : UInt
i := UInt(1)
- accessor a = m[i] ;CHECK: a := (m[0] m[1])[i]
- accessor b = a[i] ;CHECK: b := (a[0] a[1])[i]
- accessor c = b[i] ;CHECK: c := (b[0] b[1])[i]
+ infer accessor a = m[i] ;CHECK: a := (m[0] m[1])[i]
+ infer accessor b = a[i] ;CHECK: b := (a[0] a[1])[i]
+ infer accessor c = b[i] ;CHECK: c := (b[0] b[1])[i]
wire j : UInt
j := c
- accessor x = m[i] ;CHECK: (m[0] m[1])[i] := x
- accessor y = x[i] ;CHECK: (x[0] x[1])[i] := y
- accessor z = y[i] ;CHECK: (y[0] y[1])[i] := z
+ infer accessor x = m[i] ;CHECK: (m[0] m[1])[i] := x
+ x[0][0] := UInt(1)
+ x[1][0] := UInt(1)
+ x[0][1] := UInt(1)
+ x[1][1] := UInt(1)
+ infer accessor y = x[i] ;CHECK: (x[0] x[1])[i] := y
+ infer accessor z = y[i] ;CHECK: (y[0] y[1])[i] := z
+ y[0] := UInt(1)
+ y[1] := UInt(1)
z := j
wire p : {n : UInt<32>[2]}
- accessor q = p.n[i] ;CHECK: (p.n[0] p.n[1])[i] := q
+ p.n[0] := UInt(1)
+ p.n[1] := UInt(1)
+ infer accessor q = p.n[i] ;CHECK: (p.n[0] p.n[1])[i] := q
q := j
wire r : {m : UInt<32>}[2]
- accessor s = r[i] ;CHECK: s := (r[0] r[1])[i]
+ r[0].m := UInt(1)
+ r[1].m := UInt(1)
+ infer accessor s = r[i] ;CHECK: s := (r[0] r[1])[i]
j := s.m
; CHECK: Finished Expand Accessors
diff --git a/test/passes/expand-connect-indexed/bundle-vecs.fir b/test/passes/expand-connect-indexed/bundle-vecs.fir
index 9d375087..ea453ab1 100644
--- a/test/passes/expand-connect-indexed/bundle-vecs.fir
+++ b/test/passes/expand-connect-indexed/bundle-vecs.fir
@@ -12,7 +12,7 @@ circuit top :
; CHECK: wire a$1$x : UInt<32>
; CHECK: wire a$1$y : UInt<32>
- accessor b = a[i]
+ infer accessor b = a[i]
; CHECK: wire b$x : UInt<32>
; CHECK: wire b$y : UInt<32>
; CHECK: b$x := a$0$x
diff --git a/test/passes/expand-whens/bundle-init.fir b/test/passes/expand-whens/bundle-init.fir
index 4f8c31e2..261ebf02 100644
--- a/test/passes/expand-whens/bundle-init.fir
+++ b/test/passes/expand-whens/bundle-init.fir
@@ -15,8 +15,8 @@ circuit top :
r.y := b
on-reset r := w
-; CHECK: r$x := Register(mux(reset, w$x, a), UInt(1))
-; CHECK: r$y := Register(b, UInt(1))
+; CHECK: when UInt(1) : r$x := mux(reset, w$x, a)
+; CHECK: when UInt(1) : r$y := b
; CHECK: a := UInt(1)
; CHECK: b := UInt(2)
; CHECK: w$x := b
diff --git a/test/passes/expand-whens/nested-whens.fir b/test/passes/expand-whens/nested-whens.fir
index f7ac8337..4d23a549 100644
--- a/test/passes/expand-whens/nested-whens.fir
+++ b/test/passes/expand-whens/nested-whens.fir
@@ -11,6 +11,14 @@ circuit top :
wire y : UInt
wire z : UInt
wire w : UInt
+ p := UInt(1)
+ q := UInt(1)
+ a := UInt(1)
+ b := UInt(1)
+ x := UInt(1)
+ y := UInt(1)
+ z := UInt(1)
+ w := UInt(1)
on-reset r := w
when p :
@@ -20,5 +28,5 @@ circuit top :
on-reset r := y
r := b
r := z
-; CHECK: r := Register(mux(reset, mux(q, y, mux(p, x, w)), z), UInt(1))
+; CHECK: when UInt(1) : r := mux(reset, mux(q, y, mux(p, x, w)), z)
; CHECK: Finished Expand Whens
diff --git a/test/passes/expand-whens/one-when.fir b/test/passes/expand-whens/one-when.fir
index 114e5b5b..4e6ea1e5 100644
--- a/test/passes/expand-whens/one-when.fir
+++ b/test/passes/expand-whens/one-when.fir
@@ -7,21 +7,22 @@ circuit top :
wire i : UInt<1>
wire p : UInt<1>
wire j : UInt<1>
+ j := UInt(1)
reg r : UInt<1>
p := j
when p :
on-reset r := i
- accessor a = m[i]
+ infer accessor a = m[i]
i := a
- accessor b = m[i]
+ infer accessor b = m[i]
b := i
else :
- accessor c = m[i]
+ infer accessor c = m[i]
i := c
- accessor d = m[i]
+ infer accessor d = m[i]
d := i
- accessor e = m[i]
+ infer accessor e = m[i]
when p :
p := i
when e :
diff --git a/test/passes/expand-whens/partial-init.fir b/test/passes/expand-whens/partial-init.fir
index c9afd86c..03b1f965 100644
--- a/test/passes/expand-whens/partial-init.fir
+++ b/test/passes/expand-whens/partial-init.fir
@@ -4,6 +4,16 @@
circuit top :
module top :
reg r : UInt<1>[10]
+ r[0] := UInt(1)
+ r[1] := UInt(1)
+ r[2] := UInt(1)
+ r[3] := UInt(1)
+ r[4] := UInt(1)
+ r[5] := UInt(1)
+ r[6] := UInt(1)
+ r[7] := UInt(1)
+ r[8] := UInt(1)
+ r[9] := UInt(1)
on-reset r[3] := UInt(0)
; CHECK: Finished Expand Whens
diff --git a/test/passes/expand-whens/reg-wdoc.fir b/test/passes/expand-whens/reg-wdoc.fir
index ad2089c2..ad191a01 100644
--- a/test/passes/expand-whens/reg-wdoc.fir
+++ b/test/passes/expand-whens/reg-wdoc.fir
@@ -2,6 +2,7 @@
circuit top :
module top :
wire p : UInt
+ p := UInt(1)
when p :
reg r : UInt
on-reset r := UInt(10)
diff --git a/test/passes/expand-whens/scoped-reg.fir b/test/passes/expand-whens/scoped-reg.fir
index 7f2632f4..d119932f 100644
--- a/test/passes/expand-whens/scoped-reg.fir
+++ b/test/passes/expand-whens/scoped-reg.fir
@@ -2,6 +2,7 @@
circuit top :
module top :
wire p : UInt
+ p := UInt(1)
when p :
reg r : UInt
on-reset r := UInt(10)
diff --git a/test/passes/expand-whens/two-when.fir b/test/passes/expand-whens/two-when.fir
index fb537303..b6c98263 100644
--- a/test/passes/expand-whens/two-when.fir
+++ b/test/passes/expand-whens/two-when.fir
@@ -5,31 +5,34 @@ circuit top :
module top :
cmem m :{ x : UInt<1>, y : UInt<1> }[2]
wire i : UInt<1>
+ i := UInt(1)
wire p : UInt<1>
+ p := UInt(1)
wire q : { x : UInt<1>, y : UInt<1> }
when p :
wire p2 : UInt<1>
- reg r5 : UInt<1>
+ p2 := UInt(1)
when p2 :
- accessor a = m[i]
+ infer accessor a = m[i]
q := a
- accessor b = m[i]
+ infer accessor b = m[i]
b := q
else :
- accessor c = m[i]
+ infer accessor c = m[i]
q := c
- accessor d = m[i]
+ infer accessor d = m[i]
d := q
else :
wire p3 : UInt<1>
+ p3 := UInt(1)
when p3 :
- accessor w = m[i]
+ infer accessor w = m[i]
q := w
- accessor x = m[i]
+ infer accessor x = m[i]
x := q
else :
- accessor y = m[i]
+ infer accessor y = m[i]
q := y
- accessor z = m[i]
+ infer accessor z = m[i]
z := q
; CHECK: Finished Expand Whens
diff --git a/test/passes/infer-types/bundle.fir b/test/passes/infer-types/bundle.fir
index 5018aeef..892103d2 100644
--- a/test/passes/infer-types/bundle.fir
+++ b/test/passes/infer-types/bundle.fir
@@ -8,5 +8,10 @@ circuit top :
node y = z.y ;CHECK: node y = z@<t:{ x : UInt@<t:UInt>, flip y : SInt@<t:SInt>}>.y@<t:SInt>
wire a : UInt<3>[10] ;CHECK: wire a : UInt<3>[10]@<t:UInt>@<t:UInt<3>[10]@<t:UInt>>
node b = a[2] ;CHECK: node b = a@<t:UInt<3>[10]@<t:UInt>>[2]@<t:UInt>
- accessor c = a[UInt(3)] ;CHECK: accessor c = a@<t:UInt<3>[10]@<t:UInt>>[UInt(3)]
+ read accessor c = a[UInt(3)] ;CHECK: read accessor c = a@<t:UInt<3>[10]@<t:UInt>>[UInt(3)]
; CHECK: Finished Infer Types
+; CHECK: Resolve Genders
+; CHECK: read accessor c = a@<t:UInt<3>[10]@<t:UInt>>[UInt(3)]
+; CHECK: Finished Resolve Genders
+
+