# test case for LOAD / STORE Computation Unit using MMU
-#from nmigen.compat.sim import run_simulation
-from nmigen.compat.sim import Simulator, Delay, Settle
+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 soc.config.loadstore import ConfigMemoryPortInterface
from soc.experiment.test import pagetables
-from soc.experiment.test.test_wishbone import wb_get
+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):
yield dut.mmu.rin.prtbl.eq(0x1000000) # set process table
addr = 0x100e0
- data = 0xf553b658ba7e1f51
+ data = 0xFF #just a single byte for this test
+ #data = 0xf553b658ba7e1f51
yield from store(dut, addr, 0, data, 0)
yield
- #TODO
- dut.stop = True # stop simulation
+ ld_data, data_ok, ld_addr = yield from load(dut, addr, 0, 0)
+ print(data,data_ok,ld_addr)
+ assert(ld_data==data)
+ 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):
- 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
+ m.submodules.mmu = self.mmu
# 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():
+ m = Module()
+
units = {}
pspec = TestMemPspec(ldst_ifacetype='mmu_cache_wb',
imem_ifacetype='bare_wb',
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):
- from soc.experiment.l0_cache import TstL0CacheBuffer
from soc.fu.ldst.pipe_data import LDSTPipeSpec
regspec = LDSTPipeSpec.regspec
# use a LoadStore1 here
-
cmpi = ConfigMemoryPortInterface(pspec)
self.cmpi = cmpi
ldst = cmpi.pi
return m
-
-
-
def test_scoreboard_regspec_mmu():
m = Module()
sim.add_clock(1e-6)
dut.mem = pagetables.test1
- dut.stop = False
+ wbget.stop = False
sim.add_sync_process(wrap(ldst_sim(dut)))
- sim.add_sync_process(wrap(wb_get(dut)))
- with sim.write_vcd('test_scoreboard_regspec_mmu'):
+ 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()
- #only one test for now -- test_scoreboard_mmu()
+ test_scoreboard_mmu()