diff options
| author | azidar | 2015-07-06 17:45:06 -0700 |
|---|---|---|
| committer | azidar | 2015-07-14 11:29:55 -0700 |
| commit | 68f7ac42d01c88bcc0c77c919587618673658c76 (patch) | |
| tree | 054c3a2fdb710b187664fb9e7212046f12ec2ef2 | |
| parent | 8d6c83072cd60ecc376d81eb9a48ccf0f67e57f6 (diff) | |
Still partial commit, many tests pass. Many tests fail.
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 + + |
