From 01399dd00ba18b1e4d5c1f773ca33f077c53c534 Mon Sep 17 00:00:00 2001 From: Albert Magyar Date: Mon, 30 Sep 2019 14:34:15 -0700 Subject: Add read-under-write checks for memory emission * Stop ignoring read-under-write (RUW) parameter * Add conservative check: blackbox only when RUW is "undefined" * VerilogMemDelays now throws InternalError for read-first memories * Previously, read-first mems were incorrectly implemented as write-first --- src/main/scala/firrtl/passes/memlib/ToMemIR.scala | 7 ++++--- src/main/scala/firrtl/passes/memlib/VerilogMemDelays.scala | 2 ++ 2 files changed, 6 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/main/scala/firrtl/passes/memlib/ToMemIR.scala b/src/main/scala/firrtl/passes/memlib/ToMemIR.scala index a9f4b330..554a3572 100644 --- a/src/main/scala/firrtl/passes/memlib/ToMemIR.scala +++ b/src/main/scala/firrtl/passes/memlib/ToMemIR.scala @@ -11,14 +11,15 @@ import firrtl.ir._ * - read latency and write latency of one * - only one readwrite port or write port * - zero or one read port + * - undefined read-under-write behavior */ object ToMemIR extends Pass { /** Only annotate memories that are candidates for memory macro replacements - * i.e. rw, w + r (read, write 1 cycle delay) + * i.e. rw, w + r (read, write 1 cycle delay) and read-under-write "undefined." */ + import ReadUnderWrite._ def updateStmts(s: Statement): Statement = s match { - case m: DefMemory if m.readLatency == 1 && m.writeLatency == 1 && - (m.writers.length + m.readwriters.length) == 1 && m.readers.length <= 1 => + case m @ DefMemory(_,_,_,_,1,1,r,w,rw,Undefined) if (w.length + rw.length) == 1 && r.length <= 1 => DefAnnotatedMemory(m) case sx => sx map updateStmts } diff --git a/src/main/scala/firrtl/passes/memlib/VerilogMemDelays.scala b/src/main/scala/firrtl/passes/memlib/VerilogMemDelays.scala index 335e1121..89d4e6f0 100644 --- a/src/main/scala/firrtl/passes/memlib/VerilogMemDelays.scala +++ b/src/main/scala/firrtl/passes/memlib/VerilogMemDelays.scala @@ -33,6 +33,8 @@ object VerilogMemDelays extends Pass { repl: Netlist, stmts: mutable.ArrayBuffer[Statement]) (s: Statement): Statement = s.map(memDelayStmt(netlist, namespace, repl, stmts)) match { + case sx: DefMemory if (sx.readUnderWrite == ir.ReadUnderWrite.Old) => + throwInternalError("VerilogMemDelays does not support read-first (readunderwrite == 'old') memories") case sx: DefMemory => val ports = (sx.readers ++ sx.writers).toSet def newPortName(rw: String, p: String) = (for { -- cgit v1.2.3