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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
|
// SPDX-License-Identifier: Apache-2.0
package chiselTests.util.random
import chisel3._
import chisel3.stage.ChiselStage
import chisel3.testers.BasicTester
import chisel3.util.Counter
import chisel3.util.random.PRNG
import chiselTests.{ChiselFlatSpec, Utils}
class CyclePRNG(width: Int, seed: Option[BigInt], step: Int, updateSeed: Boolean)
extends PRNG(width, seed, step, updateSeed) {
def delta(s: Seq[Bool]): Seq[Bool] = s.last +: s.dropRight(1)
}
class PRNGStepTest extends BasicTester {
val count2: UInt = Counter(true.B, 2)._1
val count4: UInt = Counter(true.B, 4)._1
val a: UInt = PRNG(new CyclePRNG(16, Some(1), 1, false), true.B)
val b: UInt = PRNG(new CyclePRNG(16, Some(1), 2, false), count2 === 1.U)
val c: UInt = PRNG(new CyclePRNG(16, Some(1), 4, false), count4 === 3.U)
val (_, done) = Counter(true.B, 16)
when(count2 === 0.U) {
assert(a === b, "1-step and 2-step PRNGs did not agree! (0b%b != 0b%b)", a, b)
}
when(count4 === 0.U) {
assert(a === c, "1-step and 4-step PRNGs did not agree!")
}
when(done) {
stop()
}
}
class PRNGUpdateSeedTest(updateSeed: Boolean, seed: BigInt, expected: BigInt) extends BasicTester {
val a: CyclePRNG = Module(new CyclePRNG(16, Some(1), 1, updateSeed))
val (count, done) = Counter(true.B, 4)
a.io.increment := true.B
a.io.seed.valid := count === 2.U
a.io.seed.bits := seed.U(a.width.W).asBools
when(count === 3.U) {
assert(a.io.out.asUInt === expected.U, "Output didn't match!")
}
when(done) {
stop()
}
}
class PRNGSpec extends ChiselFlatSpec with Utils {
behavior.of("PRNG")
it should "throw an exception if the step size is < 1" in {
{
the[IllegalArgumentException] thrownBy extractCause[IllegalArgumentException] {
ChiselStage.elaborate(new CyclePRNG(0, Some(1), 1, true))
}
}.getMessage should include("Width must be greater than zero!")
}
it should "throw an exception if the step size is <= 0" in {
{
the[IllegalArgumentException] thrownBy extractCause[IllegalArgumentException] {
ChiselStage.elaborate(new CyclePRNG(1, Some(1), 0, true))
}
}.getMessage should include("Step size must be greater than one!")
}
it should "handle non-unary steps" in {
assertTesterPasses(new PRNGStepTest)
}
it should "handle state update without and with updateSeed enabled" in {
info("without updateSeed okay!")
assertTesterPasses(new PRNGUpdateSeedTest(false, 3, 3))
info("with updateSeed okay!")
assertTesterPasses(new PRNGUpdateSeedTest(true, 3, 6))
}
}
|