diff options
| -rw-r--r-- | spec/spec.pdf | bin | 269138 -> 269128 bytes | |||
| -rw-r--r-- | spec/spec.tex | 2 | ||||
| -rw-r--r-- | src/main/scala/firrtl/passes/Checks.scala | 4 | ||||
| -rw-r--r-- | src/test/scala/firrtlTests/CheckSpec.scala | 19 |
4 files changed, 24 insertions, 1 deletions
diff --git a/spec/spec.pdf b/spec/spec.pdf Binary files differindex 42395661..9242011e 100644 --- a/spec/spec.pdf +++ b/spec/spec.pdf 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 : |
