diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/main/scala/chisel3/util/LFSR.scala | 17 | ||||
| -rw-r--r-- | src/test/scala/chiselTests/LFSR16.scala | 31 | ||||
| -rw-r--r-- | src/test/scala/chiselTests/QueueSpec.scala | 13 |
3 files changed, 47 insertions, 14 deletions
diff --git a/src/main/scala/chisel3/util/LFSR.scala b/src/main/scala/chisel3/util/LFSR.scala index 3b112973..6ee6be5d 100644 --- a/src/main/scala/chisel3/util/LFSR.scala +++ b/src/main/scala/chisel3/util/LFSR.scala @@ -7,6 +7,7 @@ package chisel3.util import chisel3._ import chisel3.internal.naming.chiselName // can't use chisel3_ version because of compile order +import chisel3.util.random.FibonacciLFSR /** LFSR16 generates a 16-bit linear feedback shift register, returning the register contents. * This is useful for generating a pseudo-random sequence. @@ -27,17 +28,19 @@ import chisel3.internal.naming.chiselName // can't use chisel3_ version because * }}} */ // scalastyle:off magic.number +@deprecated("LFSR16 is deprecated in favor of the parameterized chisel3.util.random.LFSR", "3.3") object LFSR16 { /** Generates a 16-bit linear feedback shift register, returning the register contents. * @param increment optional control to gate when the LFSR updates. */ + @deprecated("Use chisel3.util.random.LFSR(16) for a 16-bit LFSR", "3.3") @chiselName - def apply(increment: Bool = true.B): UInt = { - val width = 16 - val lfsr = RegInit(1.U(width.W)) - when (increment) { lfsr := Cat(lfsr(0)^lfsr(2)^lfsr(3)^lfsr(5), lfsr(width-1,1)) } - lfsr - } + def apply(increment: Bool = true.B): UInt = + Vec( FibonacciLFSR + .maxPeriod(16, seed = Some(BigInt(1) << 15)) + .asBools + .reverse ) + .asUInt + } // scalastyle:on magic.number - diff --git a/src/test/scala/chiselTests/LFSR16.scala b/src/test/scala/chiselTests/LFSR16.scala index c3c9dfad..992bb4bf 100644 --- a/src/test/scala/chiselTests/LFSR16.scala +++ b/src/test/scala/chiselTests/LFSR16.scala @@ -5,6 +5,7 @@ package chiselTests import chisel3._ import chisel3.testers.BasicTester import chisel3.util._ +import chisel3.util.random.{PRNG, LFSR} /** * This test creates two 4 sided dice. @@ -56,12 +57,40 @@ class LFSRMaxPeriod(gen: => UInt) extends BasicTester { } } +/** Check that the output of the new LFSR is the same asthe old LFSR */ +class MeetTheNewLFSR16SameAsTheOldLFSR16 extends BasicTester { + + /** This is the exact implementation of the old LFSR16 algorithm */ + val oldLfsr = { + val width = 16 + val lfsr = RegInit(1.U(width.W)) + lfsr := Cat(lfsr(0)^lfsr(2)^lfsr(3)^lfsr(5), lfsr(width-1,1)) + lfsr + } + + /** The new LFSR16 uses equivalent taps and a reverse so that it can use LFSR(16) under the hood. */ + val newLfsr = LFSR16() + + val (_, done) = Counter(true.B, 16) + + assert(oldLfsr === newLfsr) + + when (done) { + stop() + } + +} + class LFSRSpec extends ChiselPropSpec { property("LFSR16 can be used to produce pseudo-random numbers, this tests the distribution") { assertTesterPasses{ new LFSRDistribution(LFSR16()) } } property("LFSR16 period tester, Period should 2^16 - 1") { - assertTesterPasses { new LFSRMaxPeriod(LFSR16()) } + assertTesterPasses{ new LFSRMaxPeriod(LFSR16()) } + } + + property("New LFSR16 is the same as the old LFSR16") { + assertTesterPasses{ new MeetTheNewLFSR16SameAsTheOldLFSR16 } } } diff --git a/src/test/scala/chiselTests/QueueSpec.scala b/src/test/scala/chiselTests/QueueSpec.scala index 3f723ecf..994f3e6d 100644 --- a/src/test/scala/chiselTests/QueueSpec.scala +++ b/src/test/scala/chiselTests/QueueSpec.scala @@ -9,6 +9,7 @@ import org.scalacheck._ import chisel3._ import chisel3.testers.BasicTester import chisel3.util._ +import chisel3.util.random.LFSR class ThingsPassThroughTester(elements: Seq[Int], queueDepth: Int, bitWidth: Int, tap: Int) extends BasicTester { val q = Module(new Queue(UInt(bitWidth.W), queueDepth)) @@ -19,7 +20,7 @@ class ThingsPassThroughTester(elements: Seq[Int], queueDepth: Int, bitWidth: Int val outCnt = Counter(elements.length + 1) q.io.enq.valid := (inCnt.value < elements.length.U) - q.io.deq.ready := LFSR16()(tap) + q.io.deq.ready := LFSR(16)(tap) q.io.enq.bits := elems(inCnt.value) when(q.io.enq.fire()) { @@ -47,7 +48,7 @@ class QueueReasonableReadyValid(elements: Seq[Int], queueDepth: Int, bitWidth: I //Queue should be full or ready assert(q.io.enq.ready || q.io.count === queueDepth.U) - q.io.deq.ready := LFSR16()(tap) + q.io.deq.ready := LFSR(16)(tap) //Queue should be empty or valid assert(q.io.deq.valid || q.io.count === 0.U) @@ -72,7 +73,7 @@ class CountIsCorrectTester(elements: Seq[Int], queueDepth: Int, bitWidth: Int, t val outCnt = Counter(elements.length + 1) q.io.enq.valid := (inCnt.value < elements.length.U) - q.io.deq.ready := LFSR16()(tap) + q.io.deq.ready := LFSR(16)(tap) q.io.enq.bits := elems(inCnt.value) when(q.io.enq.fire()) { @@ -99,7 +100,7 @@ class QueueSinglePipeTester(elements: Seq[Int], bitWidth: Int, tap: Int) extends val outCnt = Counter(elements.length + 1) q.io.enq.valid := (inCnt.value < elements.length.U) - q.io.deq.ready := LFSR16()(tap) + q.io.deq.ready := LFSR(16)(tap) assert(q.io.enq.ready || (q.io.count === 1.U && !q.io.deq.ready)) @@ -125,7 +126,7 @@ class QueuePipeTester(elements: Seq[Int], queueDepth: Int, bitWidth: Int, tap: I val outCnt = Counter(elements.length + 1) q.io.enq.valid := (inCnt.value < elements.length.U) - q.io.deq.ready := LFSR16()(tap) + q.io.deq.ready := LFSR(16)(tap) assert(q.io.enq.ready || (q.io.count === queueDepth.U && !q.io.deq.ready)) @@ -154,7 +155,7 @@ class QueueFlowTester(elements: Seq[Int], queueDepth: Int, bitWidth: Int, tap: I //Queue should be full or ready assert(q.io.enq.ready || q.io.count === queueDepth.U) - q.io.deq.ready := LFSR16()(tap) + q.io.deq.ready := LFSR(16)(tap) //Queue should be empty or valid assert(q.io.deq.valid || (q.io.count === 0.U && !q.io.enq.fire())) |
