1 # test case for LOAD / STORE Computation Unit using MMU
3 #from nmigen.compat.sim import run_simulation
4 from nmigen
.sim
import Simulator
, Delay
, Settle
5 from nmigen
.cli
import verilog
, rtlil
6 from nmigen
import Module
, Signal
, Mux
, Cat
, Elaboratable
, Array
, Repl
7 from nmigen
.hdl
.rec
import Record
, Layout
9 from nmutil
.latch
import SRLatch
, latchregister
10 from nmutil
.byterev
import byte_reverse
11 from nmutil
.extend
import exts
12 from nmutil
.util
import wrap
13 from soc
.fu
.regspec
import RegSpecAPI
15 from openpower
.decoder
.power_enums
import MicrOp
, Function
, LDSTMode
16 from soc
.fu
.ldst
.ldst_input_record
import CompLDSTOpSubset
17 from openpower
.decoder
.power_decoder2
import Data
18 from openpower
.consts
import MSR
20 from soc
.experiment
.compalu_multi
import go_record
, CompUnitRecord
21 from soc
.experiment
.l0_cache
import PortInterface
22 from soc
.experiment
.pimem
import LDSTException
23 from soc
.experiment
.compldst_multi
import LDSTCompUnit
, load
, store
24 from soc
.config
.test
.test_loadstore
import TestMemPspec
26 from soc
.experiment
.mmu
import MMU
27 from nmutil
.util
import Display
29 from soc
.config
.loadstore
import ConfigMemoryPortInterface
30 from soc
.experiment
.test
import pagetables
33 def wait_for_debug(sig
, event
, wait
=True, test1st
=False):
35 print("wait for", sig
, v
, wait
, test1st
)
36 if test1st
and bool(v
) == wait
:
41 yield Display("waiting for "+event
)
45 def load_debug(dut
, src1
, src2
, imm
, imm_ok
=True, update
=False, zero_a
=False,
47 print("LD", src1
, src2
, imm
, imm_ok
, update
)
48 yield dut
.oper_i
.insn_type
.eq(MicrOp
.OP_LOAD
)
49 yield dut
.oper_i
.data_len
.eq(2) # half-word
50 yield dut
.oper_i
.byte_reverse
.eq(byterev
)
51 yield dut
.src1_i
.eq(src1
)
52 yield dut
.src2_i
.eq(src2
)
53 yield dut
.oper_i
.zero_a
.eq(zero_a
)
54 yield dut
.oper_i
.imm_data
.data
.eq(imm
)
55 yield dut
.oper_i
.imm_data
.ok
.eq(imm_ok
)
56 yield dut
.issue_i
.eq(1)
58 yield dut
.issue_i
.eq(0)
61 # set up read-operand flags
63 if not imm_ok
: # no immediate means RB register needs to be read
65 if not zero_a
: # no zero-a means RA needs to be read
68 # wait for the operands (RA, RB, or both)
70 yield dut
.rd
.go_i
.eq(rd
)
71 yield from wait_for_debug(dut
.rd
.rel_o
,"operands")
72 yield dut
.rd
.go_i
.eq(0)
74 yield from wait_for_debug(dut
.adr_rel_o
, "adr_rel_o" ,False, test1st
=True)
75 yield Display("load_debug: done")
76 # yield dut.ad.go.eq(1)
78 # yield dut.ad.go.eq(0)
84 yield from wait_for(dut.wr.rel_o[1])
85 yield dut.wr.go.eq(0b10)
87 addr = yield dut.addr_o
93 yield from wait_for(dut.wr.rel_o[0], test1st=True)
96 data = yield dut.o_data
99 yield from wait_for(dut.busy_o)
101 # wait_for(dut.stwd_mem_o)
105 # same thing as soc/src/soc/experiment/test/test_dcbz_pi.py
107 yield dut
.mmu
.rin
.prtbl
.eq(0x1000000) # set process table
108 ###yield from dcbz(dut, 4, 0, 3) # EA=7
110 data
= 0xf553b658ba7e1f51
112 yield from store(dut
, addr
, 0, data
, 0)
114 yield from load_debug(dut
, 4, 0, 2) #FIXME
116 ld_data = yield from pi_ld(pi, addr, 8, msr_pr=0)
117 assert ld_data == 0xf553b658ba7e1f51
118 ld_data = yield from pi_ld(pi, addr, 8, msr_pr=0)
119 assert ld_data == 0xf553b658ba7e1f51
122 dut
.stop
= True # stop simulation
124 ########################################
127 class TestLDSTCompUnitMMU(LDSTCompUnit
):
129 def __init__(self
, rwid
, pspec
):
130 from soc
.experiment
.l0_cache
import TstL0CacheBuffer
131 self
.l0
= l0
= TstL0CacheBuffer(pspec
)
133 LDSTCompUnit
.__init
__(self
, pi
, rwid
, 4)
135 def elaborate(self
, platform
):
136 m
= LDSTCompUnit
.elaborate(self
, platform
)
137 m
.submodules
.l0
= self
.l0
138 # link addr-go direct to rel
139 m
.d
.comb
+= self
.ad
.go_i
.eq(self
.ad
.rel_o
)
143 def test_scoreboard_mmu():
146 pspec
= TestMemPspec(ldst_ifacetype
='mmu_cache_wb',
147 imem_ifacetype
='bare_wb',
153 dut
= TestLDSTCompUnitMMU(16,pspec
)
154 vl
= rtlil
.convert(dut
, ports
=dut
.ports())
155 with
open("test_ldst_comp_mmu1.il", "w") as f
:
158 run_simulation(dut
, ldst_sim(dut
), vcd_name
='test_ldst_comp.vcd')
160 ########################################
161 class TestLDSTCompUnitRegSpecMMU(LDSTCompUnit
):
163 def __init__(self
, pspec
):
164 from soc
.experiment
.l0_cache
import TstL0CacheBuffer
165 from soc
.fu
.ldst
.pipe_data
import LDSTPipeSpec
166 regspec
= LDSTPipeSpec
.regspec
168 # use a LoadStore1 here
170 cmpi
= ConfigMemoryPortInterface(pspec
)
176 LDSTCompUnit
.__init
__(self
, ldst
.pi
, regspec
, 4)
178 def elaborate(self
, platform
):
179 m
= LDSTCompUnit
.elaborate(self
, platform
)
180 m
.submodules
.l0
= self
.l0
181 m
.submodules
.mmu
= self
.mmu
182 # link addr-go direct to rel
183 m
.d
.comb
+= self
.ad
.go_i
.eq(self
.ad
.rel_o
)
185 # link mmu and dcache together
186 dcache
= self
.l0
.dcache
188 m
.d
.comb
+= dcache
.m_in
.eq(mmu
.d_out
) # MMUToDCacheType
189 m
.d
.comb
+= mmu
.d_in
.eq(dcache
.m_out
) # DCacheToMMUType
195 """simulator process for getting memory load requests
198 wb
= dut
.cmpi
.wb_bus()
200 # FIXME: this is redundant code
202 while True: # wait for dc_valid
210 addr
= (yield wb
.adr
) << 3
212 print (" WB LOOKUP NO entry @ %x, returning zero" % (addr
))
217 store
= (yield wb
.dat_w
)
219 data
= mem
.get(addr
, 0)
220 # note we assume 8-bit sel, here
229 print (" DCACHE set %x mask %x data %x" % (addr
, sel
, res
))
231 data
= mem
.get(addr
, 0)
232 yield wb
.dat_r
.eq(data
)
233 print (" DCACHE get %x data %x" % (addr
, data
))
240 def test_scoreboard_regspec_mmu():
245 pspec
= TestMemPspec(ldst_ifacetype
='mmu_cache_wb',
246 imem_ifacetype
='bare_wb',
252 dut
= TestLDSTCompUnitRegSpecMMU(pspec
)
254 m
.submodules
.dut
= dut
259 dut
.mem
= pagetables
.test1
262 sim
.add_sync_process(wrap(ldst_sim(dut
)))
263 sim
.add_sync_process(wrap(wb_get(dut
)))
264 with sim
.write_vcd('test_scoreboard_regspec_mmu'):
268 if __name__
== '__main__':
269 test_scoreboard_regspec_mmu()
270 #only one test for now -- test_scoreboard_mmu()