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
31 def b(x
): # byte-reverse function
32 return int.from_bytes(x
.to_bytes(8, byteorder
='little'),
33 byteorder
='big', signed
=False)
34 #FIXME: move to common module
36 def wait_for_debug(sig
, event
, wait
=True, test1st
=False):
38 print("wait for", sig
, v
, wait
, test1st
)
39 if test1st
and bool(v
) == wait
:
44 yield Display("waiting for "+event
)
48 def load_debug(dut
, src1
, src2
, imm
, imm_ok
=True, update
=False, zero_a
=False,
50 print("LD", src1
, src2
, imm
, imm_ok
, update
)
51 yield dut
.oper_i
.insn_type
.eq(MicrOp
.OP_LOAD
)
52 yield dut
.oper_i
.data_len
.eq(2) # half-word
53 yield dut
.oper_i
.byte_reverse
.eq(byterev
)
54 yield dut
.src1_i
.eq(src1
)
55 yield dut
.src2_i
.eq(src2
)
56 yield dut
.oper_i
.zero_a
.eq(zero_a
)
57 yield dut
.oper_i
.imm_data
.data
.eq(imm
)
58 yield dut
.oper_i
.imm_data
.ok
.eq(imm_ok
)
59 yield dut
.issue_i
.eq(1)
61 yield dut
.issue_i
.eq(0)
64 # set up read-operand flags
66 if not imm_ok
: # no immediate means RB register needs to be read
68 if not zero_a
: # no zero-a means RA needs to be read
71 # wait for the operands (RA, RB, or both)
73 yield dut
.rd
.go_i
.eq(rd
)
74 yield from wait_for_debug(dut
.rd
.rel_o
,"operands")
75 yield dut
.rd
.go_i
.eq(0)
77 yield from wait_for_debug(dut
.adr_rel_o
, "adr_rel_o" ,False, test1st
=True)
78 yield Display("load_debug: done")
79 # yield dut.ad.go.eq(1)
81 # yield dut.ad.go.eq(0)
87 yield from wait_for(dut.wr.rel_o[1])
88 yield dut.wr.go.eq(0b10)
90 addr = yield dut.addr_o
96 yield from wait_for(dut.wr.rel_o[0], test1st=True)
99 data = yield dut.o_data
101 yield dut.wr.go.eq(0)
102 yield from wait_for(dut.busy_o)
104 # wait_for(dut.stwd_mem_o)
110 # same thing as soc/src/soc/experiment/test/test_dcbz_pi.py
112 yield dut
.mmu
.rin
.prtbl
.eq(0x1000000) # set process table
113 ###yield from dcbz(dut, 4, 0, 3) # EA=7
115 data
= 0xf553b658ba7e1f51
117 yield from store(dut
, addr
, 0, data
, 0)
119 yield from load_debug(dut
, 4, 0, 2) #FIXME
121 ld_data = yield from pi_ld(pi, addr, 8, msr_pr=0)
122 assert ld_data == 0xf553b658ba7e1f51
123 ld_data = yield from pi_ld(pi, addr, 8, msr_pr=0)
124 assert ld_data == 0xf553b658ba7e1f51
128 ########################################
131 class TestLDSTCompUnitMMU(LDSTCompUnit
):
133 def __init__(self
, rwid
, pspec
):
134 from soc
.experiment
.l0_cache
import TstL0CacheBuffer
135 self
.l0
= l0
= TstL0CacheBuffer(pspec
)
137 LDSTCompUnit
.__init
__(self
, pi
, rwid
, 4)
139 def elaborate(self
, platform
):
140 m
= LDSTCompUnit
.elaborate(self
, platform
)
141 m
.submodules
.l0
= self
.l0
142 # link addr-go direct to rel
143 m
.d
.comb
+= self
.ad
.go_i
.eq(self
.ad
.rel_o
)
147 def test_scoreboard_mmu():
150 pspec
= TestMemPspec(ldst_ifacetype
='mmu_cache_wb',
151 imem_ifacetype
='bare_wb',
157 dut
= TestLDSTCompUnitMMU(16,pspec
)
158 vl
= rtlil
.convert(dut
, ports
=dut
.ports())
159 with
open("test_ldst_comp_mmu1.il", "w") as f
:
162 run_simulation(dut
, ldst_sim(dut
), vcd_name
='test_ldst_comp.vcd')
163 #TODO add wb runner here
166 ########################################
167 class TestLDSTCompUnitRegSpecMMU(LDSTCompUnit
):
169 def __init__(self
, pspec
):
170 from soc
.experiment
.l0_cache
import TstL0CacheBuffer
171 from soc
.fu
.ldst
.pipe_data
import LDSTPipeSpec
172 regspec
= LDSTPipeSpec
.regspec
174 # use a LoadStore1 here
176 cmpi
= ConfigMemoryPortInterface(pspec
)
182 LDSTCompUnit
.__init
__(self
, ldst
.pi
, regspec
, 4)
184 def elaborate(self
, platform
):
185 m
= LDSTCompUnit
.elaborate(self
, platform
)
186 m
.submodules
.l0
= self
.l0
187 m
.submodules
.mmu
= self
.mmu
188 # link addr-go direct to rel
189 m
.d
.comb
+= self
.ad
.go_i
.eq(self
.ad
.rel_o
)
191 # link mmu and dcache together
192 dcache
= self
.l0
.dcache
194 m
.d
.comb
+= dcache
.m_in
.eq(mmu
.d_out
) # MMUToDCacheType
195 m
.d
.comb
+= mmu
.d_in
.eq(dcache
.m_out
) # DCacheToMMUType
199 # FIXME: this is redundant code
201 """simulator process for getting memory load requests
208 while True: # wait for dc_valid
216 addr
= (yield wb
.adr
) << 3
217 stop
= True # hack for testing
219 print (" WB LOOKUP NO entry @ %x, returning zero" % (addr
))
224 store
= (yield wb
.dat_w
)
226 data
= mem
.get(addr
, 0)
227 # note we assume 8-bit sel, here
236 print (" DCACHE set %x mask %x data %x" % (addr
, sel
, res
))
238 data
= mem
.get(addr
, 0)
239 yield wb
.dat_r
.eq(data
)
240 print (" DCACHE get %x data %x" % (addr
, data
))
247 def test_scoreboard_regspec_mmu():
252 pspec
= TestMemPspec(ldst_ifacetype
='mmu_cache_wb',
253 imem_ifacetype
='bare_wb',
259 dut
= TestLDSTCompUnitRegSpecMMU(pspec
)
261 m
.submodules
.dut
= dut
266 sim
.add_sync_process(wrap(ldst_sim(dut
)))
268 # FIXME: this is redundant code
270 0x10000: # PARTITION_TABLE_2
271 # PATB_GR=1 PRTB=0x1000 PRTS=0xb
272 b(0x800000000100000b),
274 0x30000: # RADIX_ROOT_PTE
275 # V = 1 L = 0 NLB = 0x400 NLS = 9
276 b(0x8000000000040009),
278 0x40000: # RADIX_SECOND_LEVEL
279 # V = 1 L = 1 SW = 0 RPN = 0
280 # R = 1 C = 1 ATT = 0 EAA 0x7
281 b(0xc000000000000183),
283 0x1000000: # PROCESS_TABLE_3
284 # RTS1 = 0x2 RPDB = 0x300 RTS2 = 0x5 RPDS = 13
285 b(0x40000000000300ad),
291 sim
.add_sync_process(wrap(wb_get(dut
.cmpi
.wb_bus(), mem
)))
292 with sim
.write_vcd('test_dcbz_addr_zero.vcd'):
296 if __name__
== '__main__':
297 #FIXME: avoid using global variables
300 test_scoreboard_regspec_mmu()
301 #only one test for now -- test_scoreboard_mmu()