sort out misaligned store in LoadStore1
[soc.git] / src / soc / experiment / test / test_loadstore1.py
index 918c67dfb75d5216727ceb70e4fabc87fd5fee62..e79e0c127c22ef55947363498624f70b67d66806 100644 (file)
@@ -20,7 +20,7 @@ from soc.experiment.test import pagetables
 
 from nmigen.compat.sim import run_simulation
 from random import random
-from openpower.test.wb_get import wb_get
+from openpower.test.wb_get import wb_get_classic
 from openpower.test import wb_get as wbget
 from openpower.exceptions import LDSTExceptionTuple
 
@@ -167,9 +167,11 @@ def _test_loadstore1_ifetch_iface(dut, mem):
 
     wbget.stop = True
 
+
 def write_mem2(mem, addr, i1, i2):
     mem[addr] = i1 | i2<<32
 
+
 #TODO: use fetch interface here
 def lookup_virt(dut,addr):
     icache = dut.submodules.ldst.icache
@@ -193,6 +195,7 @@ def lookup_virt(dut,addr):
 
     return valid,failed
 
+
 def mmu_lookup(dut,addr):
     ldst = dut.submodules.ldst
     pi = ldst.pi
@@ -216,6 +219,7 @@ def mmu_lookup(dut,addr):
     yield
     yield
 
+
 def _test_loadstore1_ifetch_multi(dut, mem):
     mmu = dut.submodules.mmu
     ldst = dut.submodules.ldst
@@ -267,6 +271,7 @@ def _test_loadstore1_ifetch_multi(dut, mem):
 
     wbget.stop = True
 
+
 def _test_loadstore1_ifetch(dut, mem):
     """test_loadstore1_ifetch
 
@@ -488,6 +493,94 @@ def _test_loadstore1_invalid(dut, mem):
     wbget.stop = True
 
 
+def _test_loadstore1_microwatt_mmu_bin_test2(dut, mem):
+    mmu = dut.submodules.mmu
+    pi = dut.submodules.ldst.pi
+    ldst = dut.submodules.ldst # to get at DAR (NOT part of PortInterface)
+    wbget.stop = False
+
+    yield mmu.rin.prtbl.eq(0x12000) # set process table
+    yield mmu.rin.pid.eq(0x1)       # set PID=1
+    yield
+
+    addr = 0x124108
+    msr = MSRSpec(pr=1, dr=1, sf=1)
+
+    print("=== alignment error (ld) ===")
+
+    ld_data, exctype, exc = yield from pi_ld(pi, addr, 8, msr=msr)
+    print("ld_data after mmu.bin test2")
+    print(ld_data)
+    assert ld_data == 0x0000000badc0ffee
+    assert exctype is None
+
+    wbget.stop = True
+
+
+def _test_loadstore1_microwatt_mmu_bin_test5(dut, mem):
+    mmu = dut.submodules.mmu
+    pi = dut.submodules.ldst.pi
+    ldst = dut.submodules.ldst # to get at DAR (NOT part of PortInterface)
+    wbget.stop = False
+
+    yield mmu.rin.prtbl.eq(0x12000) # set process table
+    yield mmu.rin.pid.eq(0x1)       # set PID=1
+    yield
+
+    addr = 0x39fffd
+    msr = MSRSpec(pr=1, dr=1, sf=1)
+
+    print("=== page-fault alignment error (ld) ===")
+
+    ld_data, exctype, exc = yield from pi_ld(pi, addr, 8, msr=msr)
+    print("ld_data after mmu.bin test5")
+    print(ld_data)
+    print (exctype, exc)
+
+    wbget.stop = True
+
+
+def test_pi_ld_misalign(pi, addr, data_len, msr):
+    for i in range(0,data_len):
+        ld_data, exctype, exc = yield from pi_ld(pi, addr+i, data_len, msr=msr)
+        yield
+        assert exc is None # use "is None" not "== None"
+        print("MISALIGN: test_pi_ld_misalign returned",hex(ld_data))
+
+
+def test_pi_st_ld_misalign(pi, addr, data_len, msr):
+    data = 0x0102030405060708
+    for i in range(0, data_len):
+        exctype, exc = yield from pi_st(pi, addr+i, data, data_len, msr=msr)
+        print (exctype, exc)
+        assert exc is None # use "is None" not "== None"
+        ld_data, exctype, exc = yield from pi_ld(pi, addr+i, data_len, msr=msr)
+        yield
+        assert exc is None # use "is None" not "== None"
+        print("MISALIGN: test_pi_ld_misalign returned",hex(ld_data))
+        assert ld_data == data
+
+
+def _test_loadstore1_misalign(dut, mem):
+    mmu = dut.submodules.mmu
+    pi = dut.submodules.ldst.pi
+    ldst = dut.submodules.ldst # to get at DAR (NOT part of PortInterface)
+    wbget.stop = False
+
+    yield mmu.rin.prtbl.eq(0x12000) # set process table
+    yield mmu.rin.pid.eq(0x1)       # set PID=1
+    #yield
+
+    addr = 1
+    msr = MSRSpec(pr=0, dr=0, sf=1)
+
+    yield from test_pi_ld_misalign(pi,0,8,msr)
+
+    yield from test_pi_st_ld_misalign(pi,0,8,msr)
+
+    wbget.stop = True
+
+
 def _test_loadstore1(dut, mem):
     mmu = dut.submodules.mmu
     pi = dut.submodules.ldst.pi
@@ -499,9 +592,9 @@ def _test_loadstore1(dut, mem):
 
     addr = 0x100e0
     data = 0xf553b658ba7e1f51
+    msr = MSRSpec(pr=0, dr=0, sf=0)
 
     if test_dcbz:
-        msr = MSRSpec(pr=0, dr=0, sf=0)
         yield from pi_st(pi, addr, data, 8, msr=msr)
         yield
 
@@ -774,10 +867,10 @@ def test_loadstore1_ifetch_unit_iface():
     sim.add_clock(1e-6)
 
     sim.add_sync_process(wrap(_test_loadstore1_ifetch_iface(m, mem)))
-    # add two wb_get processes onto the *same* memory dictionary.
+    # add two wb_get_classic processes onto the *same* memory dictionary.
     # this shouuuld work.... cross-fingers...
-    sim.add_sync_process(wrap(wb_get(cmpi.wb_bus(), mem)))
-    sim.add_sync_process(wrap(wb_get(icache.ibus, mem))) # ibus not bus
+    sim.add_sync_process(wrap(wb_get_classic(cmpi.wb_bus(), mem)))
+    sim.add_sync_process(wrap(wb_get_classic(icache.ibus, mem))) # ibus not bus
     with sim.write_vcd('test_loadstore1_ifetch_iface.vcd',
                       traces=[m.debug_status]): # include extra debug
         sim.run()
@@ -795,10 +888,10 @@ def test_loadstore1_ifetch():
 
     icache = m.submodules.ldst.icache
     sim.add_sync_process(wrap(_test_loadstore1_ifetch(m, mem)))
-    # add two wb_get processes onto the *same* memory dictionary.
+    # add two wb_get_classic processes onto the *same* memory dictionary.
     # this shouuuld work.... cross-fingers...
-    sim.add_sync_process(wrap(wb_get(cmpi.wb_bus(), mem)))
-    sim.add_sync_process(wrap(wb_get(icache.bus, mem)))
+    sim.add_sync_process(wrap(wb_get_classic(cmpi.wb_bus(), mem)))
+    sim.add_sync_process(wrap(wb_get_classic(icache.bus, mem)))
     with sim.write_vcd('test_loadstore1_ifetch.vcd',
                       traces=[m.debug_status]): # include extra debug
         sim.run()
@@ -815,11 +908,64 @@ def test_loadstore1():
     sim.add_clock(1e-6)
 
     sim.add_sync_process(wrap(_test_loadstore1(m, mem)))
-    sim.add_sync_process(wrap(wb_get(cmpi.wb_bus(), mem)))
+    sim.add_sync_process(wrap(wb_get_classic(cmpi.wb_bus(), mem)))
     with sim.write_vcd('test_loadstore1.vcd'):
         sim.run()
 
 
+def test_loadstore1_microwatt_mmu_bin_test2():
+
+    m, cmpi = setup_mmu()
+
+    mem = pagetables.microwatt_test2
+
+    # nmigen Simulation
+    sim = Simulator(m)
+    sim.add_clock(1e-6)
+
+    sim.add_sync_process(wrap(_test_loadstore1_microwatt_mmu_bin_test2(m, mem)))
+    sim.add_sync_process(wrap(wb_get_classic(cmpi.wb_bus(), mem)))
+    with sim.write_vcd('test_microwatt_mmu_test2.vcd'):
+        sim.run()
+
+
+def test_loadstore1_microwatt_mmu_bin_test5():
+
+    m, cmpi = setup_mmu()
+
+    mem = pagetables.microwatt_test5
+
+    # nmigen Simulation
+    sim = Simulator(m)
+    sim.add_clock(1e-6)
+
+    sim.add_sync_process(wrap(_test_loadstore1_microwatt_mmu_bin_test5(m, mem)))
+    sim.add_sync_process(wrap(wb_get_classic(cmpi.wb_bus(), mem)))
+    with sim.write_vcd('test_microwatt_mmu_test5.vcd'):
+        sim.run()
+
+
+def test_loadstore1_misalign():
+
+    m, cmpi = setup_mmu()
+
+    mem = pagetables.microwatt_test2
+
+    # nmigen Simulation
+    sim = Simulator(m)
+    sim.add_clock(1e-6)
+
+    ###########1122334455667788
+    mem[0] = 0x0102030405060708
+    mem[8] = 0xffffffffffffffff
+
+    sim.add_sync_process(wrap(_test_loadstore1_misalign(m, mem)))
+    sim.add_sync_process(wrap(wb_get_classic(cmpi.wb_bus(), mem)))
+    with sim.write_vcd('test_loadstore1_misalign.vcd'):
+        sim.run()
+    print ("mem", mem)
+
+
 def test_loadstore1_invalid():
 
     m, cmpi = setup_mmu()
@@ -831,10 +977,11 @@ def test_loadstore1_invalid():
     sim.add_clock(1e-6)
 
     sim.add_sync_process(wrap(_test_loadstore1_invalid(m, mem)))
-    sim.add_sync_process(wrap(wb_get(cmpi.wb_bus(), mem)))
+    sim.add_sync_process(wrap(wb_get_classic(cmpi.wb_bus(), mem)))
     with sim.write_vcd('test_loadstore1_invalid.vcd'):
         sim.run()
 
+
 def test_loadstore1_ifetch_invalid():
     m, cmpi = setup_mmu()
 
@@ -848,14 +995,15 @@ def test_loadstore1_ifetch_invalid():
 
     icache = m.submodules.ldst.icache
     sim.add_sync_process(wrap(_test_loadstore1_ifetch_invalid(m, mem)))
-    # add two wb_get processes onto the *same* memory dictionary.
+    # add two wb_get_classic processes onto the *same* memory dictionary.
     # this shouuuld work.... cross-fingers...
-    sim.add_sync_process(wrap(wb_get(cmpi.wb_bus(), mem)))
-    sim.add_sync_process(wrap(wb_get(icache.bus, mem)))
+    sim.add_sync_process(wrap(wb_get_classic(cmpi.wb_bus(), mem)))
+    sim.add_sync_process(wrap(wb_get_classic(icache.bus, mem)))
     with sim.write_vcd('test_loadstore1_ifetch_invalid.vcd',
                       traces=[m.debug_status]): # include extra debug
         sim.run()
 
+
 def test_loadstore1_ifetch_multi():
     m, cmpi = setup_mmu()
     wbget.stop = False
@@ -875,18 +1023,21 @@ def test_loadstore1_ifetch_multi():
     sim.add_clock(1e-6)
 
     sim.add_sync_process(wrap(_test_loadstore1_ifetch_multi(m, mem)))
-    # add two wb_get processes onto the *same* memory dictionary.
+    # add two wb_get_classic processes onto the *same* memory dictionary.
     # this shouuuld work.... cross-fingers...
-    sim.add_sync_process(wrap(wb_get(cmpi.wb_bus(), mem)))
-    sim.add_sync_process(wrap(wb_get(icache.ibus, mem))) # ibus not bus
+    sim.add_sync_process(wrap(wb_get_classic(cmpi.wb_bus(), mem)))
+    sim.add_sync_process(wrap(wb_get_classic(icache.ibus, mem))) # ibus not bus
     with sim.write_vcd('test_loadstore1_ifetch_multi.vcd',
                       traces=[m.debug_status]): # include extra debug
         sim.run()
 
 if __name__ == '__main__':
-    test_loadstore1()
-    test_loadstore1_invalid()
-    test_loadstore1_ifetch() #FIXME
-    test_loadstore1_ifetch_invalid()
-    test_loadstore1_ifetch_unit_iface() # guess: should be working
-    test_loadstore1_ifetch_multi()
+    #test_loadstore1()
+    #test_loadstore1_microwatt_mmu_bin_test2()
+    #test_loadstore1_microwatt_mmu_bin_test5()
+    #test_loadstore1_invalid()
+    #test_loadstore1_ifetch() #FIXME
+    #test_loadstore1_ifetch_invalid()
+    #test_loadstore1_ifetch_unit_iface() # guess: should be working
+    #test_loadstore1_ifetch_multi()
+    test_loadstore1_misalign()