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)
107 # same thing as soc/src/soc/experiment/test/test_dcbz_pi.py
109 yield dut
.mmu
.rin
.prtbl
.eq(0x1000000) # set process table
110 ###yield from dcbz(dut, 4, 0, 3) # EA=7
112 data
= 0xf553b658ba7e1f51
114 yield from store(dut
, addr
, 0, data
, 0)
116 yield from load_debug(dut
, 4, 0, 2) #FIXME
118 ld_data = yield from pi_ld(pi, addr, 8, msr_pr=0)
119 assert ld_data == 0xf553b658ba7e1f51
120 ld_data = yield from pi_ld(pi, addr, 8, msr_pr=0)
121 assert ld_data == 0xf553b658ba7e1f51
125 ########################################
128 class TestLDSTCompUnitMMU(LDSTCompUnit
):
130 def __init__(self
, rwid
, pspec
):
131 from soc
.experiment
.l0_cache
import TstL0CacheBuffer
132 self
.l0
= l0
= TstL0CacheBuffer(pspec
)
134 LDSTCompUnit
.__init
__(self
, pi
, rwid
, 4)
136 def elaborate(self
, platform
):
137 m
= LDSTCompUnit
.elaborate(self
, platform
)
138 m
.submodules
.l0
= self
.l0
139 # link addr-go direct to rel
140 m
.d
.comb
+= self
.ad
.go_i
.eq(self
.ad
.rel_o
)
144 def test_scoreboard_mmu():
147 pspec
= TestMemPspec(ldst_ifacetype
='mmu_cache_wb',
148 imem_ifacetype
='bare_wb',
154 dut
= TestLDSTCompUnitMMU(16,pspec
)
155 vl
= rtlil
.convert(dut
, ports
=dut
.ports())
156 with
open("test_ldst_comp_mmu1.il", "w") as f
:
159 run_simulation(dut
, ldst_sim(dut
), vcd_name
='test_ldst_comp.vcd')
160 #TODO add wb runner here
163 ########################################
164 class TestLDSTCompUnitRegSpecMMU(LDSTCompUnit
):
166 def __init__(self
, pspec
):
167 from soc
.experiment
.l0_cache
import TstL0CacheBuffer
168 from soc
.fu
.ldst
.pipe_data
import LDSTPipeSpec
169 regspec
= LDSTPipeSpec
.regspec
171 # use a LoadStore1 here
173 cmpi
= ConfigMemoryPortInterface(pspec
)
179 LDSTCompUnit
.__init
__(self
, ldst
.pi
, regspec
, 4)
181 def elaborate(self
, platform
):
182 m
= LDSTCompUnit
.elaborate(self
, platform
)
183 m
.submodules
.l0
= self
.l0
184 m
.submodules
.mmu
= self
.mmu
185 # link addr-go direct to rel
186 m
.d
.comb
+= self
.ad
.go_i
.eq(self
.ad
.rel_o
)
188 # link mmu and dcache together
189 dcache
= self
.l0
.dcache
191 m
.d
.comb
+= dcache
.m_in
.eq(mmu
.d_out
) # MMUToDCacheType
192 m
.d
.comb
+= mmu
.d_in
.eq(dcache
.m_out
) # DCacheToMMUType
196 # FIXME: this is redundant code
198 """simulator process for getting memory load requests
205 while True: # wait for dc_valid
213 addr
= (yield wb
.adr
) << 3
214 stop
= True # hack for testing
216 print (" WB LOOKUP NO entry @ %x, returning zero" % (addr
))
221 store
= (yield wb
.dat_w
)
223 data
= mem
.get(addr
, 0)
224 # note we assume 8-bit sel, here
233 print (" DCACHE set %x mask %x data %x" % (addr
, sel
, res
))
235 data
= mem
.get(addr
, 0)
236 yield wb
.dat_r
.eq(data
)
237 print (" DCACHE get %x data %x" % (addr
, data
))
244 def test_scoreboard_regspec_mmu():
249 pspec
= TestMemPspec(ldst_ifacetype
='mmu_cache_wb',
250 imem_ifacetype
='bare_wb',
256 dut
= TestLDSTCompUnitRegSpecMMU(pspec
)
258 m
.submodules
.dut
= dut
263 mem
= pagetables
.test1
265 sim
.add_sync_process(wrap(ldst_sim(dut
)))
266 sim
.add_sync_process(wrap(wb_get(dut
.cmpi
.wb_bus(), mem
)))
267 with sim
.write_vcd('test_scoreboard_regspec_mmu'):
271 if __name__
== '__main__':
272 #FIXME: avoid using global variables
275 test_scoreboard_regspec_mmu()
276 #only one test for now -- test_scoreboard_mmu()