diff options
| -rw-r--r-- | simple.fir | 0 | ||||
| -rw-r--r-- | spec/spec.tex | 4 | ||||
| -rw-r--r-- | src/main/scala/firrtl/Emitter.scala | 20 | ||||
| -rw-r--r-- | src/main/scala/firrtl/Utils.scala | 4 | ||||
| -rw-r--r-- | src/main/scala/firrtl/passes/InferReadWrite.scala | 4 | ||||
| -rw-r--r-- | src/main/scala/firrtl/passes/LowerTypes.scala | 6 | ||||
| -rw-r--r-- | src/main/scala/firrtl/passes/Passes.scala | 6 | ||||
| -rw-r--r-- | test/integration/MemTester.fir | 6 |
8 files changed, 26 insertions, 24 deletions
diff --git a/simple.fir b/simple.fir deleted file mode 100644 index e69de29b..00000000 --- a/simple.fir +++ /dev/null diff --git a/spec/spec.tex b/spec/spec.tex index fe61b84a..14f5ce11 100644 --- a/spec/spec.tex +++ b/spec/spec.tex @@ -827,10 +827,10 @@ If the \verb|en| field is high, then the non-masked portion of the \verb|data| f \subsubsection{Readwrite Ports} Finally, the readwrite ports have type: \begin{verbatim} -{wmode:UInt<1>, flip rdata:T, data:T, mask:M, +{wmode:UInt<1>, flip rdata:T, wdata:T, wmask:M, addr:UInt<N>, en:UInt<1>, clk:Clock} \end{verbatim} -A readwrite port is a single port that, on a given cycle, can be used either as a read or a write port. If the readwrite port is not in write mode (the \verb|wmode| field is low), then the \verb|rdata|, \verb|addr|, \verb|en|, and \verb|clk| fields constitute its read port fields, and should be used accordingly. If the readwrite port is in write mode (the \verb|wmode| field is high), then the \verb|data|, \verb|mask|, \verb|addr|, \verb|en|, and \verb|clk| fields constitute its write port fields, and should be used accordingly. +A readwrite port is a single port that, on a given cycle, can be used either as a read or a write port. If the readwrite port is not in write mode (the \verb|wmode| field is low), then the \verb|rdata|, \verb|addr|, \verb|en|, and \verb|clk| fields constitute its read port fields, and should be used accordingly. If the readwrite port is in write mode (the \verb|wmode| field is high), then the \verb|wdata|, \verb|wmask|, \verb|addr|, \verb|en|, and \verb|clk| fields constitute its write port fields, and should be used accordingly. \subsubsection{Read Under Write Behaviour} diff --git a/src/main/scala/firrtl/Emitter.scala b/src/main/scala/firrtl/Emitter.scala index d09a4afe..3a6af54e 100644 --- a/src/main/scala/firrtl/Emitter.scala +++ b/src/main/scala/firrtl/Emitter.scala @@ -559,8 +559,8 @@ class VerilogEmitter extends Emitter { for (rw <- s.readwriters) { val wmode = mem_exp(rw,"wmode") val rdata = mem_exp(rw,"rdata") - val data = mem_exp(rw,"data") - val mask = mem_exp(rw,"mask") + val wdata = mem_exp(rw,"wdata") + val wmask = mem_exp(rw,"wmask") val addr = mem_exp(rw,"addr") val en = mem_exp(rw,"en") //Ports should share an always@posedge, so can't have intermediary wire @@ -568,16 +568,16 @@ class VerilogEmitter extends Emitter { declare("wire",LowerTypes.loweredName(wmode),tpe(wmode)) declare("wire",LowerTypes.loweredName(rdata),tpe(rdata)) - declare("wire",LowerTypes.loweredName(data),tpe(data)) - declare("wire",LowerTypes.loweredName(mask),tpe(mask)) + declare("wire",LowerTypes.loweredName(wdata),tpe(wdata)) + declare("wire",LowerTypes.loweredName(wmask),tpe(wmask)) declare("wire",LowerTypes.loweredName(addr),tpe(addr)) declare("wire",LowerTypes.loweredName(en),tpe(en)) //; Assigned to lowered wires of each assign(addr,netlist(addr)) - assign(data,netlist(data)) + assign(wdata,netlist(wdata)) assign(addr,netlist(addr)) - assign(mask,netlist(mask)) + assign(wmask,netlist(wmask)) assign(en,netlist(en)) assign(wmode,netlist(wmode)) @@ -586,8 +586,8 @@ class VerilogEmitter extends Emitter { val waddrx = delay(addr,s.writeLatency - 1,clk) val enx = delay(en,s.writeLatency - 1,clk) val rmodx = delay(wmode,s.writeLatency - 1,clk) - val datax = delay(data,s.writeLatency - 1,clk) - val maskx = delay(mask,s.writeLatency - 1,clk) + val wdatax = delay(wdata,s.writeLatency - 1,clk) + val wmaskx = delay(wmask,s.writeLatency - 1,clk) //; Write @@ -596,11 +596,11 @@ class VerilogEmitter extends Emitter { val wmem_port = WSubAccess(mem,waddrx,s.dataType,UNKNOWNGENDER) val tempName = namespace.newTemp - val tempExp = AND(enx,maskx) + val tempExp = AND(enx,wmaskx) declare("wire", tempName, tpe(tempExp)) val tempWRef = wref(tempName, tpe(tempExp)) assign(tempWRef, tempExp) - update(wmem_port,datax,clk,AND(tempWRef,wmode)) + update(wmem_port,wdatax,clk,AND(tempWRef,wmode)) } } case (s:Block) => s map (build_streams) diff --git a/src/main/scala/firrtl/Utils.scala b/src/main/scala/firrtl/Utils.scala index 4843e693..e6db4b2d 100644 --- a/src/main/scala/firrtl/Utils.scala +++ b/src/main/scala/firrtl/Utils.scala @@ -578,9 +578,11 @@ object Utils extends LazyLogging { val mask = Field("mask",Default,create_mask(s.dataType)) val wmode = Field("wmode",Default,UIntType(IntWidth(1))) val rdata = Field("rdata",Flip,s.dataType) + val wdata = Field("wdata",Default,s.dataType) + val wmask = Field("wmask",Default,create_mask(s.dataType)) val read_type = BundleType(Seq(rev_data,addr,en,clk)) val write_type = BundleType(Seq(def_data,mask,addr,en,clk)) - val readwrite_type = BundleType(Seq(wmode,rdata,def_data,mask,addr,en,clk)) + val readwrite_type = BundleType(Seq(wmode,rdata,wdata,wmask,addr,en,clk)) val mem_fields = ArrayBuffer[Field]() s.readers.foreach {x => mem_fields += Field(x,Flip,read_type)} diff --git a/src/main/scala/firrtl/passes/InferReadWrite.scala b/src/main/scala/firrtl/passes/InferReadWrite.scala index 2378216d..664b3dfc 100644 --- a/src/main/scala/firrtl/passes/InferReadWrite.scala +++ b/src/main/scala/firrtl/passes/InferReadWrite.scala @@ -139,8 +139,8 @@ object InferReadWritePass extends Pass { repl(s"${mem.name}.$w.en") = WSubField(rw_exp, "wmode", bt, FEMALE) repl(s"${mem.name}.$w.clk") = EmptyExpression repl(s"${mem.name}.$w.addr") = EmptyExpression - repl(s"${mem.name}.$w.data") = WSubField(rw_exp, "data", mem.dataType, FEMALE) - repl(s"${mem.name}.$w.mask") = WSubField(rw_exp, "mask", ut, FEMALE) + repl(s"${mem.name}.$w.data") = WSubField(rw_exp, "wdata", mem.dataType, FEMALE) + repl(s"${mem.name}.$w.mask") = WSubField(rw_exp, "wmask", ut, FEMALE) stmts += Connect(NoInfo, WSubField(rw_exp, "clk", ClockType, FEMALE), WRef("clk", ClockType, NodeKind(), MALE)) stmts += Connect(NoInfo, WSubField(rw_exp, "en", bt, FEMALE), diff --git a/src/main/scala/firrtl/passes/LowerTypes.scala b/src/main/scala/firrtl/passes/LowerTypes.scala index 7ab3333a..585598a8 100644 --- a/src/main/scala/firrtl/passes/LowerTypes.scala +++ b/src/main/scala/firrtl/passes/LowerTypes.scala @@ -96,7 +96,7 @@ object LowerTypes extends Pass { // Since mems with Bundle type must be split into multiple ground type // mem, references to fields addr, en, clk, and rmode must be replicated // for each resulting memory - // References to data, mask, and rdata have already been split in expand connects + // References to data, mask, rdata, wdata, and wmask have already been split in expand connects // and just need to be converted to refer to the correct new memory def lowerTypesMemExp(e: Expression): Seq[Expression] = { val (mem, port, field, tail) = splitMemRef(e) @@ -117,8 +117,8 @@ object LowerTypes extends Pass { } // Fields that need not be replicated for each // eg. mem.reader.data[0].a - // (Connect/IsInvalid must already have been split to gorund types) - } else if (Seq("data", "mask", "rdata").contains(field.name)) { + // (Connect/IsInvalid must already have been split to ground types) + } else if (Seq("data", "mask", "rdata", "wdata", "wmask").contains(field.name)) { val loMem = tail match { case Some(e) => val loMemExp = mergeRef(mem, e) diff --git a/src/main/scala/firrtl/passes/Passes.scala b/src/main/scala/firrtl/passes/Passes.scala index a8580988..1b6c76f4 100644 --- a/src/main/scala/firrtl/passes/Passes.scala +++ b/src/main/scala/firrtl/passes/Passes.scala @@ -1147,7 +1147,7 @@ object RemoveCHIRRTL extends Pass { set_poison(rws,"addr") set_wmode(rws,"wmode") set_enable(rws,"en") - set_write(rws,"data","mask") + set_write(rws,"wdata","wmask") val read_l = if (s.seq) 1 else 0 val mem = DefMemory(s.info,s.name,s.tpe,s.size,1,read_l,rds.map(_.name),wrs.map(_.name),rws.map(_.name)) Block(Seq(mem,Block(stmts))) @@ -1160,11 +1160,11 @@ object RemoveCHIRRTL extends Pass { val masks = ArrayBuffer[String]() s.direction match { case MReadWrite => { - repl(s.name) = DataRef(SubField(Reference(s.mem,ut),s.name,ut),"rdata","data","mask",true) + repl(s.name) = DataRef(SubField(Reference(s.mem,ut),s.name,ut),"rdata","wdata","wmask",true) addrs += "addr" clks += "clk" ens += "en" - masks += "mask" + masks += "wmask" } case MWrite => { repl(s.name) = DataRef(SubField(Reference(s.mem,ut),s.name,ut),"data","data","mask",false) diff --git a/test/integration/MemTester.fir b/test/integration/MemTester.fir index c41fe1cc..451ec5d3 100644 --- a/test/integration/MemTester.fir +++ b/test/integration/MemTester.fir @@ -28,14 +28,14 @@ circuit MemTester : m.rw.clk <= clk m.rw.addr <= addr m.rw.wmode <= wmode - m.rw.data <= n - m.rw.mask <= UInt(1) + m.rw.wdata <= n + m.rw.wmask <= UInt(1) m.rw.en <= UInt(1) when not(reset) : when eq(wmode, UInt(0)) : when neq(m.rw.rdata, n) : - printf(clk, UInt(1), "Assertion failed! m.rw.data has the wrong value!\n") + printf(clk, UInt(1), "Assertion failed! m.rw.rdata has the wrong value!\n") stop(clk, UInt(1), 1) module MemTester : |
