diff options
| author | Andrew Waterman | 2019-08-06 13:47:44 -0700 |
|---|---|---|
| committer | Schuyler Eldridge | 2019-08-06 17:44:37 -0400 |
| commit | 62daa09c61886bfeddfbaf2463d3cc08dbd15b71 (patch) | |
| tree | a0feee930a36dbe9811599267b4f4f90e50195ae /src/main/scala/chisel3/util | |
| parent | b2a1bd7a10977d3331fee3022ec490a1aa1e0e17 (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.
Diffstat (limited to 'src/main/scala/chisel3/util')
| -rw-r--r-- | src/main/scala/chisel3/util/random/LFSR.scala | 19 | ||||
| -rw-r--r-- | src/main/scala/chisel3/util/random/PRNG.scala | 11 |
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 |
