remove extraneous yields
[soc.git] / src / soc / experiment / test / test_pi2ls.py
1 from nmigen import Signal, Module, Record
2 from nmigen.back.pysim import Simulator, Delay
3 from nmigen.compat.sim import run_simulation, Settle
4 from nmutil.formaltest import FHDLTestCase
5 from nmigen.cli import rtlil
6 import unittest
7 from soc.experiment.pi2ls import Pi2LSUI
8 from soc.experiment.lsmem import TestMemLoadStoreUnit
9 from soc.experiment.pimem import TestMemoryPortInterface
10
11 def wait_busy(port, no=False):
12 while True:
13 busy = yield port.pi.busy_o
14 print("busy", no, busy)
15 if bool(busy) == no:
16 break
17 yield
18
19
20 def wait_addr(port):
21 while True:
22 addr_ok = yield port.pi.addr_ok_o
23 print("addrok", addr_ok)
24 if addr_ok:
25 break
26 yield
27
28
29 def wait_ldok(port):
30 while True:
31 ldok = yield port.pi.ld.ok
32 print("ldok", ldok)
33 if ldok:
34 break
35 yield
36
37
38 def l0_cache_st(dut, addr, data, datalen):
39 if isinstance(dut.pi, Record):
40 port1 = dut
41 else:
42 port1 = dut.pi
43
44 # have to wait until not busy
45 yield from wait_busy(port1, no=False) # wait until not busy
46
47 # set up a ST on the port. address first:
48 yield port1.pi.is_st_i.eq(1) # indicate ST
49 yield port1.pi.data_len.eq(datalen) # ST length (1/2/4/8)
50
51 yield port1.pi.addr.data.eq(addr) # set address
52 yield port1.pi.addr.ok.eq(1) # set ok
53 yield Settle()
54 yield from wait_addr(port1) # wait until addr ok
55 # yield # not needed, just for checking
56 # yield # not needed, just for checking
57 # assert "ST" for one cycle (required by the API)
58 yield port1.pi.st.data.eq(data)
59 yield port1.pi.st.ok.eq(1)
60 yield
61 yield port1.pi.st.ok.eq(0)
62
63 # can go straight to reset.
64 yield port1.pi.is_st_i.eq(0) # end
65 yield port1.pi.addr.ok.eq(0) # set !ok
66 # yield from wait_busy(port1, False) # wait until not busy
67
68
69 def l0_cache_ld(dut, addr, datalen, expected):
70
71 if isinstance(dut.pi, Record):
72 port1 = dut
73 else:
74 port1 = dut.pi
75
76 # have to wait until not busy
77 yield from wait_busy(port1, no=False) # wait until not busy
78
79 # set up a LD on the port. address first:
80 yield port1.pi.is_ld_i.eq(1) # indicate LD
81 yield port1.pi.data_len.eq(datalen) # LD length (1/2/4/8)
82
83 yield port1.pi.addr.data.eq(addr) # set address
84 yield port1.pi.addr.ok.eq(1) # set ok
85 yield Settle()
86 yield from wait_addr(port1) # wait until addr ok
87 yield
88 yield from wait_ldok(port1) # wait until ld ok
89 data = yield port1.pi.ld.data
90
91 # cleanup
92 yield port1.pi.is_ld_i.eq(0) # end
93 yield port1.pi.addr.ok.eq(0) # set !ok
94 # yield from wait_busy(port1, no=False) # wait until not busy
95
96 return data
97
98
99 def l0_cache_ldst(arg, dut):
100 yield
101 addr = 0x2
102 data = 0xbeef
103 data2 = 0xf00f
104 #data = 0x4
105 yield from l0_cache_st(dut, 0x2, data, 2)
106 yield from l0_cache_st(dut, 0x4, data2, 2)
107 result = yield from l0_cache_ld(dut, 0x2, 2, data)
108 result2 = yield from l0_cache_ld(dut, 0x4, 2, data2)
109 arg.assertEqual(data, result, "data %x != %x" % (result, data))
110 arg.assertEqual(data2, result2, "data2 %x != %x" % (result2, data2))
111
112
113
114 class TestPIMem(unittest.TestCase):
115
116 def test_pi_mem(self):
117
118 dut = TestMemoryPortInterface(regwid=64)
119 #vl = rtlil.convert(dut, ports=dut.ports())
120 #with open("test_basic_l0_cache.il", "w") as f:
121 # f.write(vl)
122
123 run_simulation(dut, {"sync": l0_cache_ldst(self, dut)},
124 vcd_name='test_pi_mem_basic.vcd')
125
126 def test_pi2ls(self):
127 m = Module()
128 regwid = 64
129 addrwid = 48
130 m.submodules.dut = dut = Pi2LSUI("mem", regwid=regwid, addrwid=addrwid)
131 m.submodules.lsmem = lsmem = TestMemLoadStoreUnit(addr_wid=addrwid,
132 mask_wid=8,
133 data_wid=regwid)
134
135 # Connect inputs
136 m.d.comb += [lsmem.x_addr_i.eq(dut.lsui.x_addr_i),
137 lsmem.x_mask_i.eq(dut.lsui.x_mask_i),
138 lsmem.x_ld_i.eq(dut.lsui.x_ld_i),
139 lsmem.x_st_i.eq(dut.lsui.x_st_i),
140 lsmem.x_st_data_i.eq(dut.lsui.x_st_data_i),
141 lsmem.x_stall_i.eq(dut.lsui.x_stall_i),
142 lsmem.x_valid_i.eq(dut.lsui.x_valid_i),
143 lsmem.m_stall_i.eq(dut.lsui.m_stall_i),
144 lsmem.m_valid_i.eq(dut.lsui.m_valid_i)]
145
146 m.d.comb += [dut.lsui.x_busy_o.eq(lsmem.x_busy_o),
147 dut.lsui.m_busy_o.eq(lsmem.m_busy_o),
148 dut.lsui.m_ld_data_o.eq(lsmem.m_ld_data_o),
149 dut.lsui.m_load_err_o.eq(lsmem.m_load_err_o),
150 dut.lsui.m_store_err_o.eq(lsmem.m_store_err_o),
151 dut.lsui.m_badaddr_o.eq(lsmem.m_badaddr_o)]
152
153 run_simulation(m, {"sync": l0_cache_ldst(self, dut)},
154 vcd_name='test_pi2ls.vcd')
155
156 if __name__ == '__main__':
157 unittest.main(exit=False)