aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJack Koenig2018-04-26 13:15:51 -0700
committerGitHub2018-04-26 13:15:51 -0700
commitb72b6ebec78343c7ad12cbb51834118e69b1443b (patch)
tree386376e3844a949228a67d000824a3eb036de24a /src
parent1b4b17c7fb6d29179e7ff11368f7e387ce1bc179 (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.scala23
-rw-r--r--src/test/scala/firrtlTests/VerilogMemDelaySpec.scala52
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)
+ }
+}