summaryrefslogtreecommitdiff
path: root/src/main/scala/Chisel
diff options
context:
space:
mode:
authorAdam Izraelevitz2015-12-11 17:21:36 -0800
committerAdam Izraelevitz2015-12-11 17:21:36 -0800
commitb8cd46de6c01febdbdba7ecb83db494bad8a7a94 (patch)
treec3a0f10dd286ae2bba50c31b987ab39c45189898 /src/main/scala/Chisel
parentbffc67c2bbeb107d2ff9903aa35e85fbb7da73f9 (diff)
parentdbd072172f6312893e1922e48ed768ae0fab9a89 (diff)
Merge pull request #67 from ucb-bar/asserttest
Refactor tests to use stop() and assert() instead of io.error/io.done
Diffstat (limited to 'src/main/scala/Chisel')
-rw-r--r--src/main/scala/Chisel/CoreUtil.scala47
-rw-r--r--src/main/scala/Chisel/testers/BasicTester.scala18
-rw-r--r--src/main/scala/Chisel/util/Counter.scala6
3 files changed, 54 insertions, 17 deletions
diff --git a/src/main/scala/Chisel/CoreUtil.scala b/src/main/scala/Chisel/CoreUtil.scala
index 41266cae..aaca404b 100644
--- a/src/main/scala/Chisel/CoreUtil.scala
+++ b/src/main/scala/Chisel/CoreUtil.scala
@@ -7,21 +7,52 @@ import internal.Builder.pushCommand
import firrtl._
object assert {
+ /** Checks for a condition to be valid in the circuit at all times. If the
+ * condition evaluates to false, the circuit simulation stops with an error.
+ *
+ * Does not fire when in reset (defined as the encapsulating Module's
+ * reset). If your definition of reset is not the encapsulating Module's
+ * reset, you will need to gate this externally.
+ *
+ * May be called outside of a Module (like defined in a function), so
+ * functions using assert make the standard Module assumptions (single clock
+ * and single reset).
+ *
+ * @param cond condition, assertion fires (simulation fails) when false
+ * @param message optional message to print when the assertion fires
+ */
def apply(cond: Bool, message: String="") {
- when(!cond) {
- if (message.isEmpty()) {
- printf(s"Assertion failed: (TODO: code / lineno)")
- } else {
- printf(s"Assertion failed: (TODO: code / lineno): $message")
+ when (!Builder.dynamicContext.currentModule.get.reset) {
+ when(!cond) {
+ if (message.isEmpty()) {
+ printf(s"Assertion failed: (TODO: code / lineno)")
+ } else {
+ printf(s"Assertion failed: (TODO: code / lineno): $message")
+ }
+ pushCommand(Stop(Node(Builder.dynamicContext.currentModule.get.clock), 1))
}
- pushCommand(Stop(Node(Builder.dynamicContext.currentModule.get.clock), 1))
}
}
}
object printf {
+ /** Prints a message in simulation.
+ *
+ * Does not fire when in reset (defined as the encapsulating Module's
+ * reset). If your definition of reset is not the encapsulating Module's
+ * reset, you will need to gate this externally.
+ *
+ * May be called outside of a Module (like defined in a function), so
+ * functions using printf make the standard Module assumptions (single clock
+ * and single reset).
+ *
+ * @param fmt printf format string
+ * @param data format string varargs containing data to print
+ */
def apply(fmt: String, data: Bits*) {
- pushCommand(Printf(Node(Builder.dynamicContext.currentModule.get.clock),
- fmt, data.map(Node(_))))
+ when (!Builder.dynamicContext.currentModule.get.reset) {
+ pushCommand(Printf(Node(Builder.dynamicContext.currentModule.get.clock),
+ fmt, data.map((d: Bits) => d.ref)))
+ }
}
}
diff --git a/src/main/scala/Chisel/testers/BasicTester.scala b/src/main/scala/Chisel/testers/BasicTester.scala
index fecbe2a9..1079727c 100644
--- a/src/main/scala/Chisel/testers/BasicTester.scala
+++ b/src/main/scala/Chisel/testers/BasicTester.scala
@@ -8,18 +8,20 @@ import internal.Builder.pushCommand
import firrtl._
class BasicTester extends Module {
- val io = new Bundle {
- val done = Bool()
- val error = UInt(width = 4)
- }
- io.done := Bool(false)
- io.error := UInt(0)
+ // The testbench has no IOs, rather it should communicate using printf, assert, and stop.
+ val io = new Bundle()
def popCount(n: Long): Int = n.toBinaryString.count(_=='1')
- /** Ends the test, reporting success.
+ /** Ends the test reporting success.
+ *
+ * Does not fire when in reset (defined as the encapsulating Module's
+ * reset). If your definition of reset is not the encapsulating Module's
+ * reset, you will need to gate this externally.
*/
def stop() {
- pushCommand(Stop(Node(clock), 0))
+ when (!reset) {
+ pushCommand(Stop(Node(clock), 0))
+ }
}
}
diff --git a/src/main/scala/Chisel/util/Counter.scala b/src/main/scala/Chisel/util/Counter.scala
index e4a8e95b..356cedc8 100644
--- a/src/main/scala/Chisel/util/Counter.scala
+++ b/src/main/scala/Chisel/util/Counter.scala
@@ -3,10 +3,14 @@
package Chisel
/** A counter module
- * @param n The maximum value of the counter, does not have to be power of 2
+ * @param n number of counts before the counter resets (or one more than the
+ * maximum output value of the counter), need not be a power of two
*/
class Counter(val n: Int) {
val value = if (n == 1) UInt(0) else Reg(init=UInt(0, log2Up(n)))
+ /** Increment the counter this cycle. Returns whether the counter is at its
+ * maximum (and will wrap around on the next inc() call).
+ */
def inc(): Bool = {
if (n == 1) {
Bool(true)