# test case for LOAD / STORE Computation Unit using MMU
-#from nmigen.compat.sim import run_simulation
-from nmigen.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 openpower.test.wb_get import wb_get
+from openpower.test import wb_get as wbget
-def wait_for_debug(sig, event, wait=True, test1st=False):
+########################################
+
+def wait_for_debug(sig, reason, wait=True, test1st=False):
v = (yield sig)
- print("wait for", sig, v, wait, test1st)
+ 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)
- yield Display("waiting for "+event)
+ #print("...wait for", sig, v)
if bool(v) == wait:
break
-def load_debug(dut, src1, src2, imm, imm_ok=True, update=False, zero_a=False,
- byterev=True):
- print("LD", src1, src2, imm, imm_ok, update)
- yield dut.oper_i.insn_type.eq(MicrOp.OP_LOAD)
+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.oper_i.zero_a.eq(zero_a)
+ 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)
- # set up read-operand flags
- rd = 0b00
- if not imm_ok: # no immediate means RB register needs to be read
- rd |= 0b10
- if not zero_a: # no zero-a means RA needs to be read
- rd |= 0b01
-
- # wait for the operands (RA, RB, or both)
- if rd:
- yield dut.rd.go_i.eq(rd)
- yield from wait_for_debug(dut.rd.rel_o,"operands")
- yield dut.rd.go_i.eq(0)
-
- yield from wait_for_debug(dut.adr_rel_o, "adr_rel_o" ,False, test1st=True)
- yield Display("load_debug: done")
+ 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)
- """
- guess: hangs here
-
if update:
- yield from wait_for(dut.wr.rel_o[1])
+ yield from wait_for_debug(dut.wr.rel_o[1],"update")
yield dut.wr.go.eq(0b10)
yield
addr = yield dut.addr_o
yield dut.wr.go.eq(0)
else:
addr = None
+ print("not update ===============")
- yield from wait_for(dut.wr.rel_o[0], test1st=True)
- yield dut.wr.go.eq(1)
+ yield from wait_for_debug(dut.sto_rel_o,"sto_rel_o")
+ yield dut.go_st_i.eq(1)
yield
- data = yield dut.o_data
- print(data)
- yield dut.wr.go.eq(0)
- yield from wait_for(dut.busy_o)
+ 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
- # wait_for(dut.stwd_mem_o)
- return data, addr
- """
+ 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
- ###yield from dcbz(dut, 4, 0, 3) # EA=7
addr = 0x100e0
- data = 0xf553b658ba7e1f51
+ data = 0xFF #just a single byte for this test
+ #data = 0xf553b658ba7e1f51
yield from store(dut, addr, 0, data, 0)
yield
- yield from load_debug(dut, 4, 0, 2) #FIXME
- """
- ld_data = yield from pi_ld(pi, addr, 8, msr_pr=0)
- assert ld_data == 0xf553b658ba7e1f51
- ld_data = yield from pi_ld(pi, addr, 8, msr_pr=0)
- assert ld_data == 0xf553b658ba7e1f51
- """
+ ld_data, data_ok, ld_addr = yield from load(dut, addr, 0, 0)
+ print(data,data_ok,ld_addr)
+ assert(ld_data==data)
yield
- dut.stop = True # stop simulation
-########################################
+ 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 wb_get(dut):
- """simulator process for getting memory load requests
- """
- mem = dut.mem
- wb = dut.cmpi.wb_bus()
-
- # FIXME: this is redundant code
- while not dut.stop:
- while True: # wait for dc_valid
- if dut.stop:
- return
- cyc = yield (wb.cyc)
- stb = yield (wb.stb)
- if cyc and stb:
- break
- yield
- addr = (yield wb.adr) << 3
- if addr not in mem:
- print (" WB LOOKUP NO entry @ %x, returning zero" % (addr))
-
- # 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 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()