diff options
Diffstat (limited to 'src/test/scala/chiselTests/util/random/LFSRSpec.scala')
| -rw-r--r-- | src/test/scala/chiselTests/util/random/LFSRSpec.scala | 182 |
1 files changed, 0 insertions, 182 deletions
diff --git a/src/test/scala/chiselTests/util/random/LFSRSpec.scala b/src/test/scala/chiselTests/util/random/LFSRSpec.scala deleted file mode 100644 index d47c2d7d..00000000 --- a/src/test/scala/chiselTests/util/random/LFSRSpec.scala +++ /dev/null @@ -1,182 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 - -package chiselTests.util.random - -import chisel3._ -import chisel3.stage.ChiselStage -import chisel3.util.{Cat, Counter, Enum} -import chisel3.util.random._ -import chisel3.testers.{BasicTester, TesterDriver} -import chiselTests.{ChiselFlatSpec, Utils} - -import math.pow - -class FooLFSR(val reduction: LFSRReduce, seed: Option[BigInt]) extends PRNG(4, seed) with LFSR { - def delta(s: Seq[Bool]): Seq[Bool] = s -} - -class LFSRMaxPeriod(gen: => UInt) extends BasicTester { - - val rv = gen - val started = RegNext(true.B, false.B) - 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) - -} - -/** - * This test creates two 4 sided dice. - * Each cycle it adds them together and adds a count to the bin corresponding to that value - * The asserts check that the bins show the correct distribution. - */ -class LFSRDistribution(gen: => UInt, cycles: Int = 10000) extends BasicTester { - - val rv = gen - val bins = Reg(Vec(8, UInt(32.W))) - - // Use tap points on each LFSR so values are more independent - val die0 = Cat(Seq.tabulate(2) { i => rv(i) }) - val die1 = Cat(Seq.tabulate(2) { i => rv(i + 2) }) - - val (trial, done) = Counter(true.B, cycles) - - val rollValue = die0 +& die1 // Note +& is critical because sum will need an extra bit. - - bins(rollValue) := bins(rollValue) + 1.U - - when(done) { - printf(p"bins: $bins\n") // Note using the printable interpolator p"" to print out a Vec - - // test that the distribution feels right. - assert(bins(1) > bins(0)) - assert(bins(2) > bins(1)) - assert(bins(3) > bins(2)) - assert(bins(4) < bins(3)) - assert(bins(5) < bins(4)) - assert(bins(6) < bins(5)) - assert(bins(7) === 0.U) - - stop() - } -} - -/** This tests that after reset an LFSR is not locked up. This manually sets the seed of the LFSR at run-time to the - * value that would cause it to lock up. It then asserts reset. The next cycle it checks that the value is NOT the - * locked up value. - * @param gen an LFSR to test - * @param lockUpValue the value that would lock up the LFSR - */ -class LFSRResetTester(gen: => LFSR, lockUpValue: BigInt) extends BasicTester { - - val lfsr = Module(gen) - lfsr.io.seed.valid := false.B - lfsr.io.seed.bits := DontCare - lfsr.io.increment := true.B - - val (count, done) = Counter(true.B, 5) - - lfsr.io.seed.valid := count === 1.U - lfsr.io.seed.bits := lockUpValue.U(lfsr.width.W).asBools - lfsr.io.increment := true.B - - when(count === 2.U) { - 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.asUInt =/= lockUpValue.U, "LFSR is locked up, but should not be after reset!") - } - - when(done) { - stop() - } - -} - -class LFSRSpec extends ChiselFlatSpec with Utils { - - def periodCheck(gen: (Int, Set[Int], LFSRReduce) => PRNG, reduction: LFSRReduce, range: Range): Unit = { - val testName = s"have a maximal period over a range of widths (${range.head} to ${range.last})" + - s" using ${reduction.getClass}" - it should testName in { - range.foreach { width => - LFSR.tapsMaxPeriod(width).foreach { taps => - info(s"""width $width okay using taps: ${taps.mkString(", ")}""") - assertTesterPasses( - new LFSRMaxPeriod(PRNG(gen(width, taps, reduction))), - annotations = TesterDriver.verilatorOnly - ) - } - } - } - } - - behavior.of("LFSR") - - it should "throw an exception if initialized to a seed of zero for XOR configuration" in { - { - the[IllegalArgumentException] thrownBy extractCause[IllegalArgumentException] { - ChiselStage.elaborate(new FooLFSR(XOR, Some(0))) - } - }.getMessage should include("Seed cannot be zero") - } - - it should "throw an exception if initialized to a seed of all ones for XNOR configuration" in { - { - the[IllegalArgumentException] thrownBy extractCause[IllegalArgumentException] { - ChiselStage.elaborate(new FooLFSR(XNOR, Some(15))) - } - }.getMessage should include("Seed cannot be all ones") - } - - it should "reset correctly without a seed for XOR configuration" in { - assertTesterPasses(new LFSRResetTester(new FooLFSR(XOR, None), 0)) - } - - it should "reset correctly without a seed for XNOR configuration" in { - assertTesterPasses(new LFSRResetTester(new FooLFSR(XNOR, None), 15)) - } - - behavior.of("MaximalPeriodGaloisLFSR") - - it should "throw an exception if no LFSR taps are known" in { - { - the[IllegalArgumentException] thrownBy extractCause[IllegalArgumentException] { - ChiselStage.elaborate(new MaxPeriodGaloisLFSR(787)) - } - }.getMessage should include("No max period LFSR taps stored for requested width") - } - - periodCheck((w: Int, t: Set[Int], r: LFSRReduce) => new GaloisLFSR(w, t, reduction = r), XOR, 2 to 16) - periodCheck((w: Int, t: Set[Int], r: LFSRReduce) => new GaloisLFSR(w, t, reduction = r), XNOR, 2 to 16) - - ignore should "have a sane distribution for larger widths" in { - ((17 to 32) ++ Seq(64, 128, 256, 512, 1024, 2048, 4096)).foreach { width => - info(s"width $width okay!") - assertTesterPasses(new LFSRDistribution(LFSR(width), math.pow(2, 22).toInt)) - } - } - - behavior.of("MaximalPeriodFibonacciLFSR") - - periodCheck((w: Int, t: Set[Int], r: LFSRReduce) => new FibonacciLFSR(w, t, reduction = r), XOR, 2 to 16) - periodCheck((w: Int, t: Set[Int], r: LFSRReduce) => new FibonacciLFSR(w, t, reduction = r), XNOR, 2 to 16) - - behavior.of("LFSR maximal period taps") - - it should "contain all the expected widths" in { - ((2 to 786) ++ Seq(1024, 2048, 4096)).foreach(LFSR.tapsMaxPeriod.keys should contain(_)) - } - -} |
