stop = False
-def wb_get(wb):
+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
- def b(x):
- return int.from_bytes(x.to_bytes(8, byteorder='little'),
- byteorder='big', signed=False)
-
- 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(0xc000000000000187),
-
- 0x1000000: # PROCESS_TABLE_3
- # RTS1 = 0x2 RPDB = 0x300 RTS2 = 0x5 RPDS = 13
- b(0x40000000000300ad),
-
- # data to return
- 0x1000: 0xdeadbeef01234567
- }
-
while not stop:
while True: # wait for dc_valid
if stop:
if addr not in mem:
print (" WB LOOKUP NO entry @ %x, returning zero" % (addr))
- data = mem.get(addr, 0)
- yield wb.dat_r.eq(data)
- print (" DCACHE get %x data %x" % (addr, data))
+ # 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 mmu_lookup(dut, addr):
mmu = dut.submodules.mmu
global stop
- print("pi_ld")
+ print("pi_ld", hex(addr))
data = yield from pi_ld(dut.submodules.ldst.pi, addr, 4, msr_pr=1)
print("pi_ld done, data", hex(data))
"""
yield
yield mmu.l_in.valid.eq(0)
- return phys_addr
+ return data
def ldst_sim(dut):
yield mmu.rin.prtbl.eq(0x1000000) # set process table
yield
+ # expecting this data to return
+ # 0x1000: 0xdeadbeef01234567,
+ # 0x1008: 0xfeedf00ff001a5a5
+
addr = 0x1000
print("pi_ld")
# TODO mmu_lookup using port interface
- # set inputs
- phys_addr = yield from mmu_lookup(dut, addr)
- #assert phys_addr == addr # happens to be the same (for this example)
+ # set inputs
+ data = yield from mmu_lookup(dut, addr)
+ assert data == 0x1234567
- phys_addr = yield from mmu_lookup(dut, addr)
+ data = yield from mmu_lookup(dut, addr+8)
+ assert data == 0xf001a5a5
#assert phys_addr == addr # happens to be the same (for this example)
+ data = yield from mmu_lookup(dut, addr+4)
+ assert data == 0xdeadbeef
+
+ data = yield from mmu_lookup(dut, addr+8)
+ assert data == 0xf001a5a5
+
+ yield from pi_st(dut.submodules.ldst.pi, addr+4, 0x10015a5a, 4, msr_pr=1)
+
+ data = yield from mmu_lookup(dut, addr+4)
+ assert data == 0x10015a5a
+
+ yield
+ yield
+
stop = True
comb += l_in.eq(ldst.m_out)
comb += ldst.m_in.eq(l_out)
+ # virtual "memory" to use for this test
+
+ 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),
+
+ # data to return
+ 0x1000: 0xdeadbeef01234567,
+ 0x1008: 0xfeedf00ff001a5a5
+ }
+
# nmigen Simulation
sim = Simulator(m)
sim.add_clock(1e-6)
sim.add_sync_process(wrap(ldst_sim(m)))
- sim.add_sync_process(wrap(wb_get(cmpi.wb_bus())))
+ sim.add_sync_process(wrap(wb_get(cmpi.wb_bus(), mem)))
with sim.write_vcd('test_ldst_pi.vcd'):
sim.run()