aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlbert Magyar2019-08-07 16:33:45 -0700
committermergify[bot]2019-08-07 23:33:45 +0000
commitc6c509d623e5e64e021fa311018b8ace2f3f8969 (patch)
treee1f81ce7cfaf6842f3edbb4778839cc2da3d8fc1
parent23a104d3409385718a960427f1576f508e3f473b (diff)
Check mems for legal latencies; ban zero write latency. (#1147)
* Check mems for legal latencies; ban zero write latency. * Trigger
-rw-r--r--spec/spec.pdfbin269138 -> 269128 bytes
-rw-r--r--spec/spec.tex2
-rw-r--r--src/main/scala/firrtl/passes/Checks.scala4
-rw-r--r--src/test/scala/firrtlTests/CheckSpec.scala19
4 files changed, 24 insertions, 1 deletions
diff --git a/spec/spec.pdf b/spec/spec.pdf
index 42395661..9242011e 100644
--- a/spec/spec.pdf
+++ b/spec/spec.pdf
Binary files differ
diff --git a/spec/spec.tex b/spec/spec.tex
index fd1f045c..8685de45 100644
--- a/spec/spec.tex
+++ b/spec/spec.tex
@@ -756,7 +756,7 @@ A memory is an abstract representation of a hardware memory. It is characterized
\item A positive integer representing the number of elements in the memory.
\item A variable number of named ports, each being a read port, a write port, or readwrite port.
\item A non-negative integer indicating the read latency, which is the number of cycles after setting the port's read address before the corresponding element's value can be read from the port's data field.
-\item A non-negative integer indicating the write latency, which is the number of cycles after setting the port's write address and data before the corresponding element within the memory holds the new value.
+\item A positive integer indicating the write latency, which is the number of cycles after setting the port's write address and data before the corresponding element within the memory holds the new value.
\item A read-under-write flag indicating the behaviour when a memory location is written to while a read to that location is in progress.
\end{enumerate}
diff --git a/src/main/scala/firrtl/passes/Checks.scala b/src/main/scala/firrtl/passes/Checks.scala
index 471fe216..4bcfad9c 100644
--- a/src/main/scala/firrtl/passes/Checks.scala
+++ b/src/main/scala/firrtl/passes/Checks.scala
@@ -27,6 +27,8 @@ trait CheckHighFormLike {
s"$info: [module $mname] Memory $name has not been properly lowered from Chirrtl IR.")
class MemWithFlipException(info: Info, mname: String, name: String) extends PassException(
s"$info: [module $mname] Memory $name cannot be a bundle type with flips.")
+ class IllegalMemLatencyException(info: Info, mname: String, name: String) extends PassException(
+ s"$info: [module $mname] Memory $name must have non-negative read latency and positive write latency.")
class RegWithFlipException(info: Info, mname: String, name: String) extends PassException(
s"$info: [module $mname] Register $name cannot be a bundle type with flips.")
class InvalidAccessException(info: Info, mname: String) extends PassException(
@@ -191,6 +193,8 @@ trait CheckHighFormLike {
if (reset.tpe == AsyncResetType && !init.isInstanceOf[Literal])
errors.append(new NonLiteralAsyncResetValueException(info, mname, name, init.serialize))
case sx: DefMemory =>
+ if (sx.readLatency < 0 || sx.writeLatency <= 0)
+ errors.append(new IllegalMemLatencyException(info, mname, sx.name))
if (hasFlip(sx.dataType))
errors.append(new MemWithFlipException(info, mname, sx.name))
if (sx.depth <= 0)
diff --git a/src/test/scala/firrtlTests/CheckSpec.scala b/src/test/scala/firrtlTests/CheckSpec.scala
index 93bc2cab..54dc60ab 100644
--- a/src/test/scala/firrtlTests/CheckSpec.scala
+++ b/src/test/scala/firrtlTests/CheckSpec.scala
@@ -41,6 +41,25 @@ class CheckSpec extends FlatSpec with Matchers {
}
}
+ "Memories with zero write latency" should "throw an exception" in {
+ val passes = Seq(
+ ToWorkingIR,
+ CheckHighForm)
+ val input =
+ """circuit Unit :
+ | module Unit :
+ | mem m :
+ | data-type => UInt<32>
+ | depth => 32
+ | read-latency => 0
+ | write-latency => 0""".stripMargin
+ intercept[CheckHighForm.IllegalMemLatencyException] {
+ passes.foldLeft(Parser.parse(input.split("\n").toIterator)) {
+ (c: Circuit, p: Pass) => p.run(c)
+ }
+ }
+ }
+
"Registers with flip in the type" should "throw an exception" in {
val input =
"""circuit Unit :