1 #nmigen: UnusedElaboratable=no
6 from nmigen
.utils
import log2_int
7 from nmigen
.back
.pysim
import *
9 from nmigen_soc
.wishbone
import CycleType
, BurstTypeExt
11 from .utils
.wishbone
import *
12 from ..periph
.sram
import SRAMPeripheral
15 def simulation_test(dut
, process
):
18 sim
.add_sync_process(process
)
19 with sim
.write_vcd("test.vcd"):
23 def _burst_type(wrap
):
25 return BurstTypeExt
.LINEAR
27 return BurstTypeExt
.WRAP_4
29 return BurstTypeExt
.WRAP_8
31 return BurstTypeExt
.WRAP_16
35 class SRAMPeripheralTestCase(unittest
.TestCase
):
36 def read_incr(self
, dut
, *, addr
, count
, wrap
=0): # FIXME clean
38 yield dut
.bus
.cyc
.eq(1)
39 yield dut
.bus
.stb
.eq(1)
40 yield dut
.bus
.adr
.eq(addr
)
41 yield dut
.bus
.bte
.eq(_burst_type(wrap
))
42 yield dut
.bus
.cti
.eq(CycleType
.END_OF_BURST
if count
== 0 else CycleType
.INCR_BURST
)
44 self
.assertFalse((yield dut
.bus
.ack
))
45 for i
in range(count
):
47 self
.assertTrue((yield dut
.bus
.ack
))
48 data
.append((yield dut
.bus
.dat_r
))
50 yield dut
.bus
.adr
.eq((yield dut
.bus
.adr
) + 1)
52 yield dut
.bus
.adr
[:log2_int(wrap
)].eq((yield dut
.bus
.adr
[:log2_int(wrap
)]) + 1)
53 yield dut
.bus
.cti
.eq(CycleType
.END_OF_BURST
if i
== count
-1 else CycleType
.INCR_BURST
)
54 yield dut
.bus
.cyc
.eq(0)
55 yield dut
.bus
.stb
.eq(0)
59 dut
= SRAMPeripheral(size
=16, data_width
=32, granularity
=8)
60 self
.assertEqual(dut
.bus
.addr_width
, 2)
61 self
.assertEqual(dut
.bus
.data_width
, 32)
62 self
.assertEqual(dut
.bus
.granularity
, 8)
64 def test_invalid_size(self
):
65 with self
.assertRaisesRegex(ValueError,
66 r
"Size must be an integer power of two, not 'foo'"):
67 dut
= SRAMPeripheral(size
='foo')
68 with self
.assertRaisesRegex(ValueError,
69 r
"Size must be an integer power of two, not 3"):
70 dut
= SRAMPeripheral(size
=3)
72 def test_invalid_size_ratio(self
):
73 with self
.assertRaisesRegex(ValueError,
74 r
"Size 2 cannot be lesser than the data width/granularity ratio of "
76 dut
= SRAMPeripheral(size
=2, data_width
=32, granularity
=8)
79 dut
= SRAMPeripheral(size
=4, data_width
=8, writable
=False)
80 dut
.init
= [0x00, 0x01, 0x02, 0x03]
83 data
= (yield from wb_read(dut
.bus
, addr
=i
, sel
=1))
84 self
.assertEqual(data
, dut
.init
[i
])
86 simulation_test(dut
, process
)
88 def test_read_incr_linear(self
):
89 dut
= SRAMPeripheral(size
=8, data_width
=8, writable
=False)
90 dut
.init
= [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07]
92 data
= (yield from self
.read_incr(dut
, addr
=0x00, count
=6))
93 self
.assertEqual(data
, dut
.init
[:6])
95 data
= (yield from self
.read_incr(dut
, addr
=0x06, count
=2))
96 self
.assertEqual(data
, dut
.init
[6:])
97 simulation_test(dut
, process
)
99 def test_read_incr_wrap_4(self
):
100 dut
= SRAMPeripheral(size
=8, data_width
=8, writable
=False)
101 dut
.init
= [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07]
103 data
= (yield from self
.read_incr(dut
, addr
=0x01, count
=8, wrap
=4))
104 self
.assertEqual(data
, 2*(dut
.init
[1:4] + [dut
.init
[0]]))
105 simulation_test(dut
, process
)
107 def test_read_incr_wrap_8(self
):
108 dut
= SRAMPeripheral(size
=8, data_width
=8, writable
=False)
109 dut
.init
= [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07]
111 data
= (yield from self
.read_incr(dut
, addr
=0x06, count
=16, wrap
=8))
112 self
.assertEqual(data
, 2*(dut
.init
[6:] + dut
.init
[:6]))
113 simulation_test(dut
, process
)
115 def test_read_incr_wrap_16(self
):
116 dut
= SRAMPeripheral(size
=16, data_width
=8, writable
=False)
117 dut
.init
= [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
118 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f]
120 data
= (yield from self
.read_incr(dut
, addr
=0x06, count
=32, wrap
=16))
121 self
.assertEqual(data
, 2*(dut
.init
[6:] + dut
.init
[:6]))
122 simulation_test(dut
, process
)
124 def test_write(self
):
125 dut
= SRAMPeripheral(size
=4, data_width
=8)
127 data
= [0x00, 0x01, 0x02, 0x03]
128 for i
in range(len(data
)):
129 yield from wb_write(dut
.bus
, addr
=i
, data
=data
[i
], sel
=1)
131 for i
in range(len(data
)):
132 b
= yield from wb_read(dut
.bus
, addr
=i
, sel
=1)
134 self
.assertEqual(b
, data
[i
])
135 simulation_test(dut
, process
)
137 def test_write_sel(self
):
138 dut
= SRAMPeripheral(size
=4, data_width
=16, granularity
=8)
140 yield from wb_write(dut
.bus
, addr
=0x0, data
=0x5aa5, sel
=0b01)
142 yield from wb_write(dut
.bus
, addr
=0x1, data
=0x5aa5, sel
=0b10)
144 self
.assertEqual((yield from wb_read(dut
.bus
, addr
=0x0, sel
=1)), 0x00a5)
146 self
.assertEqual((yield from wb_read(dut
.bus
, addr
=0x1, sel
=1)), 0x5a00)
147 simulation_test(dut
, process
)
149 # TODO test write bursts