From: Luke Kenneth Casson Leighton Date: Fri, 3 Dec 2021 17:35:16 +0000 (+0000) Subject: fix up LDST test functions pi_ld and pi_st to respect timing X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=769c0b97600606e27d305d0fb748fb240c3442f2;p=soc.git fix up LDST test functions pi_ld and pi_st to respect timing (combinatorial setting followed by test followed by immediate unsetting is *not* ok. it has to be set WAIT (yield one clock) and *then* clear) added a simulation function get_exception_info() which returns a LDSTExceptionTuple containing the yield()ed exception information reason: at the time that the exception was raised, THAT is when the exception information must be obtained. by the time that the LDST port is_ld_i/is_st_i is lowered, that is far too late --- diff --git a/src/soc/config/test/test_pi2ls.py b/src/soc/config/test/test_pi2ls.py index 8c356595..1009d6f1 100644 --- a/src/soc/config/test/test_pi2ls.py +++ b/src/soc/config/test/test_pi2ls.py @@ -6,6 +6,7 @@ from nmigen.cli import rtlil import unittest from soc.config.test.test_loadstore import TestMemPspec from soc.config.loadstore import ConfigMemoryPortInterface +from openpower.exceptions import LDSTExceptionTuple def wait_busy(port, no=False, debug=None): @@ -57,7 +58,6 @@ def pi_st(port1, addr, data, datalen, msr_pr=0, is_dcbz=0): yield port1.addr.ok.eq(1) # set ok yield Settle() yield from wait_addr(port1) # wait until addr ok - yield from wait_addr(port1) # wait until addr ok # yield # not needed, just for checking # yield # not needed, just for checking @@ -66,14 +66,28 @@ def pi_st(port1, addr, data, datalen, msr_pr=0, is_dcbz=0): yield port1.st.ok.eq(1) yield yield port1.st.ok.eq(0) - exc_happened = yield port1.exc_o.happened + exc_info = yield from get_exception_info(port1.exc_o) + dar_o = yield port1.dar_o + exc_happened = exc_info.happened if exc_happened: - print("print fast exception happened") + print("print fast ST exception happened") + yield # MUST wait for one clock cycle before de-asserting these yield port1.is_st_i.eq(0) # end yield port1.addr.ok.eq(0) # set !ok yield port1.is_dcbz_i.eq(0) # reset dcbz too - return "fast" + return "fast", exc_info, dar_o + yield from wait_busy(port1,debug="pi_st_E") # wait while busy + exc_info = yield from get_exception_info(port1.exc_o) + dar_o = yield port1.dar_o + exc_happened = exc_info.happened + if exc_happened: + yield # needed if mmu/dache is used + yield port1.is_st_i.eq(0) # end + yield port1.addr.ok.eq(0) # set !ok + yield port1.is_dcbz_i.eq(0) # reset dcbz too + yield # needed if mmu/dache is used + return "slow", exc_info, dar_o # can go straight to reset. yield port1.is_st_i.eq(0) # end @@ -81,7 +95,15 @@ def pi_st(port1, addr, data, datalen, msr_pr=0, is_dcbz=0): yield port1.is_dcbz_i.eq(0) # reset dcbz too yield # needed if mmu/dache is used - return None + return None, None, None + +def get_exception_info(exc_o): + attrs = [] + for fname in LDSTExceptionTuple._fields: + attr = getattr(exc_o, fname) + val = yield attr + attrs.append(val) + return LDSTExceptionTuple(*attrs) # copy of pi_st removed @@ -100,31 +122,39 @@ def pi_ld(port1, addr, datalen, msr_pr=0): yield port1.addr.ok.eq(1) # set ok yield Settle() yield from wait_addr(port1) # wait until addr ok - exc_happened = yield port1.exc_o.happened + exc_info = yield from get_exception_info(port1.exc_o) + dar_o = yield port1.dar_o + exc_happened = exc_info.happened if exc_happened: - print("print fast exception happened") + print("print fast LD exception happened") + yield # MUST wait for one clock cycle before de-asserting these yield port1.is_ld_i.eq(0) # end yield port1.addr.ok.eq(0) # set !ok - return None, "fast" + return None, "fast", exc_info, dar_o yield yield from wait_ldok(port1) # wait until ld ok data = yield port1.ld.data + exc_info = yield from get_exception_info(port1.exc_o) + dar_o = yield port1.dar_o exc_happened = yield port1.exc_o.happened + exc_happened = exc_info.happened # cleanup yield port1.is_ld_i.eq(0) # end yield port1.addr.ok.eq(0) # set !ok if exc_happened: - return None, "slow" + return None, "slow", exc_info, dar_o yield from wait_busy(port1, debug="pi_ld_E") # wait while busy - exc_happened = yield port1.exc_o.happened + exc_info = yield from get_exception_info(port1.exc_o) + dar_o = yield port1.dar_o + exc_happened = exc_info.happened if exc_happened: - return None, "slow" + return None, "slow", exc_info, dar_o - return data, None + return data, None, None, None def pi_ldst(arg, dut, msr_pr=0):