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
98
99
100
101
102
103
104
105
106
107
108
|
// See LICENSE for license details.
package chiselTests
import chisel3._
import chisel3.util._
import chisel3.testers.BasicTester
class MemVecTester extends BasicTester {
val mem = Mem(2, Vec(2, UInt(8.W)))
// Circuit style tester is definitely the wrong abstraction here
val (cnt, wrap) = Counter(true.B, 2)
mem(0)(0) := 1.U
when (cnt === 1.U) {
assert(mem.read(0.U)(0) === 1.U)
stop()
}
}
class SyncReadMemTester extends BasicTester {
val (cnt, _) = Counter(true.B, 5)
val mem = SyncReadMem(2, UInt(2.W))
val rdata = mem.read(cnt - 1.U, cnt =/= 0.U)
switch (cnt) {
is (0.U) { mem.write(cnt, 3.U) }
is (1.U) { mem.write(cnt, 2.U) }
is (2.U) { assert(rdata === 3.U) }
is (3.U) { assert(rdata === 2.U) }
is (4.U) { stop() }
}
}
class SyncReadMemWithZeroWidthTester extends BasicTester {
val (cnt, _) = Counter(true.B, 3)
val mem = SyncReadMem(2, UInt(0.W))
val rdata = mem.read(0.U, true.B)
switch (cnt) {
is (1.U) { assert(rdata === 0.U) }
is (2.U) { stop() }
}
}
// TODO this can't actually simulate with FIRRTL behavioral mems
class HugeSMemTester(size: BigInt) extends BasicTester {
val (cnt, _) = Counter(true.B, 5)
val mem = SyncReadMem(size, UInt(8.W))
val rdata = mem.read(cnt - 1.U, cnt =/= 0.U)
switch (cnt) {
is (0.U) { mem.write(cnt, 3.U) }
is (1.U) { mem.write(cnt, 2.U) }
is (2.U) { assert(rdata === 3.U) }
is (3.U) { assert(rdata === 2.U) }
is (4.U) { stop() }
}
}
class HugeCMemTester(size: BigInt) extends BasicTester {
val (cnt, _) = Counter(true.B, 5)
val mem = Mem(size, UInt(8.W))
val rdata = mem.read(cnt)
switch (cnt) {
is (0.U) { mem.write(cnt, 3.U) }
is (1.U) { mem.write(cnt, 2.U) }
is (2.U) { assert(rdata === 3.U) }
is (3.U) { assert(rdata === 2.U) }
is (4.U) { stop() }
}
}
class MemorySpec extends ChiselPropSpec {
property("Mem of Vec should work") {
assertTesterPasses { new MemVecTester }
}
property("SyncReadMem should work") {
assertTesterPasses { new SyncReadMemTester }
}
property("SyncReadMem should work with zero width entry") {
assertTesterPasses { new SyncReadMemWithZeroWidthTester }
}
property("Massive memories should be emitted in Verilog") {
val addrWidth = 65
val size = BigInt(1) << addrWidth
val smem = compile(new HugeSMemTester(size))
smem should include (s"reg /* sparse */ [7:0] mem [0:$addrWidth'd${size-1}];")
val cmem = compile(new HugeCMemTester(size))
cmem should include (s"reg /* sparse */ [7:0] mem [0:$addrWidth'd${size-1}];")
}
property("Implicit conversions with Mem indices should work") {
"""
|import chisel3._
|import chisel3.util.ImplicitConversions._
|class MyModule extends Module {
| val io = IO(new Bundle {})
| val mem = Mem(32, UInt(8.W))
| mem(0) := 0.U
|}
|""".stripMargin should compile
}
}
|