--- /dev/null
+"""DCache PortInterface Test
+ starting as a copy to test_ldst_pi.py
+"""
+
+from nmigen import (C, Module, Signal, Elaboratable, Mux, Cat, Repl, Signal)
+from nmigen.cli import main
+from nmigen.cli import rtlil
+from nmutil.mask import Mask, masked
+from nmutil.util import Display
+from random import randint, seed
+
+if True:
+ from nmigen.back.pysim import Simulator, Delay, Settle
+else:
+ from nmigen.sim.cxxsim import Simulator, Delay, Settle
+from nmutil.util import wrap
+
+from soc.config.test.test_pi2ls import pi_ld, pi_st, pi_ldst
+from soc.config.test.test_loadstore import TestMemPspec
+from soc.config.loadstore import ConfigMemoryPortInterface
+
+from soc.fu.ldst.loadstore import LoadStore1
+from soc.experiment.mmu import MMU
+
+from nmigen.compat.sim import run_simulation
+
+
+stop = False
+
+def b(x): # byte-reverse function
+ return int.from_bytes(x.to_bytes(8, byteorder='little'),
+ byteorder='big', signed=False)
+
+def wb_get(wb, mem):
+ """simulator process for getting memory load requests
+ """
+
+ global stop
+ assert(stop==False)
+
+ while not stop:
+ while True: # wait for dc_valid
+ if stop:
+ return
+ cyc = yield (wb.cyc)
+ stb = yield (wb.stb)
+ if cyc and stb:
+ break
+ yield
+ addr = (yield wb.adr) << 3
+ if addr not in mem:
+ print (" WB LOOKUP NO entry @ %x, returning zero" % (addr))
+
+ # read or write?
+ we = (yield wb.we)
+ if we:
+ store = (yield wb.dat_w)
+ sel = (yield wb.sel)
+ data = mem.get(addr, 0)
+ # note we assume 8-bit sel, here
+ res = 0
+ for i in range(8):
+ mask = 0xff << (i*8)
+ if sel & (1<<i):
+ res |= store & mask
+ else:
+ res |= data & mask
+ mem[addr] = res
+ print (" DCACHE set %x mask %x data %x" % (addr, sel, res))
+ else:
+ data = mem.get(addr, 0)
+ yield wb.dat_r.eq(data)
+ print (" DCACHE get %x data %x" % (addr, data))
+
+ yield wb.ack.eq(1)
+ yield
+ yield wb.ack.eq(0)
+ yield
+
+def setup_mmu():
+
+ global stop
+ stop = False
+
+ pspec = TestMemPspec(ldst_ifacetype='mmu_cache_wb',
+ imem_ifacetype='',
+ addr_wid=48,
+ #disable_cache=True, # hmmm...
+ mask_wid=8,
+ reg_wid=64)
+
+ m = Module()
+ comb = m.d.comb
+ cmpi = ConfigMemoryPortInterface(pspec)
+ m.submodules.ldst = ldst = cmpi.pi
+ m.submodules.mmu = mmu = MMU()
+ dcache = ldst.dcache
+
+ l_in, l_out = mmu.l_in, mmu.l_out
+ d_in, d_out = dcache.d_in, dcache.d_out
+ wb_out, wb_in = dcache.wb_out, dcache.wb_in
+
+ # link mmu and dcache together
+ m.d.comb += dcache.m_in.eq(mmu.d_out) # MMUToDCacheType
+ m.d.comb += mmu.d_in.eq(dcache.m_out) # DCacheToMMUType
+
+ # link ldst and MMU together
+ comb += l_in.eq(ldst.m_out)
+ comb += ldst.m_in.eq(l_out)
+
+ return m, cmpi
+
+### test case for dcbz
+
+def _test_dcbz_addr_zero(dut, mem):
+ mmu = dut.submodules.mmu
+ pi = dut.submodules.ldst.pi
+ global stop
+ stop = False
+
+ yield mmu.rin.prtbl.eq(0x1000000) # set process table
+ yield
+
+ ###### TODO
+ #yield from pi_dcbz(pi, addr, data, 8, msr_pr=1)
+ #yield
+
+ yield
+ stop = True
+
+def test_dcbz_addr_zero():
+
+ m, cmpi = setup_mmu()
+
+ # dcache_load at addr 0
+ mem = {
+ 0x10000: # PARTITION_TABLE_2
+ # PATB_GR=1 PRTB=0x1000 PRTS=0xb
+ b(0x800000000100000b),
+
+ 0x30000: # RADIX_ROOT_PTE
+ # V = 1 L = 0 NLB = 0x400 NLS = 9
+ b(0x8000000000040009),
+
+ 0x40000: # RADIX_SECOND_LEVEL
+ # V = 1 L = 1 SW = 0 RPN = 0
+ # R = 1 C = 1 ATT = 0 EAA 0x7
+ b(0xc000000000000183),
+
+ 0x1000000: # PROCESS_TABLE_3
+ # RTS1 = 0x2 RPDB = 0x300 RTS2 = 0x5 RPDS = 13
+ b(0x40000000000300ad),
+
+ }
+
+ # nmigen Simulation
+ sim = Simulator(m)
+ sim.add_clock(1e-6)
+
+ sim.add_sync_process(wrap(_test_dcbz_addr_zero(m, mem)))
+ sim.add_sync_process(wrap(wb_get(cmpi.wb_bus(), mem)))
+ with sim.write_vcd('test_ldst_pi_random2.vcd'):
+ sim.run()
+
+if __name__ == '__main__':
+ test_dcbz_addr_zero()