minor rework of wb_get, make generic
[soc.git] / src / soc / experiment / test / test_ldst_pi.py
index 290cbf5e081138d922a497efd52f500775d5e304..aa3087c6f9c449edd17c75f266dfaceb58466380 100644 (file)
@@ -28,37 +28,16 @@ from nmigen.compat.sim import run_simulation
 
 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:
@@ -72,19 +51,38 @@ def wb_get(wb):
         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))
     """
@@ -113,7 +111,7 @@ def mmu_lookup(dut, addr):
     yield
     yield mmu.l_in.valid.eq(0)
 
-    return phys_addr
+    return data
 
 
 def ldst_sim(dut):
@@ -122,17 +120,36 @@ 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
 
 
@@ -164,13 +181,37 @@ def test_mmu():
     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()