investigating why write-enable not getting passed through
[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
9
10 def write_to_addr(dut, addr, value):
11 yield dut.x_addr_i.eq(addr)
12 yield dut.x_st_data_i.eq(value)
13 yield dut.x_st_i.eq(1)
14 yield dut.x_mask_i.eq(-1)
15 yield dut.x_valid_i.eq(1)
16 yield dut.x_stall_i.eq(1)
17 yield dut.m_valid_i.eq(1)
18 yield
19 yield
20
21 yield dut.x_stall_i.eq(0)
22 yield
23 yield dut.x_st_i.eq(0)
24 while (yield dut.x_stall_i):
25 yield
26
27
28 def read_from_addr(dut, addr):
29 yield dut.x_addr_i.eq(addr)
30 yield dut.x_ld_i.eq(1)
31 yield dut.x_valid_i.eq(1)
32 yield dut.x_stall_i.eq(1)
33 yield
34 yield dut.x_stall_i.eq(0)
35 yield
36 yield dut.x_ld_i.eq(0)
37 yield Settle()
38 while (yield dut.x_stall_i):
39 yield
40 assert (yield dut.x_valid_i)
41 return (yield dut.m_ld_data_o)
42
43
44 def write_byte(dut, addr, val):
45 offset = addr & 0x3
46 yield dut.x_addr_i.eq(addr)
47 yield dut.x_st_i.eq(1)
48 yield dut.x_st_data_i.eq(val << (offset * 8))
49 yield dut.x_mask_i.eq(1 << offset)
50 print ("write_byte", addr, hex(1<<offset), hex(val<<(offset*8)))
51 yield dut.x_valid_i.eq(1)
52 yield dut.m_valid_i.eq(1)
53
54 yield
55 yield dut.x_st_i.eq(0)
56 while (yield dut.x_stall_i):
57 yield
58
59
60 def read_byte(dut, addr):
61 offset = addr & 0x3
62 yield dut.x_addr_i.eq(addr)
63 yield dut.x_ld_i.eq(1)
64 yield dut.x_valid_i.eq(1)
65 yield
66 yield dut.x_ld_i.eq(0)
67 yield Settle()
68 while (yield dut.x_stall_i):
69 yield
70 assert (yield dut.x_valid_i)
71 val = (yield dut.m_ld_data_o)
72 print ("read_byte", addr, offset, hex(val))
73 return (val >> (offset * 8)) & 0xff
74
75
76 def tst_lsmemtype(ifacetype):
77 m = Module()
78 Pspec = namedtuple('Pspec', ['ldst_ifacetype',
79 'addr_wid', 'mask_wid', 'reg_wid'])
80 pspec = Pspec(ldst_ifacetype=ifacetype, addr_wid=64, mask_wid=4, reg_wid=32)
81 dut = ConfigLoadStoreUnit(pspec).lsi
82 m.submodules.dut = dut
83
84 sim = Simulator(m)
85 sim.add_clock(1e-6)
86
87 def process():
88
89 values = [random.randint(0, (1<<32)-1) for x in range(16)]
90
91 for addr, val in enumerate(values):
92 yield from write_to_addr(dut, addr << 2, val)
93 x = yield from read_from_addr(dut, addr << 2)
94 print ("addr, val", addr, hex(val), hex(x))
95 assert x == val
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 sim.add_sync_process(process)
107 with sim.write_vcd("test_loadstore_%s.vcd" % ifacetype, traces=[]):
108 sim.run()
109
110 if __name__ == '__main__':
111 tst_lsmemtype('test_bare_wb')
112 tst_lsmemtype('testmem')