summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Waterman2019-08-06 13:47:44 -0700
committerSchuyler Eldridge2019-08-06 17:44:37 -0400
commit62daa09c61886bfeddfbaf2463d3cc08dbd15b71 (patch)
treea0feee930a36dbe9811599267b4f4f90e50195ae
parentb2a1bd7a10977d3331fee3022ec490a1aa1e0e17 (diff)
Avoid when(reset) construct in LFSR
Muxes and resets are only isomorphic with synchronous reset. Use a reset instead of a conditional to make this async-reset-safe.
-rw-r--r--src/main/scala/chisel3/util/random/LFSR.scala19
-rw-r--r--src/main/scala/chisel3/util/random/PRNG.scala11
2 files changed, 19 insertions, 11 deletions
diff --git a/src/main/scala/chisel3/util/random/LFSR.scala b/src/main/scala/chisel3/util/random/LFSR.scala
index a19f40d3..5b67c509 100644
--- a/src/main/scala/chisel3/util/random/LFSR.scala
+++ b/src/main/scala/chisel3/util/random/LFSR.scala
@@ -47,19 +47,24 @@ trait LFSR extends PRNG {
*/
def reduction: LFSRReduce
- seed match {
- case Some(s) =>
- reduction match {
+ override protected def resetValue: Vec[Bool] = seed match {
+ case Some(s) => reduction match {
case XOR => require(s != 0, "Seed cannot be zero")
case XNOR => require(s != BigInt(2).pow(width) - 1, "Seed cannot be all ones (max value)")
}
- case None =>
+ super.resetValue
+
+ case None => {
+ val res = WireDefault(Vec(width, Bool()), DontCare)
+
reduction match {
- case XOR => when (reset.toBool) { state(0) := 1.U }
- case XNOR => when (reset.toBool) { state(0) := 0.U }
+ case XOR => res(0) := true.B
+ case XNOR => res(0) := false.B
}
- }
+ res
+ }
+ }
}
/** Utilities related to psuedorandom number generation using Linear Feedback Shift Registers (LFSRs).
diff --git a/src/main/scala/chisel3/util/random/PRNG.scala b/src/main/scala/chisel3/util/random/PRNG.scala
index c74759b0..37f50599 100644
--- a/src/main/scala/chisel3/util/random/PRNG.scala
+++ b/src/main/scala/chisel3/util/random/PRNG.scala
@@ -33,15 +33,18 @@ abstract class PRNG(val width: Int, val seed: Option[BigInt], step: Int = 1, upd
val io: PRNGIO = IO(new PRNGIO(width))
+ /** Allow implementations to override the reset value, e.g., if some bits should be don't-cares. */
+ protected def resetValue: Vec[Bool] = seed match {
+ case Some(s) => VecInit(s.U(width.W).asBools)
+ case None => WireDefault(Vec(width, Bool()), DontCare)
+ }
+
/** Internal state of the PRNG. If the user sets a seed, this is initialized to the seed. If the user does not set a
* seed this is left uninitialized. In the latter case, a PRNG subclass *must do something to handle lockup*, e.g.,
* the PRNG state should be manually reset to a safe value. [[LFSR]] handles this by, based on the chosen reduction
* operator, either sets or resets the least significant bit of the state.
*/
- private [random] val state: Vec[Bool] = seed match {
- case Some(s) => RegInit(VecInit(s.U(width.W).asBools))
- case None => Reg(Vec(width, Bool()))
- }
+ private [random] val state: Vec[Bool] = RegInit(resetValue)
/** State update function
* @param s input state