summaryrefslogtreecommitdiff
path: root/src/test/scala/chiselTests
diff options
context:
space:
mode:
authorSchuyler Eldridge2019-05-09 16:48:36 -0400
committerSchuyler Eldridge2019-05-09 19:45:25 -0400
commit356d5c99c233540e4d993ccc365a7069d9d2beaa (patch)
tree82453617fec3957e33724eb3a0fd25dd060d803f /src/test/scala/chiselTests
parent6be76f79f873873497e40fa647f9456391b4d59a (diff)
PRNG state UInt->Vec[Bool], make async reset safe
Changes the internal state of PRNG to use Vec[Bool] instead of UInt. This fixes an @aswaterman identified future problem with asynchronous reset. A register with an asynchronous reset can only be reset to a literal. Previously, an LFSR would store state as a UInt. If it was not parameterized with a seed it should have its least significant bit reset to something to avoid locking up. It's ideal to not reset the full UInt (better test coverage, decreased reset fanout). However, it's difficult to only reset one bit of a UInt. Conversely, it's trivial to reset one bit of a Vec[Bool]. This also moves PRNG/LFSR closer to a canonical representation of their internal state, i.e., it's natural to think of generalizing Vec[Bool] to arbitrary finite fields (Vec[A <: Field]) whereas UInt is tightly coupled to GF2. Minor updates: - Updates/fixes to some scaladoc - Add assertion to period test to make sure LFSR is changing Signed-off-by: Schuyler Eldridge <schuyler.eldridge@ibm.com>
Diffstat (limited to 'src/test/scala/chiselTests')
-rw-r--r--src/test/scala/chiselTests/LFSR16.scala5
-rw-r--r--src/test/scala/chiselTests/util/random/LFSRSpec.scala10
-rw-r--r--src/test/scala/chiselTests/util/random/PRNGSpec.scala6
3 files changed, 12 insertions, 9 deletions
diff --git a/src/test/scala/chiselTests/LFSR16.scala b/src/test/scala/chiselTests/LFSR16.scala
index 992bb4bf..d0f06865 100644
--- a/src/test/scala/chiselTests/LFSR16.scala
+++ b/src/test/scala/chiselTests/LFSR16.scala
@@ -51,10 +51,15 @@ class LFSRMaxPeriod(gen: => UInt) extends BasicTester {
val seed = withReset(!started) { RegInit(rv) }
val (_, wrap) = Counter(started, math.pow(2.0, rv.getWidth).toInt - 1)
+
when (rv === seed && started) {
chisel3.assert(wrap)
stop()
}
+
+ val last = RegNext(rv)
+ chisel3.assert(rv =/= last, "LFSR last value (0b%b) was equal to current value (0b%b)", rv, last)
+
}
/** Check that the output of the new LFSR is the same asthe old LFSR */
diff --git a/src/test/scala/chiselTests/util/random/LFSRSpec.scala b/src/test/scala/chiselTests/util/random/LFSRSpec.scala
index 5aedca75..ce0abf69 100644
--- a/src/test/scala/chiselTests/util/random/LFSRSpec.scala
+++ b/src/test/scala/chiselTests/util/random/LFSRSpec.scala
@@ -12,7 +12,7 @@ import chiselTests.{ChiselFlatSpec, LFSRDistribution, LFSRMaxPeriod}
import math.pow
class FooLFSR(val reduction: LFSRReduce, seed: Option[BigInt]) extends PRNG(4, seed) with LFSR {
- def delta(s: UInt): UInt = s
+ def delta(s: Seq[Bool]): Seq[Bool] = s
}
/** This tests that after reset an LFSR is not locked up. This manually sets the seed of the LFSR at run-time to the
@@ -30,20 +30,18 @@ class LFSRResetTester(gen: => LFSR, lockUpValue: BigInt) extends BasicTester {
val (count, done) = Counter(true.B, 5)
- printf("%d: 0b%b\n", count, lfsr.io.out)
-
lfsr.io.seed.valid := count === 1.U
- lfsr.io.seed.bits := lockUpValue.U
+ lfsr.io.seed.bits := lockUpValue.U(lfsr.width.W).asBools
lfsr.io.increment := true.B
when (count === 2.U) {
- assert(lfsr.io.out === lockUpValue.U, "LFSR is NOT locked up, but should be!")
+ assert(lfsr.io.out.asUInt === lockUpValue.U, "LFSR is NOT locked up, but should be!")
}
lfsr.reset := count === 3.U
when (count === 4.U) {
- assert(lfsr.io.out =/= lockUpValue.U, "LFSR is locked up, but should not be after reset!")
+ assert(lfsr.io.out.asUInt =/= lockUpValue.U, "LFSR is locked up, but should not be after reset!")
}
when (done) {
diff --git a/src/test/scala/chiselTests/util/random/PRNGSpec.scala b/src/test/scala/chiselTests/util/random/PRNGSpec.scala
index 138a6ceb..341fb685 100644
--- a/src/test/scala/chiselTests/util/random/PRNGSpec.scala
+++ b/src/test/scala/chiselTests/util/random/PRNGSpec.scala
@@ -12,7 +12,7 @@ import chiselTests.ChiselFlatSpec
class CyclePRNG(width: Int, seed: Option[BigInt], step: Int, updateSeed: Boolean)
extends PRNG(width, seed, step, updateSeed) {
- def delta(s: UInt): UInt = s ## s(width - 1)
+ def delta(s: Seq[Bool]): Seq[Bool] = s.last +: s.dropRight(1)
}
@@ -49,10 +49,10 @@ class PRNGUpdateSeedTest(updateSeed: Boolean, seed: BigInt, expected: BigInt) ex
a.io.increment := true.B
a.io.seed.valid := count === 2.U
- a.io.seed.bits := seed.U
+ a.io.seed.bits := seed.U(a.width.W).asBools
when (count === 3.U) {
- assert(a.io.out === expected.U, "Output didn't match!")
+ assert(a.io.out.asUInt === expected.U, "Output didn't match!")
}
when (done) {