test_compldst_multi_mmu.py: verify dcbz result, add debug outputs
[soc.git] / src / soc / experiment / test / test_compldst_multi_mmu.py
1 # test case for LOAD / STORE Computation Unit using MMU
2
3 from nmigen.back.pysim import Simulator, Delay, Settle, Tick
4 from nmigen.cli import verilog, rtlil
5 from nmigen import Module, Signal, Mux, Cat, Elaboratable, Array, Repl
6 from nmigen.hdl.rec import Record, Layout
7
8 from nmutil.latch import SRLatch, latchregister
9 from nmutil.byterev import byte_reverse
10 from nmutil.extend import exts
11 from nmutil.util import wrap
12 from soc.fu.regspec import RegSpecAPI
13
14 from openpower.decoder.power_enums import MicrOp, Function, LDSTMode
15 from soc.fu.ldst.ldst_input_record import CompLDSTOpSubset
16 from openpower.decoder.power_decoder2 import Data
17 from openpower.consts import MSR
18
19 from soc.experiment.compalu_multi import go_record, CompUnitRecord
20 from soc.experiment.l0_cache import PortInterface
21 from soc.experiment.pimem import LDSTException
22 from soc.experiment.compldst_multi import LDSTCompUnit, load, store
23 from soc.config.test.test_loadstore import TestMemPspec
24
25 from soc.experiment.mmu import MMU
26 from nmutil.util import Display
27
28 from soc.config.loadstore import ConfigMemoryPortInterface
29 from soc.experiment.test import pagetables
30 from soc.experiment.test.test_wishbone import wb_get
31
32 ########################################
33
34 def wait_for_debug(sig, wait=True, test1st=False):
35 v = (yield sig)
36 cnt = 0
37 print("wait for", sig, v, wait, test1st)
38 if test1st and bool(v) == wait:
39 return
40 while True:
41 cnt = cnt + 1
42 if cnt > 1000:
43 print("hang")
44 break
45 yield
46 v = (yield sig)
47 #print("...wait for", sig, v)
48 if bool(v) == wait:
49 break
50
51 def store_debug(dut, src1, src2, src3, imm, imm_ok=True, update=False,
52 byterev=True,dcbz=False):
53 print("ST", src1, src2, src3, imm, imm_ok, update)
54 if dcbz:
55 yield dut.oper_i.insn_type.eq(MicrOp.OP_DCBZ)
56 else:
57 yield dut.oper_i.insn_type.eq(MicrOp.OP_STORE)
58 yield dut.oper_i.data_len.eq(2) # half-word
59 yield dut.oper_i.byte_reverse.eq(byterev)
60 yield dut.src1_i.eq(src1)
61 yield dut.src2_i.eq(src2)
62 yield dut.src3_i.eq(src3)
63 yield dut.oper_i.imm_data.data.eq(imm)
64 yield dut.oper_i.imm_data.ok.eq(imm_ok)
65 #guess: this one was removed -- yield dut.oper_i.update.eq(update)
66 yield dut.issue_i.eq(1)
67 yield
68 yield dut.issue_i.eq(0)
69
70 if imm_ok:
71 active_rel = 0b101
72 else:
73 active_rel = 0b111
74 # wait for all active rel signals to come up
75 cnt = 0
76 while True:
77 rel = yield dut.rd.rel_o
78 cnt = cnt + 1
79 if cnt > 1000:
80 print("hang in -- wait for all active rel signals to come up")
81 break
82 if rel == active_rel:
83 break
84 yield
85 yield dut.rd.go_i.eq(active_rel)
86 yield
87 yield dut.rd.go_i.eq(0)
88
89 yield from wait_for_debug(dut.adr_rel_o, False, test1st=True)
90 # yield from wait_for(dut.adr_rel_o)
91 # yield dut.ad.go.eq(1)
92 # yield
93 # yield dut.ad.go.eq(0)
94
95 if update:
96 yield from wait_for_debug(dut.wr.rel_o[1])
97 yield dut.wr.go.eq(0b10)
98 yield
99 addr = yield dut.addr_o
100 print("addr", addr)
101 yield dut.wr.go.eq(0)
102 else:
103 addr = None
104
105 yield from wait_for_debug(dut.sto_rel_o)
106 yield dut.go_st_i.eq(1)
107 yield
108 yield dut.go_st_i.eq(0)
109 yield from wait_for_debug(dut.busy_o, False)
110 # wait_for(dut.stwd_mem_o)
111 yield
112 return addr
113
114 # same thing as soc/src/soc/experiment/test/test_dcbz_pi.py
115 def ldst_sim(dut):
116 yield dut.mmu.rin.prtbl.eq(0x1000000) # set process table
117 addr = 0x100e0
118 data = 0xFF #just a single byte for this test
119 #data = 0xf553b658ba7e1f51
120
121 yield from store(dut, addr, 0, data, 0)
122 yield
123 ld_data, data_ok, ld_addr = yield from load(dut, addr, 0, 0)
124 print(data,data_ok,ld_addr)
125 assert(ld_data==data)
126 yield
127
128 data = 0
129
130 print("doing dcbz/store with data 0 .....")
131 yield from store_debug(dut, addr, 0, data, 0, dcbz=True) #hangs
132
133 # TODO verify
134 ld_data, data_ok, ld_addr = yield from load(dut, addr, 0, 0)
135 print(data,data_ok,ld_addr)
136 print("ld_data is")
137 print(ld_data)
138 assert(ld_data==data)
139 print("dzbz test passed")
140
141 dut.stop = True # stop simulation
142
143 ########################################
144
145
146 class TestLDSTCompUnitMMU(LDSTCompUnit):
147
148 def __init__(self, rwid, pspec):
149 from soc.experiment.l0_cache import TstL0CacheBuffer
150 self.l0 = l0 = TstL0CacheBuffer(pspec)
151 pi = l0.l0.dports[0]
152 LDSTCompUnit.__init__(self, pi, rwid, 4)
153
154 def elaborate(self, platform):
155 m = LDSTCompUnit.elaborate(self, platform)
156 m.submodules.l0 = self.l0
157 # link addr-go direct to rel
158 m.d.comb += self.ad.go_i.eq(self.ad.rel_o)
159 return m
160
161
162 def test_scoreboard_mmu():
163
164 units = {}
165 pspec = TestMemPspec(ldst_ifacetype='mmu_cache_wb',
166 imem_ifacetype='bare_wb',
167 addr_wid=48,
168 mask_wid=8,
169 reg_wid=64,
170 units=units)
171
172 dut = TestLDSTCompUnitMMU(16,pspec)
173 vl = rtlil.convert(dut, ports=dut.ports())
174 with open("test_ldst_comp_mmu1.il", "w") as f:
175 f.write(vl)
176
177 run_simulation(dut, ldst_sim(dut), vcd_name='test_ldst_comp.vcd')
178
179 ########################################
180 class TestLDSTCompUnitRegSpecMMU(LDSTCompUnit):
181
182 def __init__(self, pspec):
183 from soc.experiment.l0_cache import TstL0CacheBuffer
184 from soc.fu.ldst.pipe_data import LDSTPipeSpec
185 regspec = LDSTPipeSpec.regspec
186
187 # use a LoadStore1 here
188
189 cmpi = ConfigMemoryPortInterface(pspec)
190 self.cmpi = cmpi
191 ldst = cmpi.pi
192 self.l0 = ldst
193
194 self.mmu = MMU()
195 LDSTCompUnit.__init__(self, ldst.pi, regspec, 4)
196
197 def elaborate(self, platform):
198 m = LDSTCompUnit.elaborate(self, platform)
199 m.submodules.l0 = self.l0
200 m.submodules.mmu = self.mmu
201 # link addr-go direct to rel
202 m.d.comb += self.ad.go_i.eq(self.ad.rel_o)
203
204 # link mmu and dcache together
205 dcache = self.l0.dcache
206 mmu = self.mmu
207 m.d.comb += dcache.m_in.eq(mmu.d_out) # MMUToDCacheType
208 m.d.comb += mmu.d_in.eq(dcache.m_out) # DCacheToMMUType
209
210 return m
211
212
213
214
215 def test_scoreboard_regspec_mmu():
216
217 m = Module()
218
219 units = {}
220 pspec = TestMemPspec(ldst_ifacetype='mmu_cache_wb',
221 imem_ifacetype='bare_wb',
222 addr_wid=48,
223 mask_wid=8,
224 reg_wid=64,
225 units=units)
226
227 dut = TestLDSTCompUnitRegSpecMMU(pspec)
228
229 m.submodules.dut = dut
230
231 sim = Simulator(m)
232 sim.add_clock(1e-6)
233
234 dut.mem = pagetables.test1
235 dut.stop = False
236
237 sim.add_sync_process(wrap(ldst_sim(dut)))
238 sim.add_sync_process(wrap(wb_get(dut)))
239 with sim.write_vcd('test_scoreboard_regspec_mmu'):
240 sim.run()
241
242
243 if __name__ == '__main__':
244 test_scoreboard_regspec_mmu()
245 #only one test for now -- test_scoreboard_mmu()