From: Luke Kenneth Casson Leighton Date: Sat, 27 Jun 2020 12:34:57 +0000 (+0100) Subject: reconfigureable PortInterface testing now possible X-Git-Tag: div_pipeline~242 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=a2a001a8250da93af2cacdaebd0b388eaf6b1d47;p=soc.git reconfigureable PortInterface testing now possible --- diff --git a/src/soc/config/loadstore.py b/src/soc/config/loadstore.py index e7d52ff0..104483d1 100644 --- a/src/soc/config/loadstore.py +++ b/src/soc/config/loadstore.py @@ -1,11 +1,15 @@ -"""ConfigureableLoadStoreUnit +"""ConfigureableLoadStoreUnit and ConfigMemoryPortInterface allows the type of LoadStoreUnit to be run-time selectable +this allows the same code to be used for both small unit tests +as well as larger ones and so on, without needing large amounts +of unnecessarily-duplicated code """ from soc.experiment.lsmem import TestMemLoadStoreUnit from soc.bus.test.test_minerva import TestSRAMBareLoadStoreUnit - +from soc.experiment.pi2ls import Pi2LSUI +from soc.experiment.pimem import TestMemoryPortInterface class ConfigLoadStoreUnit: def __init__(self, pspec): @@ -18,3 +22,15 @@ class ConfigLoadStoreUnit: mask_wid=pspec.mask_wid, # cache line range data_wid=pspec.reg_wid) # data bus width + +class ConfigMemoryPortInterface: + def __init__(self, pspec): + if pspec.ldst_ifacetype == 'testpi': + self.pi = TestMemoryPortInterface(addrwid=pspec.addr_wid, # adr bus + regwid=pspec.reg_wid) # data bus + return + self.lsmem = ConfigLoadStoreUnit(pspec) + self.pi = Pi2LSUI("mem", lsui=self.lsmem.lsi, + addr_wid=pspec.addr_wid, # address range + mask_wid=pspec.mask_wid, # cache line range + data_wid=pspec.reg_wid) # data bus width diff --git a/src/soc/config/test/test_loadstore.py b/src/soc/config/test/test_loadstore.py index 0cbb81fc..2e337e92 100644 --- a/src/soc/config/test/test_loadstore.py +++ b/src/soc/config/test/test_loadstore.py @@ -7,6 +7,8 @@ from soc.config.loadstore import ConfigLoadStoreUnit from collections import namedtuple from nmigen.cli import rtlil +TestMemPspec = namedtuple('TestMemPspec', ['ldst_ifacetype', + 'addr_wid', 'mask_wid', 'reg_wid']) def write_to_addr(dut, addr, value): yield dut.x_addr_i.eq(addr) @@ -76,9 +78,9 @@ def read_byte(dut, addr): def tst_lsmemtype(ifacetype): m = Module() - Pspec = namedtuple('Pspec', ['ldst_ifacetype', - 'addr_wid', 'mask_wid', 'reg_wid']) - pspec = Pspec(ldst_ifacetype=ifacetype, addr_wid=64, mask_wid=4, reg_wid=32) + pspec = TestMemPspec(ldst_ifacetype=ifacetype, addr_wid=64, + mask_wid=4, + reg_wid=32) dut = ConfigLoadStoreUnit(pspec).lsi vl = rtlil.convert(dut, ports=[]) # TODOdut.ports()) with open("test_loadstore_%s.il" % ifacetype, "w") as f: diff --git a/src/soc/experiment/pi2ls.py b/src/soc/experiment/pi2ls.py index 7e4f59c6..e51d41e7 100644 --- a/src/soc/experiment/pi2ls.py +++ b/src/soc/experiment/pi2ls.py @@ -33,15 +33,15 @@ from nmigen import Elaboratable, Module, Signal class Pi2LSUI(Elaboratable): def __init__(self, name, pi=None, lsui=None, - regwid=64, mask_wid=8, addrwid=48): - print ("pi2lsui reg mask addr", regwid, mask_wid, addrwid) + data_wid=64, mask_wid=8, addr_wid=48): + print ("pi2lsui reg mask addr", data_wid, mask_wid, addr_wid) self.addrbits = mask_wid if pi is None: piname = "%s_pi" % name - pi = PortInterface(piname, regwid=regwid, addrwid=addrwid) + pi = PortInterface(piname, regwid=data_wid, addrwid=addr_wid) self.pi = pi if lsui is None: - lsui = LoadStoreUnitInterface(addrwid, self.addrbits, regwid) + lsui = LoadStoreUnitInterface(addr_wid, self.addrbits, data_wid) self.lsui = lsui def splitaddr(self, addr): diff --git a/src/soc/experiment/test/test_pi2ls.py b/src/soc/experiment/test/test_pi2ls.py index 07674621..ed1c0a8b 100644 --- a/src/soc/experiment/test/test_pi2ls.py +++ b/src/soc/experiment/test/test_pi2ls.py @@ -4,9 +4,9 @@ from nmigen.compat.sim import run_simulation, Settle from nmutil.formaltest import FHDLTestCase from nmigen.cli import rtlil import unittest -from soc.experiment.pi2ls import Pi2LSUI -from soc.experiment.lsmem import TestMemLoadStoreUnit -from soc.experiment.pimem import TestMemoryPortInterface +from soc.config.test.test_loadstore import TestMemPspec +from soc.config.loadstore import ConfigMemoryPortInterface + def wait_busy(port, no=False): while True: @@ -97,7 +97,8 @@ def l0_cache_ld(dut, addr, datalen): def l0_cache_ldst(arg, dut): - yield + + # do two half-word stores at consecutive addresses, then two loads addr1 = 0x04 addr2 = addr1 + 0x2 data = 0xbeef @@ -110,56 +111,41 @@ def l0_cache_ldst(arg, dut): arg.assertEqual(data, result, "data %x != %x" % (result, data)) arg.assertEqual(data2, result2, "data2 %x != %x" % (result2, data2)) - # now load both + # now load both in a 32-bit load to make sure they're really consecutive data3 = data | (data2 << 16) result3 = yield from l0_cache_ld(dut, addr1, 4) arg.assertEqual(data3, result3, "data3 %x != %x" % (result3, data3)) -class TestPIMem(unittest.TestCase): +def tst_config_pi(testcls, ifacetype): + """set up a configureable memory test of type ifacetype + """ + dut = Module() + pspec = TestMemPspec(ldst_ifacetype=ifacetype, + addr_wid=48, + mask_wid=8, + reg_wid=64) + cmpi = ConfigMemoryPortInterface(pspec) + dut.submodules.pi = cmpi.pi + if hasattr(cmpi, 'lsmem'): # hmmm not happy about this + dut.submodules.lsmem = cmpi.lsmem.lsi + vl = rtlil.convert(dut, ports=[])#dut.ports()) + with open("test_pi_%s.il" % ifacetype, "w") as f: + f.write(vl) - def test_pi_mem(self): + run_simulation(dut, {"sync": l0_cache_ldst(testcls, cmpi.pi)}, + vcd_name='test_pi_%s.vcd' % ifacetype) - dut = TestMemoryPortInterface(regwid=64) - #vl = rtlil.convert(dut, ports=dut.ports()) - #with open("test_basic_l0_cache.il", "w") as f: - # f.write(vl) - run_simulation(dut, {"sync": l0_cache_ldst(self, dut)}, - vcd_name='test_pi_mem_basic.vcd') +class TestPIMem(unittest.TestCase): + + def test_pi_mem(self): + tst_config_pi(self, 'testpi') def test_pi2ls(self): - m = Module() - regwid = 64 - addrwid = 48 - m.submodules.lsmem = lsmem = TestMemLoadStoreUnit(addr_wid=addrwid, - mask_wid=8, - data_wid=regwid) - m.submodules.dut = dut = Pi2LSUI("mem", lsui=lsmem, - regwid=regwid, addrwid=addrwid) - - """ passing in lsmem to Pi2LSUI means this isn't needed - # Connect inputs - m.d.comb += [lsmem.x_addr_i.eq(dut.lsui.x_addr_i), - lsmem.x_mask_i.eq(dut.lsui.x_mask_i), - lsmem.x_ld_i.eq(dut.lsui.x_ld_i), - lsmem.x_st_i.eq(dut.lsui.x_st_i), - lsmem.x_st_data_i.eq(dut.lsui.x_st_data_i), - lsmem.x_stall_i.eq(dut.lsui.x_stall_i), - lsmem.x_valid_i.eq(dut.lsui.x_valid_i), - lsmem.m_stall_i.eq(dut.lsui.m_stall_i), - lsmem.m_valid_i.eq(dut.lsui.m_valid_i)] - - # connect outputs - m.d.comb += [dut.lsui.x_busy_o.eq(lsmem.x_busy_o), - dut.lsui.m_busy_o.eq(lsmem.m_busy_o), - dut.lsui.m_ld_data_o.eq(lsmem.m_ld_data_o), - dut.lsui.m_load_err_o.eq(lsmem.m_load_err_o), - dut.lsui.m_store_err_o.eq(lsmem.m_store_err_o), - dut.lsui.m_badaddr_o.eq(lsmem.m_badaddr_o)] - """ - run_simulation(m, {"sync": l0_cache_ldst(self, dut)}, - vcd_name='test_pi2ls.vcd') + tst_config_pi(self, 'testmem') + if __name__ == '__main__': unittest.main(exit=False) +