diff options
| author | Donggyu | 2016-08-18 18:03:18 -0700 |
|---|---|---|
| committer | Adam Izraelevitz | 2016-08-18 18:03:18 -0700 |
| commit | ebd6f893428b16629be8d4d703d553d0fe8cf37c (patch) | |
| tree | 79d4c8454312d815a79f5189bff45514848ceb63 /src | |
| parent | f8fab5bee8f0484a788769d2d4e87c08ccd884e4 (diff) | |
emit correct enable signals for memories (#242)
Diffstat (limited to 'src')
| -rw-r--r-- | src/main/scala/firrtl/Emitter.scala | 55 |
1 files changed, 36 insertions, 19 deletions
diff --git a/src/main/scala/firrtl/Emitter.scala b/src/main/scala/firrtl/Emitter.scala index 3a6af54e..316a7044 100644 --- a/src/main/scala/firrtl/Emitter.scala +++ b/src/main/scala/firrtl/Emitter.scala @@ -437,16 +437,14 @@ class VerilogEmitter extends Emitter { Seq("$fwrite(32'h80000002,",strx,");") } def delay (e:Expression, n:Int, clk:Expression) : Expression = { - var ex = e - for (i <- 0 until n) { + ((0 until n) foldLeft e){(ex, i) => val name = namespace.newTemp declare("reg",name,tpe(e)) val exx = WRef(name,tpe(e),ExpKind(),UNKNOWNGENDER) initialize(exx) update(exx,ex,clk,one) - ex = exx + exx } - ex } def build_ports () = { (m.ports,0 until m.ports.size).zipped.foreach{(p,i) => { @@ -513,12 +511,20 @@ class VerilogEmitter extends Emitter { declare("wire",LowerTypes.loweredName(data),tpe(data)) declare("wire",LowerTypes.loweredName(addr),tpe(addr)) declare("wire",LowerTypes.loweredName(en),tpe(en)) - + //; Read port assign(addr,netlist(addr)) //;Connects value to m.r.addr assign(en,netlist(en)) //;Connects value to m.r.en - val addrx = delay(addr,s.readLatency,clk) - val enx = delay(en,s.readLatency,clk) + val addr_pipe = delay(addr,s.readLatency-1,clk) + val en_pipe = if (weq(en,one)) one else delay(en,s.readLatency-1,clk) + val addrx = if (s.readLatency > 0) { + val name = namespace.newTemp + val ref = WRef(name,tpe(addr),ExpKind(),UNKNOWNGENDER) + declare("reg",name,tpe(addr)) + initialize(ref) + update(ref,addr_pipe,clk,en_pipe) + ref + } else addr val mem_port = WSubAccess(mem,addrx,s.dataType,UNKNOWNGENDER) val depthValue = UIntLiteral(s.depth, IntWidth(BigInt(s.depth).bitLength)) val garbageGuard = DoPrim(Geq, Seq(addrx, depthValue), Seq(), UnknownType) @@ -582,25 +588,36 @@ class VerilogEmitter extends Emitter { assign(wmode,netlist(wmode)) //; Delay new signals by latency - val raddrx = delay(addr,s.readLatency,clk) + val raddrx = if (s.readLatency > 0) delay(addr,s.readLatency - 1,clk) else addr 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 wmodex = delay(wmode,s.writeLatency - 1,clk) val wdatax = delay(wdata,s.writeLatency - 1,clk) val wmaskx = delay(wmask,s.writeLatency - 1,clk) - - //; Write - - val rmem_port = WSubAccess(mem,raddrx,s.dataType,UNKNOWNGENDER) + + val raddrxx = if (s.readLatency > 0) { + val name = namespace.newTemp + val ref = WRef(name,tpe(raddrx),ExpKind(),UNKNOWNGENDER) + declare("reg",name,tpe(raddrx)) + initialize(ref) + ref + } else addr + val rmem_port = WSubAccess(mem,raddrxx,s.dataType,UNKNOWNGENDER) assign(rdata,rmem_port) val wmem_port = WSubAccess(mem,waddrx,s.dataType,UNKNOWNGENDER) - val tempName = namespace.newTemp - val tempExp = AND(enx,wmaskx) - declare("wire", tempName, tpe(tempExp)) - val tempWRef = wref(tempName, tpe(tempExp)) - assign(tempWRef, tempExp) - update(wmem_port,wdatax,clk,AND(tempWRef,wmode)) + def declare_and_assign(exp: Expression) = { + val name = namespace.newTemp + val ref = wref(name, tpe(exp)) + declare("wire", name, tpe(exp)) + assign(ref, exp) + ref + } + val ren = declare_and_assign(NOT(wmodex)) + val wen = declare_and_assign(AND(wmodex, wmaskx)) + if (s.readLatency > 0) + update(raddrxx,raddrx,clk,AND(enx,ren)) + update(wmem_port,wdatax,clk,AND(enx,wen)) } } case (s:Block) => s map (build_streams) |
