diff options
| author | Jack Koenig | 2018-04-26 13:15:51 -0700 |
|---|---|---|
| committer | GitHub | 2018-04-26 13:15:51 -0700 |
| commit | b72b6ebec78343c7ad12cbb51834118e69b1443b (patch) | |
| tree | 386376e3844a949228a67d000824a3eb036de24a /src | |
| parent | 1b4b17c7fb6d29179e7ff11368f7e387ce1bc179 (diff) | |
Fix bug in VerilogMemDelays (#795)
* Change VerilogMemDelays to put new Statements at end of Module
Fixes #547
This is instead of putting them right after the modified DefMemory which could
result in use before declaration errors for things that feed into the new
logic.
* Adds tests that show VerilogMemDelays crashing. (#792)
Diffstat (limited to 'src')
| -rw-r--r-- | src/main/scala/firrtl/passes/memlib/VerilogMemDelays.scala | 23 | ||||
| -rw-r--r-- | src/test/scala/firrtlTests/VerilogMemDelaySpec.scala | 52 |
2 files changed, 67 insertions, 8 deletions
diff --git a/src/main/scala/firrtl/passes/memlib/VerilogMemDelays.scala b/src/main/scala/firrtl/passes/memlib/VerilogMemDelays.scala index 6eefb69e..5bdb880d 100644 --- a/src/main/scala/firrtl/passes/memlib/VerilogMemDelays.scala +++ b/src/main/scala/firrtl/passes/memlib/VerilogMemDelays.scala @@ -10,6 +10,8 @@ import firrtl.Mappers._ import firrtl.PrimOps._ import MemPortUtils._ +import collection.mutable + /** This pass generates delay reigsters for memories for verilog */ object VerilogMemDelays extends Pass { val ug = UNKNOWNGENDER @@ -32,8 +34,9 @@ object VerilogMemDelays extends Pass { def memDelayStmt( netlist: Netlist, namespace: Namespace, - repl: Netlist) - (s: Statement): Statement = s map memDelayStmt(netlist, namespace, repl) match { + repl: Netlist, + stmts: mutable.ArrayBuffer[Statement]) + (s: Statement): Statement = s.map(memDelayStmt(netlist, namespace, repl, stmts)) match { case sx: DefMemory => val ports = (sx.readers ++ sx.writers).toSet def newPortName(rw: String, p: String) = (for { @@ -96,8 +99,7 @@ object VerilogMemDelays extends Pass { Connect(NoInfo, memPortField(mem, writer, "data"), data) ) - - Block(mem +: ((sx.readers flatMap {reader => + stmts ++= ((sx.readers flatMap {reader => // generate latency pipes for read ports (enable & addr) val clk = netlist(memPortField(sx, reader, "clk")) val (en, ss1) = pipe(memPortField(sx, reader, "en"), sx.readLatency - 1, clk, one) @@ -125,7 +127,8 @@ object VerilogMemDelays extends Pass { ss1 ++ ss2 ++ ss3 ++ ss4 ++ ss5 ++ ss6 ++ readPortConnects(reader, clk, en, raddr) ++ writePortConnects(writer, clk, AND(en, wmode), wmask, waddr, wdata) - }))) + })) + mem // The mem stays put case sx: Connect => kind(sx.loc) match { case MemKind => EmptyStmt case _ => sx @@ -144,13 +147,17 @@ object VerilogMemDelays extends Pass { def replaceStmt(repl: Netlist)(s: Statement): Statement = s map replaceStmt(repl) map replaceExp(repl) + def appendStmts(sx: Seq[Statement])(s: Statement): Statement = Block(s +: sx) + def memDelayMod(m: DefModule): DefModule = { val netlist = new Netlist val namespace = Namespace(m) val repl = new Netlist - (m map buildNetlist(netlist) - map memDelayStmt(netlist, namespace, repl) - map replaceStmt(repl)) + val extraStmts = mutable.ArrayBuffer.empty[Statement] + m.map(buildNetlist(netlist)) + .map(memDelayStmt(netlist, namespace, repl, extraStmts)) + .map(replaceStmt(repl)) + .map(appendStmts(extraStmts)) } def run(c: Circuit): Circuit = diff --git a/src/test/scala/firrtlTests/VerilogMemDelaySpec.scala b/src/test/scala/firrtlTests/VerilogMemDelaySpec.scala new file mode 100644 index 00000000..405f5ab5 --- /dev/null +++ b/src/test/scala/firrtlTests/VerilogMemDelaySpec.scala @@ -0,0 +1,52 @@ +// See LICENSE for license details. + +package firrtlTests + +import firrtl._ +import firrtl.passes.memlib.VerilogMemDelays +import firrtl.passes.CheckHighForm +import org.scalatest.{FreeSpec, Matchers} + +class VerilogMemDelaySpec extends FreeSpec with Matchers { + "The following low FIRRTL should be parsed by VerilogMemDelays" in { + val input = + """ + |circuit Test : + | module Test : + | input clock : Clock + | input addr : UInt<5> + | input mask : { a : UInt<1>, b: UInt<1> }[2] + | output out : { a : UInt<8>, b : UInt<8>}[2] + | mem m : + | data-type => { a : UInt<8>, b : UInt<8>}[2] + | depth => 32 + | read-latency => 0 + | write-latency => 1 + | reader => read + | writer => write + | m.read.clk <= clock + | m.read.en <= UInt<1>(1) + | m.read.addr <= addr + | out <= m.read.data + | + | m.write.clk <= clock + | m.write.en <= UInt<1>(1) + | m.write.mask <= mask + | m.write.addr <= addr + | wire w : { a : UInt<8>, b : UInt<8>}[2] + | w[0].a <= UInt<4>(2) + | w[0].b <= UInt<4>(3) + | w[1].a <= UInt<4>(4) + | w[1].b <= UInt<4>(5) + | m.write.data <= w + """.stripMargin + + val circuit = Parser.parse(input) + val compiler = new LowFirrtlCompiler + + val result = compiler.compile(CircuitState(circuit, ChirrtlForm), Seq.empty) + val result2 = VerilogMemDelays.run(result.circuit) + CheckHighForm.run(result2) + //result.circuit.serialize.length > 0 should be (true) + } +} |
