add Config Fetch interface and quick unit test
[soc.git] / src / soc / config / test / test_loadstore.py
1 from soc.minerva.units.loadstore import LoadStoreUnitInterface
2 from nmigen import Signal, Module, Elaboratable, Mux
3 from nmigen.utils import log2_int
4 import random
5 from nmigen.back.pysim import Simulator, Settle
6 from soc.config.loadstore import ConfigLoadStoreUnit
7 from collections import namedtuple
8 from nmigen.cli import rtlil
9
10 TestMemPspec = namedtuple('TestMemPspec', ['ldst_ifacetype',
11 'imem_ifacetype',
12 'addr_wid', 'mask_wid', 'reg_wid'])
13
14 def write_to_addr(dut, addr, value):
15 yield dut.x_addr_i.eq(addr)
16 yield dut.x_st_data_i.eq(value)
17 yield dut.x_st_i.eq(1)
18 yield dut.x_mask_i.eq(-1)
19 yield dut.x_valid_i.eq(1)
20 yield dut.x_stall_i.eq(1)
21 yield dut.m_valid_i.eq(1)
22 yield
23 yield
24
25 yield dut.x_stall_i.eq(0)
26 yield
27 yield dut.x_st_i.eq(0)
28 while (yield dut.x_busy_o):
29 yield
30
31
32 def read_from_addr(dut, addr):
33 yield dut.x_addr_i.eq(addr)
34 yield dut.x_ld_i.eq(1)
35 yield dut.x_valid_i.eq(1)
36 yield dut.x_stall_i.eq(1)
37 yield
38 yield dut.x_stall_i.eq(0)
39 yield
40 yield dut.x_ld_i.eq(0)
41 yield Settle()
42 while (yield dut.x_busy_o):
43 yield
44 assert (yield dut.x_valid_i)
45 return (yield dut.m_ld_data_o)
46
47
48 def write_byte(dut, addr, val):
49 offset = addr & 0x3
50 yield dut.x_addr_i.eq(addr)
51 yield dut.x_st_data_i.eq(val << (offset * 8))
52 yield dut.x_st_i.eq(1)
53 yield dut.x_mask_i.eq(1 << offset)
54 print ("write_byte", addr, bin(1<<offset), hex(val<<(offset*8)))
55 yield dut.x_valid_i.eq(1)
56 yield dut.m_valid_i.eq(1)
57
58 yield
59 yield dut.x_st_i.eq(0)
60 while (yield dut.x_busy_o):
61 yield
62
63
64 def read_byte(dut, addr):
65 offset = addr & 0x3
66 yield dut.x_addr_i.eq(addr)
67 yield dut.x_ld_i.eq(1)
68 yield dut.x_valid_i.eq(1)
69 yield
70 yield dut.x_ld_i.eq(0)
71 yield Settle()
72 while (yield dut.x_busy_o):
73 yield
74 assert (yield dut.x_valid_i)
75 val = (yield dut.m_ld_data_o)
76 print ("read_byte", addr, offset, hex(val))
77 return (val >> (offset * 8)) & 0xff
78
79
80 def tst_lsmemtype(ifacetype):
81 m = Module()
82 pspec = TestMemPspec(ldst_ifacetype=ifacetype, addr_wid=64,
83 mask_wid=4,
84 reg_wid=32)
85 dut = ConfigLoadStoreUnit(pspec).lsi
86 vl = rtlil.convert(dut, ports=[]) # TODOdut.ports())
87 with open("test_loadstore_%s.il" % ifacetype, "w") as f:
88 f.write(vl)
89
90 m.submodules.dut = dut
91
92 sim = Simulator(m)
93 sim.add_clock(1e-6)
94
95 def process():
96
97 values = [random.randint(0, 255) for x in range(16*4)]
98 for addr, val in enumerate(values):
99 yield from write_byte(dut, addr, val)
100 x = yield from read_from_addr(dut, addr << 2)
101 print ("addr, val", addr, hex(val), hex(x))
102 x = yield from read_byte(dut, addr)
103 print ("addr, val", addr, hex(val), hex(x))
104 assert x == val
105
106 values = [random.randint(0, (1<<32)-1) for x in range(16)]
107
108 for addr, val in enumerate(values):
109 yield from write_to_addr(dut, addr << 2, val)
110 x = yield from read_from_addr(dut, addr << 2)
111 print ("addr, val", addr, hex(val), hex(x))
112 assert x == val
113
114 sim.add_sync_process(process)
115 with sim.write_vcd("test_loadstore_%s.vcd" % ifacetype, traces=[]):
116 sim.run()
117
118 if __name__ == '__main__':
119 tst_lsmemtype('test_bare_wb')
120 tst_lsmemtype('testmem')