diff options
| -rw-r--r-- | spec/spec.tex | 18 | ||||
| -rw-r--r-- | src/main/stanza/chirrtl.stanza | 28 | ||||
| -rw-r--r-- | src/main/stanza/ir-utils.stanza | 11 | ||||
| -rw-r--r-- | src/main/stanza/passes.stanza | 61 | ||||
| -rw-r--r-- | test/features/IsInvalid.fir | 23 | ||||
| -rw-r--r-- | test/features/Poison.fir | 11 |
6 files changed, 75 insertions, 77 deletions
diff --git a/spec/spec.tex b/spec/spec.tex index 93d62525..12f2c91e 100644 --- a/spec/spec.tex +++ b/spec/spec.tex @@ -1792,18 +1792,22 @@ The concrete syntax of FIRRTL is defined in section \ref{syntax_tree}. Productio %\section{TODO} % %- FIRRTL implementation -% - Make register reset/init optional ; good % - Rework readwrite port types ; limits optimizations but probably ok -% - Add memory read-under-write flag ; probably overengineering, but could be a wash +% - Make register reset/init optional ; good +% - removed addw, added head and tail ; great! +% - Add UBits ; andrew doesn't care, favors overloading UInt +% - Add SBits % - Add partial connect algorithm ; % - Add oriented types to type checker +% - Add memory read-under-write flag ; probably overengineering, but could be a wash +% - *FINISHED* Add Mux expression ; that's lovely, need glitch-free mux for clock types +% - *FINISHED* add rename pass for verilog % - *FINISHED* Add is invalid ; good % - *FINISHED* Add validif ; good -% - Add UBits ; andrew doesn't care, favors overloading UInt -% - Add SBits -% - *FINISHED* Add Mux expression ; that's lovely, need glitch-free mux for clock types -% - removed addw, added head and tail ; great! -% - add rename pass for verilog + +%- Proposed changes to spec +% - switch back to precise dynamic left shift +% - have a wmode instead of rmode for readwrite ports \end{document} diff --git a/src/main/stanza/chirrtl.stanza b/src/main/stanza/chirrtl.stanza index 59f6e359..9b3b90ab 100644 --- a/src/main/stanza/chirrtl.stanza +++ b/src/main/stanza/chirrtl.stanza @@ -285,6 +285,9 @@ defn remove-chirrtl (c:Circuit) : defn set-enable (vec:List<MPort>,en:Symbol) -> False: for r in vec do : add(stmts,Connect(info(s),SubField(SubField(Ref(name(s),ut),name(r),ut),en,taddr),zero)) + defn set-rmode (vec:List<MPort>,rmode:Symbol) -> False: + for r in vec do : + add(stmts,Connect(info(s),SubField(SubField(Ref(name(s),ut),name(r),ut),rmode,taddr),one)) defn set-write (vec:List<MPort>,data:Symbol,mask:Symbol) -> False : val tmask = create-mask(type(s)) for r in vec do : @@ -300,11 +303,10 @@ defn remove-chirrtl (c:Circuit) : set-enable(wrs,`en) set-write(wrs,`data,`mask) val rws = to-list $ readwriters $ get?(hash,name(s),EMPs()) - set-poison(rws,`waddr) - set-poison(rws,`raddr) - set-enable(rws,`wen) - set-enable(rws,`ren) - set-write(rws,`wdata,`wmask) + set-poison(rws,`addr) + set-rmode(rws,`rmode) + set-enable(rws,`en) + set-write(rws,`data,`mask) val read-l = if seq?(s) : 1 else : 0 @@ -315,14 +317,14 @@ defn remove-chirrtl (c:Circuit) : val addrs = Vector<Symbol>() val ens = Vector<Symbol>() val masks = Vector<Symbol>() + val rmodes = Vector<Symbol>() switch { _ == direction(s) } : MReadWrite : - repl[name(s)] = DataRef(SubField(Ref(mem(s),ut),name(s),ut),`rdata,`wdata,`wmask) - add(addrs,`waddr) - add(addrs,`raddr) - add(ens,`wen) - add(ens,`ren) - add(masks,`wmask) + repl[name(s)] = DataRef(SubField(Ref(mem(s),ut),name(s),ut),`rdata,`data,`mask) + add(addrs,`addr) + add(ens,`en) + add(rmodes,`rmode) + add(masks,`mask) MWrite : repl[name(s)] = DataRef(SubField(Ref(mem(s),ut),name(s),ut),`data,`data,`mask) add(addrs,`addr) @@ -338,7 +340,9 @@ defn remove-chirrtl (c:Circuit) : add(stmts,Connect(info(s),SubField(SubField(Ref(mem(s),ut),name(s),ut),x,ut),exps(s)[0])) for x in ens do : add(stmts,Connect(info(s),SubField(SubField(Ref(mem(s),ut),name(s),ut),x,ut),one)) - Begin $ to-list $ stmts + for x in rmodes do : + add(stmts,Connect(info(s),SubField(SubField(Ref(mem(s),ut),name(s),ut),x,ut),zero)) + Begin $ to-list $ stmts (s) : map(collect-refs,s) defn remove-chirrtl-s (s:Stmt) -> Stmt : var has-write-mport? = false diff --git a/src/main/stanza/ir-utils.stanza b/src/main/stanza/ir-utils.stanza index 7d4c30b2..cf9e03e2 100644 --- a/src/main/stanza/ir-utils.stanza +++ b/src/main/stanza/ir-utils.stanza @@ -184,18 +184,13 @@ public defmethod get-type (s:Stmt) -> Type : val clk = Field(`clk,DEFAULT,ClockType()) val def-data = Field(`data,DEFAULT,data-type(s)) val rev-data = Field(`data,REVERSE,data-type(s)) - val rdata = Field(`rdata,REVERSE,data-type(s)) - val wdata = Field(`wdata,DEFAULT,data-type(s)) val mask = Field(`mask,DEFAULT,create-mask(data-type(s))) - val wmask = Field(`wmask,DEFAULT,create-mask(data-type(s))) - val ren = Field(`ren,DEFAULT,UIntType(IntWidth(1))) - val wen = Field(`wen,DEFAULT,UIntType(IntWidth(1))) - val raddr = Field(`raddr,DEFAULT,UIntType(IntWidth(ceil-log2(depth)))) - val waddr = Field(`waddr,DEFAULT,UIntType(IntWidth(ceil-log2(depth)))) + val rmode = Field(`rmode,DEFAULT,UIntType(IntWidth(1))) + val rdata = Field(`rdata,REVERSE,data-type(s)) val read-type = BundleType(to-list([rev-data,addr,en,clk])) val write-type = BundleType(to-list([def-data,mask,addr,en,clk])) - val readwrite-type = BundleType(to-list([wdata,wmask,waddr,wen,rdata,raddr,ren,clk])) + val readwrite-type = BundleType(to-list([rmode,rdata,def-data,mask,addr,en,clk])) val mem-fields = Vector<Field>() for x in readers(s) do : diff --git a/src/main/stanza/passes.stanza b/src/main/stanza/passes.stanza index cf6db44d..68922044 100644 --- a/src/main/stanza/passes.stanza +++ b/src/main/stanza/passes.stanza @@ -2146,7 +2146,6 @@ defn data? (ex:Expression) -> True|False : (ex:WRef|WSubIndex) : false (ex:WSubField) : var yes? = switch { _ == name(ex) } : - `wdata : true `rdata : true `data : true `mask : true @@ -2222,7 +2221,7 @@ defn lower-types (m:Module) -> Module : defn lower-types (s:Stmt) -> Stmt : defn lower-mem (e:Expression) -> List<Expression> : val names = expand-name(e) - if contains?([`data `mask `rdata `wdata `wmask],names[2]) : + if contains?([`data `mask `rdata],names[2]) : list(lower-data-mem(e)) else : lower-other-mem(e,mdt[name(root-ref(e))]) @@ -2724,47 +2723,45 @@ defn emit-verilog (m:InModule) -> Module : update(mem-port,data*,clk,AND(en*,mask*)) for rw in readwriters(s) do : + val rmode = mem-exp(rw,`rmode) val rdata = mem-exp(rw,`rdata) - val raddr = mem-exp(rw,`raddr) - val ren = mem-exp(rw,`ren) - val wdata = mem-exp(rw,`wdata) - val waddr = mem-exp(rw,`waddr) - val wmask = mem-exp(rw,`wmask) - val wen = mem-exp(rw,`wen) + val data = mem-exp(rw,`data) + val mask = mem-exp(rw,`mask) + val addr = mem-exp(rw,`addr) + val en = mem-exp(rw,`en) val clk = mem-exp(rw,`clk) + declare(`wire,lowered-name(rmode),type(rmode)) declare(`wire,lowered-name(rdata),type(rdata)) - declare(`wire,lowered-name(raddr),type(raddr)) - declare(`wire,lowered-name(ren),type(ren)) - declare(`wire,lowered-name(wdata),type(wdata)) - declare(`wire,lowered-name(waddr),type(waddr)) - declare(`wire,lowered-name(wmask),type(wmask)) - declare(`wire,lowered-name(wen),type(wen)) + declare(`wire,lowered-name(data),type(data)) + declare(`wire,lowered-name(mask),type(mask)) + declare(`wire,lowered-name(addr),type(addr)) + declare(`wire,lowered-name(en),type(en)) declare(`wire,lowered-name(clk),type(clk)) - ; Both + ; Assigned to lowered wires of each assign(clk,netlist[clk]) + assign(addr,netlist[addr]) + assign(data,netlist[data]) + assign(addr,netlist[addr]) + assign(mask,netlist[mask]) + assign(en,netlist[en]) + assign(rmode,netlist[rmode]) - ; Read - assign(raddr,netlist[raddr]) - assign(ren,netlist[ren]) - val raddr* = delay(raddr,read-latency(s),clk) - val ren* = delay(ren,read-latency(s),clk) - val rmem-port = WSubAccess(mem,raddr*,UnknownType(),UNKNOWN-GENDER) - assign(rdata,rmem-port) + ; Delay new signals by latency + val raddr* = delay(addr,read-latency(s),clk) + val waddr* = delay(addr,write-latency(s) - 1,clk) + val en* = delay(en,write-latency(s) - 1,clk) + val rmod* = delay(rmode,write-latency(s) - 1,clk) + val data* = delay(data,write-latency(s) - 1,clk) + val mask* = delay(mask,write-latency(s) - 1,clk) ; Write - assign(wdata,netlist[wdata]) - assign(waddr,netlist[waddr]) - assign(wmask,netlist[wmask]) - assign(wen,netlist[wen]) - - val wdata* = delay(wdata,write-latency(s) - 1,clk) - val waddr* = delay(waddr,write-latency(s) - 1,clk) - val wmask* = delay(wmask,write-latency(s) - 1,clk) - val wen* = delay(wen,write-latency(s) - 1,clk) + + val rmem-port = WSubAccess(mem,raddr*,UnknownType(),UNKNOWN-GENDER) + assign(rdata,rmem-port) val wmem-port = WSubAccess(mem,waddr*,UnknownType(),UNKNOWN-GENDER) - update(wmem-port,wdata*,clk,AND(wen*,wmask*)) + update(wmem-port,data*,clk,AND(AND(en*,mask*),NOT(rmode))) (s:Begin) : map(build-streams,s) s diff --git a/test/features/IsInvalid.fir b/test/features/IsInvalid.fir index fbb69ef7..cf898fe9 100644 --- a/test/features/IsInvalid.fir +++ b/test/features/IsInvalid.fir @@ -52,18 +52,17 @@ circuit Top : ;CHECK: m.w.addr is invalid ;CHECK: m.w.en is invalid ;CHECK: m.w.clk is invalid -;CHECK: m.rw.wdata[0] is invalid -;CHECK: m.rw.wdata[1] is invalid -;CHECK: m.rw.wdata[2] is invalid -;CHECK: m.rw.wdata[3] is invalid -;CHECK: m.rw.wmask[0] is invalid -;CHECK: m.rw.wmask[1] is invalid -;CHECK: m.rw.wmask[2] is invalid -;CHECK: m.rw.wmask[3] is invalid -;CHECK: m.rw.waddr is invalid -;CHECK: m.rw.wen is invalid -;CHECK: m.rw.raddr is invalid -;CHECK: m.rw.ren is invalid +;CHECK: m.rw.rmode is invalid +;CHECK: m.rw.data[0] is invalid +;CHECK: m.rw.data[1] is invalid +;CHECK: m.rw.data[2] is invalid +;CHECK: m.rw.data[3] is invalid +;CHECK: m.rw.mask[0] is invalid +;CHECK: m.rw.mask[1] is invalid +;CHECK: m.rw.mask[2] is invalid +;CHECK: m.rw.mask[3] is invalid +;CHECK: m.rw.addr is invalid +;CHECK: m.rw.en is invalid ;CHECK: m.rw.clk is invalid ;CHECK: x.w is invalid ;CHECK: x.x is invalid diff --git a/test/features/Poison.fir b/test/features/Poison.fir index 2b47411f..a4cb1a25 100644 --- a/test/features/Poison.fir +++ b/test/features/Poison.fir @@ -27,12 +27,11 @@ circuit Poison : m.w.data <= q m.rw.clk <= clk - m.rw.raddr <= index - m.rw.ren <= UInt(1) - m.rw.waddr <= index - m.rw.wen <= UInt(1) - m.rw.wmask <= wmask - m.rw.wdata <= q + m.rw.addr <= index + m.rw.en <= UInt(1) + m.rw.rmode <= UInt(1) + m.rw.mask <= wmask + m.rw.data <= q when p : out <= m.r.data else : |
