Allow the formal engine to perform a same-cycle result in the ALU
[soc.git] / src / soc / experiment / test / test_compldst_multi_mmu.py
index cb0ce66c4522cab0a3a19511d5cfd26292cd0218..f3a3421bcbe76a1a018fe313612b3a9a5f04932f 100644 (file)
-# test case for LOAD / STORE Computation Unit.
+# test case for LOAD / STORE Computation Unit using MMU
 
 
-
-from nmigen.compat.sim import run_simulation
+from nmigen.sim import Simulator, Delay, Settle, Tick
 from nmigen.cli import verilog, rtlil
 from nmigen import Module, Signal, Mux, Cat, Elaboratable, Array, Repl
 from nmigen.hdl.rec import Record, Layout
 
 from nmigen.cli import verilog, rtlil
 from nmigen import Module, Signal, Mux, Cat, Elaboratable, Array, Repl
 from nmigen.hdl.rec import Record, Layout
 
-"""
 from nmutil.latch import SRLatch, latchregister
 from nmutil.byterev import byte_reverse
 from nmutil.extend import exts
 from nmutil.latch import SRLatch, latchregister
 from nmutil.byterev import byte_reverse
 from nmutil.extend import exts
-
+from nmutil.util import wrap
 from soc.fu.regspec import RegSpecAPI
 
 from openpower.decoder.power_enums import MicrOp, Function, LDSTMode
 from soc.fu.ldst.ldst_input_record import CompLDSTOpSubset
 from openpower.decoder.power_decoder2 import Data
 from openpower.consts import MSR
 from soc.fu.regspec import RegSpecAPI
 
 from openpower.decoder.power_enums import MicrOp, Function, LDSTMode
 from soc.fu.ldst.ldst_input_record import CompLDSTOpSubset
 from openpower.decoder.power_decoder2 import Data
 from openpower.consts import MSR
-"""
 
 from soc.experiment.compalu_multi import go_record, CompUnitRecord
 from soc.experiment.l0_cache import PortInterface
 from soc.experiment.pimem import LDSTException
 
 from soc.experiment.compalu_multi import go_record, CompUnitRecord
 from soc.experiment.l0_cache import PortInterface
 from soc.experiment.pimem import LDSTException
-from soc.experiment.compldst_multi import LDSTCompUnit
+from soc.experiment.compldst_multi import LDSTCompUnit, load, store
 from soc.config.test.test_loadstore import TestMemPspec
 
 from soc.config.test.test_loadstore import TestMemPspec
 
+from soc.experiment.mmu import MMU
+from nmutil.util import Display
+
+from soc.config.loadstore import ConfigMemoryPortInterface
+from soc.experiment.test import pagetables
+from openpower.test.wb_get import wb_get
+from openpower.test import wb_get as wbget
+
+
 ########################################
 
 ########################################
 
+def wait_for_debug(sig, reason, wait=True, test1st=False):
+    v = (yield sig)
+    cnt = 0
+    print("wait for", reason, sig, v, wait, test1st)
+    if test1st and bool(v) == wait:
+        return
+    while True:
+        cnt = cnt + 1
+        if cnt > 15:
+            raise(Exception(reason))
+            break
+        yield
+        v = (yield sig)
+        #print("...wait for", sig, v)
+        if bool(v) == wait:
+            break
+
+def store_debug(dut, src1, src2, src3, imm, imm_ok=True, update=False,
+          byterev=True,dcbz=False):
+    print("cut here ======================================")
+    print("ST", src1, src2, src3, imm, imm_ok, update)
+    if dcbz:
+        yield dut.oper_i.insn_type.eq(MicrOp.OP_DCBZ)
+    else:
+        yield dut.oper_i.insn_type.eq(MicrOp.OP_STORE)
+    yield dut.oper_i.data_len.eq(2)  # half-word
+    yield dut.oper_i.byte_reverse.eq(byterev)
+    yield dut.src1_i.eq(src1)
+    yield dut.src2_i.eq(src2)
+    yield dut.src3_i.eq(src3)
+    yield dut.oper_i.imm_data.data.eq(imm)
+    yield dut.oper_i.imm_data.ok.eq(imm_ok)
+    #guess: this one was removed -- yield dut.oper_i.update.eq(update)
+    yield dut.issue_i.eq(1)
+    yield
+    yield dut.issue_i.eq(0)
+
+    if imm_ok:
+        active_rel = 0b101
+    else:
+        active_rel = 0b111
+    if dcbz:
+        active_rel = 0b001 # may be wrong, verify
+
+    # wait for all active rel signals to come up
+    cnt = 0
+    while True:
+        rel = yield dut.rd.rel_o # guess: wrong in dcbz case
+        cnt = cnt + 1
+        print("waitActiveRel",cnt)
+        if cnt > 10:
+            raise(Exception("Error1"))
+        print("rel EQ active_rel ?",rel,active_rel)
+        if rel == active_rel:
+            break
+        yield
+    yield dut.rd.go_i.eq(active_rel)
+    yield
+    yield dut.rd.go_i.eq(0)
+
+    yield from wait_for_debug(dut.adr_rel_o, "addr valid",False, test1st=True)
+    # yield from wait_for(dut.adr_rel_o)
+    # yield dut.ad.go.eq(1)
+    # yield
+    # yield dut.ad.go.eq(0)
+
+    if update:
+        yield from wait_for_debug(dut.wr.rel_o[1],"update")
+        yield dut.wr.go.eq(0b10)
+        yield
+        addr = yield dut.addr_o
+        print("addr", addr)
+        yield dut.wr.go.eq(0)
+    else:
+        addr = None
+        print("not update ===============")
+
+    yield from wait_for_debug(dut.sto_rel_o,"sto_rel_o")
+    yield dut.go_st_i.eq(1)
+    yield
+    yield dut.go_st_i.eq(0)
+    yield from wait_for_debug(dut.busy_o,"not_busy" ,False)
+    ###wait_for(dut.stwd_mem_o)
+    yield
+    return addr
+
+# same thing as soc/src/soc/experiment/test/test_dcbz_pi.py
 def ldst_sim(dut):
 def ldst_sim(dut):
-    print("TODO")
+    yield dut.mmu.rin.prtbl.eq(0x1000000) # set process table
+    addr = 0x100e0
+    data = 0xFF #just a single byte for this test
+    #data = 0xf553b658ba7e1f51
+
+    yield from store(dut, addr, 0, data, 0)
+    yield
+    ld_data, data_ok, ld_addr = yield from load(dut, addr, 0, 0)
+    print(data,data_ok,ld_addr)
+    assert(ld_data==data)
     yield
 
     yield
 
-########################################
+    data = 0
 
 
+    print("doing dcbz/store with data 0 .....")
+    yield from store_debug(dut, addr, 0, data, 0, dcbz=True) #hangs
 
 
+    ld_data, data_ok, ld_addr = yield from load(dut, addr, 0, 0)
+    print(data,data_ok,ld_addr)
+    print("ld_data is")
+    print(ld_data)
+    assert(ld_data==data)
+    print("dzbz test passed")
+
+    wbget.stop = True # stop simulation
+
+########################################
 class TestLDSTCompUnitMMU(LDSTCompUnit):
 
     def __init__(self, rwid, pspec):
 class TestLDSTCompUnitMMU(LDSTCompUnit):
 
     def __init__(self, rwid, pspec):
-        from soc.experiment.l0_cache import TstL0CacheBuffer
-        self.l0 = l0 = TstL0CacheBuffer(pspec)
-        pi = l0.l0.dports[0]
-        LDSTCompUnit.__init__(self, pi, rwid, 4)
+        # use a LoadStore1 here
+        cmpi = ConfigMemoryPortInterface(pspec)
+        self.cmpi = cmpi
+        ldst = cmpi.pi
+        self.l0 = ldst
+
+        self.mmu = MMU()
+        LDSTCompUnit.__init__(self, ldst.pi, rwid, 4)
 
     def elaborate(self, platform):
         m = LDSTCompUnit.elaborate(self, platform)
         m.submodules.l0 = self.l0
 
     def elaborate(self, platform):
         m = LDSTCompUnit.elaborate(self, platform)
         m.submodules.l0 = self.l0
+        m.submodules.mmu = self.mmu
         # link addr-go direct to rel
         m.d.comb += self.ad.go_i.eq(self.ad.rel_o)
         # link addr-go direct to rel
         m.d.comb += self.ad.go_i.eq(self.ad.rel_o)
+
+        # link mmu and dcache together
+        dcache = self.l0.dcache
+        mmu = self.mmu
+        m.d.comb += dcache.m_in.eq(mmu.d_out) # MMUToDCacheType
+        m.d.comb += mmu.d_in.eq(dcache.m_out) # DCacheToMMUType
+
         return m
 
 
 def test_scoreboard_mmu():
 
         return m
 
 
 def test_scoreboard_mmu():
 
+    m = Module()
+
     units = {}
     pspec = TestMemPspec(ldst_ifacetype='mmu_cache_wb',
                          imem_ifacetype='bare_wb',
     units = {}
     pspec = TestMemPspec(ldst_ifacetype='mmu_cache_wb',
                          imem_ifacetype='bare_wb',
@@ -61,33 +189,55 @@ def test_scoreboard_mmu():
                          units=units)
 
     dut = TestLDSTCompUnitMMU(16,pspec)
                          units=units)
 
     dut = TestLDSTCompUnitMMU(16,pspec)
-    vl = rtlil.convert(dut, ports=dut.ports())
-    with open("test_ldst_comp_mmu1.il", "w") as f:
-        f.write(vl)
 
 
-    run_simulation(dut, ldst_sim(dut), vcd_name='test_ldst_comp.vcd')
+    m.submodules.dut = dut
+
+    sim = Simulator(m)
+    sim.add_clock(1e-6)
+
+    dut.mem = pagetables.test1
+    wbget.stop = False
+
+    sim.add_sync_process(wrap(ldst_sim(dut)))
+    sim.add_sync_process(wrap(wb_get(dut.cmpi.wb_bus(), dut.mem)))
+    with sim.write_vcd('test_scoreboard_mmu.vcd'):
+        sim.run()
 
 ########################################
 class TestLDSTCompUnitRegSpecMMU(LDSTCompUnit):
 
     def __init__(self, pspec):
 
 ########################################
 class TestLDSTCompUnitRegSpecMMU(LDSTCompUnit):
 
     def __init__(self, pspec):
-        from soc.experiment.l0_cache import TstL0CacheBuffer
         from soc.fu.ldst.pipe_data import LDSTPipeSpec
         regspec = LDSTPipeSpec.regspec
         from soc.fu.ldst.pipe_data import LDSTPipeSpec
         regspec = LDSTPipeSpec.regspec
-        self.l0 = l0 = TstL0CacheBuffer(pspec)
-        pi = l0.l0.dports[0]
-        LDSTCompUnit.__init__(self, pi, regspec, 4)
+
+        # use a LoadStore1 here
+        cmpi = ConfigMemoryPortInterface(pspec)
+        self.cmpi = cmpi
+        ldst = cmpi.pi
+        self.l0 = ldst
+
+        self.mmu = MMU()
+        LDSTCompUnit.__init__(self, ldst.pi, regspec, 4)
 
     def elaborate(self, platform):
         m = LDSTCompUnit.elaborate(self, platform)
         m.submodules.l0 = self.l0
 
     def elaborate(self, platform):
         m = LDSTCompUnit.elaborate(self, platform)
         m.submodules.l0 = self.l0
+        m.submodules.mmu = self.mmu
         # link addr-go direct to rel
         m.d.comb += self.ad.go_i.eq(self.ad.rel_o)
         # link addr-go direct to rel
         m.d.comb += self.ad.go_i.eq(self.ad.rel_o)
-        return m
 
 
+        # link mmu and dcache together
+        dcache = self.l0.dcache
+        mmu = self.mmu
+        m.d.comb += dcache.m_in.eq(mmu.d_out) # MMUToDCacheType
+        m.d.comb += mmu.d_in.eq(dcache.m_out) # DCacheToMMUType
+
+        return m
 
 def test_scoreboard_regspec_mmu():
 
 
 def test_scoreboard_regspec_mmu():
 
+    m = Module()
+
     units = {}
     pspec = TestMemPspec(ldst_ifacetype='mmu_cache_wb',
                          imem_ifacetype='bare_wb',
     units = {}
     pspec = TestMemPspec(ldst_ifacetype='mmu_cache_wb',
                          imem_ifacetype='bare_wb',
@@ -97,13 +247,20 @@ def test_scoreboard_regspec_mmu():
                          units=units)
 
     dut = TestLDSTCompUnitRegSpecMMU(pspec)
                          units=units)
 
     dut = TestLDSTCompUnitRegSpecMMU(pspec)
-    vl = rtlil.convert(dut, ports=dut.ports())
-    with open("test_ldst_comp_mmu2.il", "w") as f:
-        f.write(vl)
 
 
-    run_simulation(dut, ldst_sim(dut), vcd_name='test_ldst_regspec.vcd')
+    m.submodules.dut = dut
+
+    sim = Simulator(m)
+    sim.add_clock(1e-6)
+
+    dut.mem = pagetables.test1
+    wbget.stop = False
 
 
+    sim.add_sync_process(wrap(ldst_sim(dut)))
+    sim.add_sync_process(wrap(wb_get(dut.cmpi.wb_bus(), dut.mem)))
+    with sim.write_vcd('test_scoreboard_regspec_mmu.vcd'):
+        sim.run()
 
 if __name__ == '__main__':
     test_scoreboard_regspec_mmu()
 
 if __name__ == '__main__':
     test_scoreboard_regspec_mmu()
-    #only one test for now -- test_scoreboard_mmu()
+    test_scoreboard_mmu()