summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSchuyler Eldridge2020-06-17 11:24:51 -0400
committerGitHub2020-06-17 11:24:51 -0400
commit3a276c86f3f08ec586810672a70c7f4f41127c2e (patch)
treeb03c1b4e3b29ba25ae8b74ac3d39da54dcb7bce6
parent5271e89c09653fe0d38adf75b5bef1fe5d3539d2 (diff)
parent818ecf08be3042a33684b269fa849105744a8b09 (diff)
Merge pull request #1476 from freechipsproject/remove-LFSR16
Move LFSR16 to Compatibility Mode (Deprecated in 3.2)
-rw-r--r--src/main/scala/chisel3/compatibility.scala36
-rw-r--r--src/main/scala/chisel3/util/LFSR.scala46
-rw-r--r--src/test/scala/chiselTests/LFSR16.scala104
-rw-r--r--src/test/scala/chiselTests/util/random/LFSRSpec.scala59
4 files changed, 92 insertions, 153 deletions
diff --git a/src/main/scala/chisel3/compatibility.scala b/src/main/scala/chisel3/compatibility.scala
index 9584fad6..0c4c18a9 100644
--- a/src/main/scala/chisel3/compatibility.scala
+++ b/src/main/scala/chisel3/compatibility.scala
@@ -4,6 +4,8 @@
* while moving to the more standard package naming convention `chisel3` (lowercase c).
*/
import chisel3._ // required for implicit conversions.
+import chisel3.experimental.chiselName
+import chisel3.util.random.FibonacciLFSR
package object Chisel { // scalastyle:ignore package.object.name number.of.types number.of.methods
import chisel3.internal.firrtl.Width
@@ -561,7 +563,39 @@ package object Chisel { // scalastyle:ignore package.object.name number.of.t
}
}
- val LFSR16 = chisel3.util.LFSR16
+ /** LFSR16 generates a 16-bit linear feedback shift register, returning the register contents.
+ * This is useful for generating a pseudo-random sequence.
+ *
+ * The example below, taken from the unit tests, creates two 4-sided dice using `LFSR16` primitives:
+ * @example {{{
+ * val bins = Reg(Vec(8, UInt(32.W)))
+ *
+ * // Create two 4 sided dice and roll them each cycle.
+ * // Use tap points on each LFSR so values are more independent
+ * val die0 = Cat(Seq.tabulate(2) { i => LFSR16()(i) })
+ * val die1 = Cat(Seq.tabulate(2) { i => LFSR16()(i + 2) })
+ *
+ * val rollValue = die0 +& die1 // Note +& is critical because sum will need an extra bit.
+ *
+ * bins(rollValue) := bins(rollValue) + 1.U
+ *
+ * }}}
+ */
+ // scalastyle:off magic.number
+ object LFSR16 {
+ /** Generates a 16-bit linear feedback shift register, returning the register contents.
+ * @param increment optional control to gate when the LFSR updates.
+ */
+ @chiselName
+ def apply(increment: Bool = true.B): UInt =
+ VecInit( FibonacciLFSR
+ .maxPeriod(16, increment, seed = Some(BigInt(1) << 15))
+ .asBools
+ .reverse )
+ .asUInt
+
+ }
+ // scalastyle:on magic.number
val ListLookup = chisel3.util.ListLookup
val Lookup = chisel3.util.Lookup
diff --git a/src/main/scala/chisel3/util/LFSR.scala b/src/main/scala/chisel3/util/LFSR.scala
deleted file mode 100644
index 5fc778fb..00000000
--- a/src/main/scala/chisel3/util/LFSR.scala
+++ /dev/null
@@ -1,46 +0,0 @@
-// See LICENSE for license details.
-
-/** LFSRs in all shapes and sizes.
- */
-
-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.
- *
- * The example below, taken from the unit tests, creates two 4-sided dice using `LFSR16` primitives:
- * @example {{{
- * val bins = Reg(Vec(8, UInt(32.W)))
- *
- * // Create two 4 sided dice and roll them each cycle.
- * // Use tap points on each LFSR so values are more independent
- * val die0 = Cat(Seq.tabulate(2) { i => LFSR16()(i) })
- * val die1 = Cat(Seq.tabulate(2) { i => LFSR16()(i + 2) })
- *
- * val rollValue = die0 +& die1 // Note +& is critical because sum will need an extra bit.
- *
- * bins(rollValue) := bins(rollValue) + 1.U
- *
- * }}}
- */
-// scalastyle:off magic.number
-@deprecated("LFSR16 is deprecated in favor of the parameterized chisel3.util.random.LFSR", "3.2")
-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.2")
- @chiselName
- def apply(increment: Bool = true.B): UInt =
- VecInit( FibonacciLFSR
- .maxPeriod(16, increment, 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
deleted file mode 100644
index a49d9722..00000000
--- a/src/test/scala/chiselTests/LFSR16.scala
+++ /dev/null
@@ -1,104 +0,0 @@
-// See LICENSE for license details.
-
-package chiselTests
-
-import chisel3._
-import chisel3.testers.BasicTester
-import chisel3.util._
-import chisel3.util.random.{PRNG, LFSR}
-
-/**
- * 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.
- */
-//scalastyle:off magic.number
-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()
- }
-}
-
-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)
-
-}
-
-/** Check that the output of the new LFSR is the same as the old LFSR */
-class MeetTheNewLFSR16SameAsTheOldLFSR16 extends BasicTester {
- val en = Counter(2).value.asBool
-
- /** This is the exact implementation of the old LFSR16 algorithm */
- val oldLfsr = {
- val width = 16
- val lfsr = RegInit(1.U(width.W))
- when (en) {
- 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(en)
-
- 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()) }
- }
-
- property("New LFSR16 is the same as the old LFSR16") {
- assertTesterPasses{ new MeetTheNewLFSR16SameAsTheOldLFSR16 }
- }
-}
diff --git a/src/test/scala/chiselTests/util/random/LFSRSpec.scala b/src/test/scala/chiselTests/util/random/LFSRSpec.scala
index ce0abf69..9afe7670 100644
--- a/src/test/scala/chiselTests/util/random/LFSRSpec.scala
+++ b/src/test/scala/chiselTests/util/random/LFSRSpec.scala
@@ -3,11 +3,11 @@
package chiselTests.util.random
import chisel3._
-import chisel3.util.{Counter, Enum}
+import chisel3.util.{Cat, Counter, Enum}
import chisel3.util.random._
import chisel3.testers.BasicTester
-import chiselTests.{ChiselFlatSpec, LFSRDistribution, LFSRMaxPeriod}
+import chiselTests.{ChiselFlatSpec, Utils}
import math.pow
@@ -15,6 +15,61 @@ class FooLFSR(val reduction: LFSRReduce, seed: Option[BigInt]) extends PRNG(4, s
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.
+ */
+//scalastyle:off magic.number
+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.