From 1cb2400058158d328de7c8a96ca9fe6e8305e0e6 Mon Sep 17 00:00:00 2001 From: Tobias Platen Date: Mon, 4 Oct 2021 19:22:36 +0200 Subject: [PATCH] add wishbone driver for test_compldst_multi_mmu.py --- .../test/test_compldst_multi_mmu.py | 159 +++++++++++++++--- 1 file changed, 138 insertions(+), 21 deletions(-) diff --git a/src/soc/experiment/test/test_compldst_multi_mmu.py b/src/soc/experiment/test/test_compldst_multi_mmu.py index 0a8ac0d5..e8179960 100644 --- a/src/soc/experiment/test/test_compldst_multi_mmu.py +++ b/src/soc/experiment/test/test_compldst_multi_mmu.py @@ -1,6 +1,7 @@ # test case for LOAD / STORE Computation Unit using MMU -from nmigen.compat.sim import run_simulation +#from nmigen.compat.sim import run_simulation +from nmigen.sim import Simulator, Delay, Settle from nmigen.cli import verilog, rtlil from nmigen import Module, Signal, Mux, Cat, Elaboratable, Array, Repl from nmigen.hdl.rec import Record, Layout @@ -8,6 +9,7 @@ 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.util import wrap from soc.fu.regspec import RegSpecAPI from openpower.decoder.power_enums import MicrOp, Function, LDSTMode @@ -26,6 +28,11 @@ from nmutil.util import Display from soc.config.loadstore import ConfigMemoryPortInterface +def b(x): # byte-reverse function + return int.from_bytes(x.to_bytes(8, byteorder='little'), + byteorder='big', signed=False) +#FIXME: move to common module + def wait_for_debug(sig, event, wait=True, test1st=False): v = (yield sig) print("wait for", sig, v, wait, test1st) @@ -38,33 +45,67 @@ def wait_for_debug(sig, event, wait=True, test1st=False): if bool(v) == wait: break -# if RA = 0 then b <- 0 RA needs to be read if RA = 0 -# else b <-(RA) -# EA <- b + (RB) RB needs to be read -# verify that EA is correct first -def dcbz(dut, ra, zero_a, rb): - print("LD_part", ra, zero_a, rb) - yield dut.oper_i.insn_type.eq(MicrOp.OP_DCBZ) - yield dut.src1_i.eq(ra) - yield dut.src2_i.eq(rb) +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) + 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.oper_i.imm_data.data.eq(imm) + yield dut.oper_i.imm_data.ok.eq(imm_ok) yield dut.issue_i.eq(1) yield yield dut.issue_i.eq(0) yield - # set up operand flags - rd = 0b10 + # 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 (RA, RB, or both)") + 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 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 dut.wr.go.eq(0b10) + yield + addr = yield dut.addr_o + print("addr", addr) + yield dut.wr.go.eq(0) + else: + addr = None + + yield from wait_for(dut.wr.rel_o[0], test1st=True) + yield dut.wr.go.eq(1) + yield + data = yield dut.o_data + print(data) + yield dut.wr.go.eq(0) + yield from wait_for(dut.busy_o) + yield + # wait_for(dut.stwd_mem_o) + return data, addr + """ + +# removed # same thing as soc/src/soc/experiment/test/test_dcbz_pi.py def ldst_sim(dut): @@ -75,7 +116,7 @@ def ldst_sim(dut): yield from store(dut, addr, 0, data, 0) yield - yield from load(dut, 4, 0, 2) #FIXME + 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 @@ -153,12 +194,59 @@ class TestLDSTCompUnitRegSpecMMU(LDSTCompUnit): m.d.comb += dcache.m_in.eq(mmu.d_out) # MMUToDCacheType m.d.comb += mmu.d_in.eq(dcache.m_out) # DCacheToMMUType - # TODO: link wishbone bus - return m +# FIXME: this is redundant code +def wb_get(wb, mem): + """simulator process for getting memory load requests + """ + + global stop + assert(stop==False) + + while not stop: + while True: # wait for dc_valid + if stop: + return + cyc = yield (wb.cyc) + stb = yield (wb.stb) + if cyc and stb: + break + yield + addr = (yield wb.adr) << 3 + stop = True # hack for testing + 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<