summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main/scala/chisel3/util/Counter.scala26
-rw-r--r--src/test/scala/chiselTests/Counter.scala8
2 files changed, 30 insertions, 4 deletions
diff --git a/src/main/scala/chisel3/util/Counter.scala b/src/main/scala/chisel3/util/Counter.scala
index 11daa515..fa1bb80c 100644
--- a/src/main/scala/chisel3/util/Counter.scala
+++ b/src/main/scala/chisel3/util/Counter.scala
@@ -19,20 +19,42 @@ import chisel3.internal.naming.chiselName // can't use chisel3_ version because
* ...
* }
* }}}
+ * @example {{{
+ * // Using Scala Range API
+ * val (counterValue, counterWrap) = Counter(0 until 10 by 2)
+ * when (counterValue === 4.U) {
+ * ...
+ * }
+ * }}}
*/
@chiselName
-class Counter private (r: Range) {
+class Counter private (r: Range, oldN: Option[Int] = None) {
require(r.length > 0, s"Counter range cannot be empty, got: $r")
require(r.start >= 0 && r.end >= 0, s"Counter range must be positive, got: $r")
private lazy val delta = math.abs(r.step)
private lazy val width = math.max(log2Up(r.last + 1), log2Up(r.head + 1))
+ /** Number of counts before the counter resets
+ *
+ * @note Only defined for ranges starting at zero with steps of size 1. Use [[range]] for other
+ * use cases.
+ */
+ def n: Int = oldN match {
+ case Some(x) => x
+ case None =>
+ // Reasonable for typical ranges
+ require(r.start == 0 && r.step == 1,
+ s"Counter.n only defined on ranges starting at 0 with step == 1, got $r. " +
+ "Use underlying range.")
+ r.last + 1
+ }
+
/** Creates a counter with the specified number of steps.
*
* @param n number of steps before the counter resets
*/
- def this(n: Int) { this(0 until math.max(1, n)) }
+ def this(n: Int) { this(0 until math.max(1, n), Some(n)) }
/** The current value of the counter. */
val value = if (r.length > 1) RegInit(r.head.U(width.W)) else r.head.U
diff --git a/src/test/scala/chiselTests/Counter.scala b/src/test/scala/chiselTests/Counter.scala
index 31bfe7eb..985cf3fd 100644
--- a/src/test/scala/chiselTests/Counter.scala
+++ b/src/test/scala/chiselTests/Counter.scala
@@ -8,8 +8,10 @@ import chisel3.util._
class CountTester(max: Int) extends BasicTester {
val cnt = Counter(max)
+ assert(cnt.n == max)
when(true.B) { cnt.inc() }
- when(cnt.value === (max-1).asUInt) {
+ val expected = if (max == 0) 0.U else (max - 1).U
+ when(cnt.value === expected) {
stop()
}
}
@@ -50,7 +52,9 @@ class RangeTester(r: Range) extends BasicTester {
class CounterSpec extends ChiselPropSpec {
property("Counter should count up") {
- forAll(smallPosInts) { (max: Int) => assertTesterPasses{ new CountTester(max) } }
+ for (i <- 0 until 4) {
+ assertTesterPasses(new CountTester(i))
+ }
}
property("Counter can be en/disabled") {