rename LoadStoreInterface signals to include _i and _o suffixes
[soc.git] / src / soc / experiment / lsmem.py
1 from soc.minerva.units.loadstore import LoadStoreUnitInterface
2 from nmigen import Signal, Module, Elaboratable, Mux
3 from soc.experiment.testmem import TestMemory # TODO: replace with TMLSUI
4 import random
5
6 from nmigen.back.pysim import Simulator, Settle
7
8
9 class TestMemLoadStoreUnit(LoadStoreUnitInterface, Elaboratable):
10 def __init__(self, regwid, addrwid):
11 super().__init__()
12 self.regwid = regwid
13 self.addrwid = addrwid
14 def elaborate(self, platform):
15 m = Module()
16
17
18 m.submodules.mem = mem = TestMemory(
19 self.regwid, self.addrwid, granularity=8)
20
21 do_load = Signal() # set when doing a load while valid and not stalled
22 do_store = Signal() # set when doing a store while valid and not stalled
23
24 m.d.comb += [
25 do_load.eq(self.x_ld_i & (self.x_valid_i & ~self.x_stall_i)),
26 do_store.eq(self.x_st_i & (self.x_valid_i & ~self.x_stall_i)),
27 ]
28 m.d.comb += [
29 mem.rdport.addr.eq(self.x_addr_i[2:]),
30 self.m_ld_data_o.eq(mem.rdport.data),
31
32 mem.wrport.addr.eq(self.x_addr_i[2:]),
33 mem.wrport.en.eq(Mux(do_store, self.x_mask_i, 0)),
34 mem.wrport.data.eq(self.x_st_data_i)
35 ]
36
37 return m
38
39
40 def write_to_addr(dut, addr, value):
41 yield dut.x_addr_i.eq(addr)
42 yield dut.x_st_data_i.eq(value)
43 yield dut.x_st_i.eq(1)
44 yield dut.x_mask_i.eq(-1)
45 yield dut.x_valid_i.eq(1)
46 yield dut.x_stall_i.eq(1)
47 yield
48 yield
49
50 yield dut.x_stall_i.eq(0)
51 yield
52 yield dut.x_st_i.eq(0)
53 while (yield dut.x_stall_i):
54 yield
55
56
57 def read_from_addr(dut, addr):
58 yield dut.x_addr_i.eq(addr)
59 yield dut.x_ld_i.eq(1)
60 yield dut.x_valid_i.eq(1)
61 yield dut.x_stall_i.eq(1)
62 yield
63 yield dut.x_stall_i.eq(0)
64 yield
65 yield dut.x_ld_i.eq(0)
66 yield Settle()
67 while (yield dut.x_stall_i):
68 yield
69 assert (yield dut.x_valid_i)
70 return (yield dut.m_ld_data_o)
71
72
73 def write_byte(dut, addr, val):
74 offset = addr & 0x3
75 yield dut.x_addr_i.eq(addr)
76 yield dut.x_st_i.eq(1)
77 yield dut.x_st_data_i.eq(val << (offset * 8))
78 yield dut.x_mask_i.eq(1 << offset)
79 yield dut.x_valid_i.eq(1)
80
81 yield
82 yield dut.x_st_i.eq(0)
83 while (yield dut.x_stall_i):
84 yield
85
86
87 def read_byte(dut, addr):
88 offset = addr & 0x3
89 yield dut.x_addr_i.eq(addr)
90 yield dut.x_ld_i.eq(1)
91 yield dut.x_valid_i.eq(1)
92 yield
93 yield dut.x_ld_i.eq(0)
94 yield Settle()
95 while (yield dut.x_stall_i):
96 yield
97 assert (yield dut.x_valid_i)
98 val = (yield dut.m_ld_data_o)
99 return (val >> (offset * 8)) & 0xff
100
101
102 if __name__ == '__main__':
103 m = Module()
104 dut = TestMemLoadStoreUnit(regwid=32, addrwid=4)
105 m.submodules.dut = dut
106
107 sim = Simulator(m)
108 sim.add_clock(1e-6)
109
110 def process():
111
112 values = [random.randint(0, (1<<32)-1) for x in range(16)]
113
114 for addr, val in enumerate(values):
115 yield from write_to_addr(dut, addr << 2, val)
116 for addr, val in enumerate(values):
117 x = yield from read_from_addr(dut, addr << 2)
118 assert x == val
119
120 values = [random.randint(0, 255) for x in range(16*4)]
121 for addr, val in enumerate(values):
122 yield from write_byte(dut, addr, val)
123 for addr, val in enumerate(values):
124 x = yield from read_byte(dut, addr)
125 assert x == val
126
127 sim.add_sync_process(process)
128 with sim.write_vcd("lsmem.vcd", "lsmem.gtkw", traces=[]):
129 sim.run()