blob: 54a3591fcbc3800c3fb95834d626479b7af00b75 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
|
// See LICENSE for license details.
package chiselTests
import chisel3._
import chisel3.testers.BasicTester
import chisel3.util._
/**
* 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 LFSRTester extends BasicTester {
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 => LFSR16()(i) })
val die1 = Cat(Seq.tabulate(2) { i => LFSR16()(i + 2) })
val (trial, done) = Counter(true.B, 10000)
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 LFSR16MaxPeriod extends BasicTester {
val lfsr16 = LFSR16()
val started = RegNext(true.B, false.B)
val (_, wrap) = Counter(started, math.pow(2.0, 16).toInt - 1)
when (lfsr16 === 1.U && started) {
chisel3.assert(wrap)
stop()
}
}
class LFSRSpec extends ChiselPropSpec {
property("LFSR16 can be used to produce pseudo-random numbers, this tests the distribution") {
assertTesterPasses{ new LFSRTester }
}
property("LFSR16 period tester, Period should 2^16 - 1") {
assertTesterPasses { new LFSR16MaxPeriod }
}
}
|