Skip to content

Commit 5e081df

Browse files
committed
add test
1 parent 0e41db6 commit 5e081df

File tree

1 file changed

+330
-0
lines changed

1 file changed

+330
-0
lines changed

tests/test_gpio.py

Lines changed: 330 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,330 @@
1+
# amaranth: UnusedElaboratable=no
2+
3+
import unittest
4+
from amaranth import *
5+
from amaranth.sim import *
6+
7+
from amaranth_orchard.io import GPIOPeripheral
8+
9+
10+
class PeripheralTestCase(unittest.TestCase):
11+
def test_init(self):
12+
dut_1 = GPIOPeripheral(pin_count=4, addr_width=2, data_width=8)
13+
self.assertEqual(dut_1.pin_count, 4)
14+
self.assertEqual(dut_1.input_stages, 2)
15+
self.assertEqual(dut_1.bus.addr_width, 2)
16+
self.assertEqual(dut_1.bus.data_width, 8)
17+
dut_2 = GPIOPeripheral(pin_count=1, addr_width=8, data_width=16, input_stages=3)
18+
self.assertEqual(dut_2.pin_count, 1)
19+
self.assertEqual(dut_2.input_stages, 3)
20+
self.assertEqual(dut_2.bus.addr_width, 8)
21+
self.assertEqual(dut_2.bus.data_width, 16)
22+
23+
def test_init_wrong_pin_count(self):
24+
with self.assertRaisesRegex(TypeError,
25+
r"Pin count must be a positive integer, not 'foo'"):
26+
GPIOPeripheral(pin_count="foo", addr_width=2, data_width=8)
27+
with self.assertRaisesRegex(TypeError,
28+
r"Pin count must be a positive integer, not 0"):
29+
GPIOPeripheral(pin_count=0, addr_width=2, data_width=8)
30+
31+
def test_init_wrong_input_stages(self):
32+
with self.assertRaisesRegex(TypeError,
33+
r"Input stages must be a non-negative integer, not 'foo'"):
34+
GPIOPeripheral(pin_count=1, addr_width=2, data_width=8, input_stages="foo")
35+
with self.assertRaisesRegex(TypeError,
36+
r"Input stages must be a non-negative integer, not -1"):
37+
GPIOPeripheral(pin_count=1, addr_width=2, data_width=8, input_stages=-1)
38+
39+
async def _csr_access(self, ctx, dut, addr, r_stb=0, w_stb=0, w_data=0, r_data=0):
40+
ctx.set(dut.bus.addr, addr)
41+
ctx.set(dut.bus.r_stb, r_stb)
42+
ctx.set(dut.bus.w_stb, w_stb)
43+
ctx.set(dut.bus.w_data, w_data)
44+
await ctx.tick()
45+
if r_stb:
46+
self.assertEqual(ctx.get(dut.bus.r_data), r_data)
47+
ctx.set(dut.bus.r_stb, 0)
48+
ctx.set(dut.bus.w_stb, 0)
49+
50+
def test_sim(self):
51+
dut = GPIOPeripheral(pin_count=4, addr_width=2, data_width=8)
52+
53+
mode_addr = 0x0
54+
input_addr = 0x1
55+
output_addr = 0x2
56+
setclr_addr = 0x3
57+
58+
async def testbench(ctx):
59+
# INPUT_ONLY mode =====================================================================
60+
61+
# - read Mode:
62+
await self._csr_access(ctx, dut, mode_addr, r_stb=1, r_data=0b00000000)
63+
self.assertEqual(ctx.get(dut.alt_mode), 0b0000)
64+
self.assertEqual(ctx.get(dut.pins.gpio.oe), 0b0000)
65+
self.assertEqual(ctx.get(dut.pins.gpio.o), 0b0000)
66+
67+
# - read Input:
68+
ctx.set(dut.pins.gpio.i[1], 1)
69+
ctx.set(dut.pins.gpio.i[3], 1)
70+
await self._csr_access(ctx, dut, input_addr, r_stb=1, r_data=0x0)
71+
ctx.set(dut.pins.gpio.i[1], 0)
72+
ctx.set(dut.pins.gpio.i[3], 0)
73+
await self._csr_access(ctx, dut, input_addr, r_stb=1, r_data=0x0)
74+
await self._csr_access(ctx, dut, input_addr, r_stb=1, r_data=0xa)
75+
await self._csr_access(ctx, dut, input_addr, r_stb=1, r_data=0x0)
76+
77+
# - write 0xf to Output:
78+
await self._csr_access(ctx, dut, output_addr, r_stb=1, r_data=0x0, w_stb=1, w_data=0xf)
79+
await ctx.tick()
80+
self.assertEqual(ctx.get(dut.pins.gpio.oe), 0b0000)
81+
self.assertEqual(ctx.get(dut.pins.gpio.o), 0b1111)
82+
83+
# - write 0x22 to SetClr (clear pins[0] and pins[2]):
84+
await self._csr_access(ctx, dut, setclr_addr, w_stb=1, w_data=0x22)
85+
await ctx.tick()
86+
self.assertEqual(ctx.get(dut.pins.gpio.oe), 0b0000)
87+
self.assertEqual(ctx.get(dut.pins.gpio.o), 0b1010)
88+
89+
# - write 0x0 to Output:
90+
await self._csr_access(ctx, dut, output_addr, r_stb=1, r_data=0xa, w_stb=1, w_data=0x0)
91+
await ctx.tick()
92+
self.assertEqual(ctx.get(dut.pins.gpio.oe), 0b0000)
93+
self.assertEqual(ctx.get(dut.pins.gpio.o), 0b0000)
94+
95+
# - write 0x44 to SetClr (set pins[1] and pins[3]):
96+
await self._csr_access(ctx, dut, setclr_addr, w_stb=1, w_data=0x44)
97+
await ctx.tick()
98+
self.assertEqual(ctx.get(dut.pins.gpio.oe), 0b0000)
99+
self.assertEqual(ctx.get(dut.pins.gpio.o), 0b1010)
100+
101+
# - write 0x0 to Output:
102+
await self._csr_access(ctx, dut, output_addr, r_stb=1, r_data=0xa, w_stb=1, w_data=0x0)
103+
await ctx.tick()
104+
self.assertEqual(ctx.get(dut.pins.gpio.oe), 0b0000)
105+
self.assertEqual(ctx.get(dut.pins.gpio.o), 0b0000)
106+
107+
# - write 0xff to SetClr (no-op):
108+
await self._csr_access(ctx, dut, setclr_addr, w_stb=1, w_data=0xff)
109+
await ctx.tick()
110+
self.assertEqual(ctx.get(dut.pins.gpio.oe), 0b0000)
111+
self.assertEqual(ctx.get(dut.pins.gpio.o), 0b0000)
112+
113+
# PUSH_PULL mode ======================================================================
114+
115+
# - write Mode:
116+
await self._csr_access(ctx, dut, mode_addr, w_stb=1, w_data=0b01010101)
117+
await ctx.tick()
118+
self.assertEqual(ctx.get(dut.alt_mode), 0b0000)
119+
self.assertEqual(ctx.get(dut.pins.gpio.oe), 0b1111)
120+
self.assertEqual(ctx.get(dut.pins.gpio.o), 0b0000)
121+
122+
# - read Input:
123+
ctx.set(dut.pins.gpio.i[1], 1)
124+
ctx.set(dut.pins.gpio.i[3], 1)
125+
await self._csr_access(ctx, dut, input_addr, r_stb=1, r_data=0x0)
126+
ctx.set(dut.pins.gpio.i[1], 0)
127+
ctx.set(dut.pins.gpio.i[3], 0)
128+
await self._csr_access(ctx, dut, input_addr, r_stb=1, r_data=0x0)
129+
await self._csr_access(ctx, dut, input_addr, r_stb=1, r_data=0xa)
130+
await self._csr_access(ctx, dut, input_addr, r_stb=1, r_data=0x0)
131+
132+
# - write 0xf to Output:
133+
await self._csr_access(ctx, dut, output_addr, r_stb=1, r_data=0x0, w_stb=1, w_data=0xf)
134+
await ctx.tick()
135+
self.assertEqual(ctx.get(dut.pins.gpio.oe), 0b1111)
136+
self.assertEqual(ctx.get(dut.pins.gpio.o), 0b1111)
137+
138+
# - write 0x22 to SetClr (clear pins[0] and pins[2]):
139+
await self._csr_access(ctx, dut, setclr_addr, w_stb=1, w_data=0x22)
140+
await ctx.tick()
141+
self.assertEqual(ctx.get(dut.pins.gpio.oe), 0b1111)
142+
self.assertEqual(ctx.get(dut.pins.gpio.o), 0b1010)
143+
144+
# - write 0x0 to Output:
145+
await self._csr_access(ctx, dut, output_addr, r_stb=1, r_data=0xa, w_stb=1, w_data=0x0)
146+
await ctx.tick()
147+
self.assertEqual(ctx.get(dut.pins.gpio.oe), 0b1111)
148+
self.assertEqual(ctx.get(dut.pins.gpio.o), 0b1111)
149+
150+
# - write 0x44 to SetClr (set pins[1] and pins[3]):
151+
await self._csr_access(ctx, dut, setclr_addr, w_stb=1, w_data=0x44)
152+
await ctx.tick()
153+
self.assertEqual(ctx.get(dut.pins.gpio.oe), 0b1111)
154+
self.assertEqual(ctx.get(dut.pins.gpio.o), 0b1010)
155+
156+
"""
157+
# - write 0x0 to Output:
158+
await self._csr_access(ctx, dut, output_addr, r_stb=1, r_data=0xa, w_stb=1, w_data=0x0)
159+
await ctx.tick()
160+
for n in range(4):
161+
self.assertEqual(ctx.get(dut.pins[n].oe), 1)
162+
self.assertEqual(ctx.get(dut.pins[n].o), 0)
163+
164+
# - write 0xff to SetClr (no-op):
165+
await self._csr_access(ctx, dut, setclr_addr, w_stb=1, w_data=0xff)
166+
await ctx.tick()
167+
for n in range(4):
168+
self.assertEqual(ctx.get(dut.pins[n].oe), 1)
169+
self.assertEqual(ctx.get(dut.pins[n].o), 0)
170+
171+
# OPEN_DRAIN mode =====================================================================
172+
173+
# - write Mode:
174+
await self._csr_access(ctx, dut, mode_addr, w_stb=1, w_data=0b10101010)
175+
await ctx.tick()
176+
for n in range(4):
177+
self.assertEqual(ctx.get(dut.alt_mode[n]), 0)
178+
self.assertEqual(ctx.get(dut.pins[n].oe), 1)
179+
self.assertEqual(ctx.get(dut.pins[n].o), 0)
180+
181+
# - read Input:
182+
ctx.set(dut.pins[1].i, 1)
183+
ctx.set(dut.pins[3].i, 1)
184+
await self._csr_access(ctx, dut, input_addr, r_stb=1, r_data=0x0)
185+
ctx.set(dut.pins[1].i, 0)
186+
ctx.set(dut.pins[3].i, 0)
187+
await self._csr_access(ctx, dut, input_addr, r_stb=1, r_data=0x0)
188+
await self._csr_access(ctx, dut, input_addr, r_stb=1, r_data=0xa)
189+
await self._csr_access(ctx, dut, input_addr, r_stb=1, r_data=0x0)
190+
191+
# - write 0xf to Output:
192+
await self._csr_access(ctx, dut, output_addr, r_stb=1, r_data=0x0, w_stb=1, w_data=0xf)
193+
await ctx.tick()
194+
for n in range(4):
195+
self.assertEqual(ctx.get(dut.pins[n].oe), 0)
196+
self.assertEqual(ctx.get(dut.pins[n].o), 0)
197+
198+
# - write 0x22 to SetClr (clear pins[0] and pins[2]):
199+
await self._csr_access(ctx, dut, setclr_addr, w_stb=1, w_data=0x22)
200+
await ctx.tick()
201+
self.assertEqual(ctx.get(dut.pins[0].oe), 1)
202+
self.assertEqual(ctx.get(dut.pins[1].oe), 0)
203+
self.assertEqual(ctx.get(dut.pins[2].oe), 1)
204+
self.assertEqual(ctx.get(dut.pins[3].oe), 0)
205+
for n in range(4):
206+
self.assertEqual(ctx.get(dut.pins[n].o), 0)
207+
208+
# - write 0x0 to Output:
209+
await self._csr_access(ctx, dut, output_addr, r_stb=1, r_data=0xa, w_stb=1, w_data=0x0)
210+
await ctx.tick()
211+
for n in range(4):
212+
self.assertEqual(ctx.get(dut.pins[n].oe), 1)
213+
self.assertEqual(ctx.get(dut.pins[n].o), 0)
214+
215+
# - write 0x44 to SetClr (set pins[1] and pins[3]):
216+
await self._csr_access(ctx, dut, setclr_addr, w_stb=1, w_data=0x44)
217+
await ctx.tick()
218+
self.assertEqual(ctx.get(dut.pins[0].oe), 1)
219+
self.assertEqual(ctx.get(dut.pins[1].oe), 0)
220+
self.assertEqual(ctx.get(dut.pins[2].oe), 1)
221+
self.assertEqual(ctx.get(dut.pins[3].oe), 0)
222+
for n in range(4):
223+
self.assertEqual(ctx.get(dut.pins[n].o), 0)
224+
225+
# - write 0x0 to Output:
226+
await self._csr_access(ctx, dut, output_addr, r_stb=1, r_data=0xa, w_stb=1, w_data=0x0)
227+
await ctx.tick()
228+
for n in range(4):
229+
self.assertEqual(ctx.get(dut.pins[n].oe), 1)
230+
self.assertEqual(ctx.get(dut.pins[n].o), 0)
231+
232+
# - write 0xff to SetClr (no-op):
233+
await self._csr_access(ctx, dut, setclr_addr, w_stb=1, w_data=0xff)
234+
await ctx.tick()
235+
for n in range(4):
236+
self.assertEqual(ctx.get(dut.pins[n].oe), 1)
237+
self.assertEqual(ctx.get(dut.pins[n].o), 0)
238+
239+
# ALTERNATE mode ======================================================================
240+
241+
# - write Mode:
242+
await self._csr_access(ctx, dut, mode_addr, w_stb=1, w_data=0b11111111)
243+
await ctx.tick()
244+
for n in range(4):
245+
self.assertEqual(ctx.get(dut.alt_mode[n]), 1)
246+
self.assertEqual(ctx.get(dut.pins[n].oe), 0)
247+
self.assertEqual(ctx.get(dut.pins[n].o), 0)
248+
249+
# - read Input:
250+
ctx.set(dut.pins[1].i, 1)
251+
ctx.set(dut.pins[3].i, 1)
252+
await self._csr_access(ctx, dut, input_addr, r_stb=1, r_data=0x0)
253+
ctx.set(dut.pins[1].i, 0)
254+
ctx.set(dut.pins[3].i, 0)
255+
await self._csr_access(ctx, dut, input_addr, r_stb=1, r_data=0x0)
256+
await self._csr_access(ctx, dut, input_addr, r_stb=1, r_data=0xa)
257+
await self._csr_access(ctx, dut, input_addr, r_stb=1, r_data=0x0)
258+
259+
# - write 0xf to Output:
260+
await self._csr_access(ctx, dut, output_addr, r_stb=1, r_data=0x0, w_stb=1, w_data=0xf)
261+
await ctx.tick()
262+
for n in range(4):
263+
self.assertEqual(ctx.get(dut.pins[n].oe), 0)
264+
self.assertEqual(ctx.get(dut.pins[n].o), 1)
265+
266+
# - write 0x22 to SetClr (clear pins[0] and pins[2]):
267+
await self._csr_access(ctx, dut, setclr_addr, w_stb=1, w_data=0x22)
268+
await ctx.tick()
269+
for n in range(4):
270+
self.assertEqual(ctx.get(dut.pins[n].oe), 0)
271+
self.assertEqual(ctx.get(dut.pins[0].o), 0)
272+
self.assertEqual(ctx.get(dut.pins[1].o), 1)
273+
self.assertEqual(ctx.get(dut.pins[2].o), 0)
274+
self.assertEqual(ctx.get(dut.pins[3].o), 1)
275+
276+
# - write 0x0 to Output:
277+
await self._csr_access(ctx, dut, output_addr, r_stb=1, r_data=0xa, w_stb=1, w_data=0x0)
278+
await ctx.tick()
279+
for n in range(4):
280+
self.assertEqual(ctx.get(dut.pins[n].oe), 0)
281+
self.assertEqual(ctx.get(dut.pins[n].o), 0)
282+
283+
# - write 0x44 to SetClr (set pins[1] and pins[3]):
284+
await self._csr_access(ctx, dut, setclr_addr, w_stb=1, w_data=0x44)
285+
await ctx.tick()
286+
for n in range(4):
287+
self.assertEqual(ctx.get(dut.pins[n].oe), 0)
288+
self.assertEqual(ctx.get(dut.pins[0].o), 0)
289+
self.assertEqual(ctx.get(dut.pins[1].o), 1)
290+
self.assertEqual(ctx.get(dut.pins[2].o), 0)
291+
self.assertEqual(ctx.get(dut.pins[3].o), 1)
292+
293+
# - write 0x0 to Output:
294+
await self._csr_access(ctx, dut, output_addr, r_stb=1, r_data=0xa, w_stb=1, w_data=0x0)
295+
await ctx.tick()
296+
for n in range(4):
297+
self.assertEqual(ctx.get(dut.pins[n].oe), 0)
298+
self.assertEqual(ctx.get(dut.pins[n].o), 0)
299+
300+
# - write 0xff to SetClr (no-op):
301+
await self._csr_access(ctx, dut, setclr_addr, w_stb=1, w_data=0xff)
302+
await ctx.tick()
303+
for n in range(4):
304+
self.assertEqual(ctx.get(dut.pins[n].oe), 0)
305+
self.assertEqual(ctx.get(dut.pins[n].o), 0)
306+
"""
307+
sim = Simulator(dut)
308+
sim.add_clock(1e-6)
309+
sim.add_testbench(testbench)
310+
with sim.write_vcd(vcd_file="test.vcd"):
311+
sim.run()
312+
313+
def test_sim_without_input_sync(self):
314+
dut = GPIOPeripheral(pin_count=4, addr_width=2, data_width=8, input_stages=0)
315+
input_addr = 0x1
316+
317+
async def testbench(ctx):
318+
await self._csr_access(ctx, dut, input_addr, r_stb=1, r_data=0x0)
319+
ctx.set(dut.pins.gpio.i[1], 1)
320+
ctx.set(dut.pins.gpio.i[3], 1)
321+
await self._csr_access(ctx, dut, input_addr, r_stb=1, r_data=0xa)
322+
ctx.set(dut.pins.gpio.i[1], 0)
323+
ctx.set(dut.pins.gpio.i[3], 0)
324+
await self._csr_access(ctx, dut, input_addr, r_stb=1, r_data=0x0)
325+
326+
sim = Simulator(dut)
327+
sim.add_clock(1e-6)
328+
sim.add_testbench(testbench)
329+
with sim.write_vcd(vcd_file="test.vcd"):
330+
sim.run()

0 commit comments

Comments
 (0)