From: Luke Kenneth Casson Leighton Date: Sun, 28 Jun 2020 19:37:07 +0000 (+0100) Subject: add Config Fetch interface and quick unit test X-Git-Tag: div_pipeline~215 X-Git-Url: https://git.libre-soc.org/?p=soc.git;a=commitdiff_plain;h=6d7bbdbe65d72b9c067129951489472e1e9f8b90 add Config Fetch interface and quick unit test --- diff --git a/src/soc/config/ifetch.py b/src/soc/config/ifetch.py new file mode 100644 index 00000000..0aea4565 --- /dev/null +++ b/src/soc/config/ifetch.py @@ -0,0 +1,22 @@ +"""ConfigureableFetchUnit and ConfigMemoryPortInterface + +allows the type of FetchUnit 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.imem import TestMemFetchUnit +#from soc.bus.test.test_minerva import TestSRAMBareFetchUnit + + +class ConfigFetchUnit: + def __init__(self, pspec): + fudict = {'testmem': TestMemFetchUnit, + #'test_bare_wb': TestSRAMBareFetchUnit, + #'test_cache_wb': TestCacheFetchUnit + } + fukls = fudict[pspec.imem_ifacetype] + self.fu = fukls(addr_wid=pspec.addr_wid, # address range + data_wid=pspec.reg_wid) # data bus width + diff --git a/src/soc/config/test/test_fetch.py b/src/soc/config/test/test_fetch.py new file mode 100644 index 00000000..e772eb8c --- /dev/null +++ b/src/soc/config/test/test_fetch.py @@ -0,0 +1,62 @@ +from soc.minerva.units.fetch import FetchUnitInterface +from nmigen import Signal, Module, Elaboratable, Mux +from nmigen.utils import log2_int +import random +from nmigen.back.pysim import Simulator, Settle +from soc.config.ifetch import ConfigFetchUnit +from collections import namedtuple +from nmigen.cli import rtlil + +from soc.config.test.test_loadstore import TestMemPspec + + +def read_from_addr(dut, addr): + yield dut.a_pc_i.eq(addr) + yield dut.a_valid_i.eq(1) + yield dut.a_stall_i.eq(1) + yield + yield dut.a_stall_i.eq(0) + yield + yield Settle() + while (yield dut.f_busy_o): + yield + assert (yield dut.a_valid_i) + return (yield dut.f_instr_o) + + +def tst_lsmemtype(ifacetype): + m = Module() + pspec = TestMemPspec(ldst_ifacetype=ifacetype, + imem_ifacetype=ifacetype, addr_wid=64, + mask_wid=4, + reg_wid=32) + dut = ConfigFetchUnit(pspec).fu + vl = rtlil.convert(dut, ports=[]) # TODOdut.ports()) + with open("test_fetch_%s.il" % ifacetype, "w") as f: + f.write(vl) + + m.submodules.dut = dut + + sim = Simulator(m) + sim.add_clock(1e-6) + + mem = dut.mem.mem + + def process(): + + values = [random.randint(0, (1<<32)-1) for x in range(16)] + for addr, val in enumerate(values): + yield mem._array[addr].eq(val) + + for addr, val in enumerate(values): + x = yield from read_from_addr(dut, addr << 2) + print ("addr, val", addr, hex(val), hex(x)) + assert x == val + + sim.add_sync_process(process) + with sim.write_vcd("test_fetch_%s.vcd" % ifacetype, traces=[]): + sim.run() + +if __name__ == '__main__': + #tst_lsmemtype('test_bare_wb') + tst_lsmemtype('testmem') diff --git a/src/soc/config/test/test_loadstore.py b/src/soc/config/test/test_loadstore.py index 2e337e92..d70c3807 100644 --- a/src/soc/config/test/test_loadstore.py +++ b/src/soc/config/test/test_loadstore.py @@ -8,6 +8,7 @@ from collections import namedtuple from nmigen.cli import rtlil TestMemPspec = namedtuple('TestMemPspec', ['ldst_ifacetype', + 'imem_ifacetype', 'addr_wid', 'mask_wid', 'reg_wid']) def write_to_addr(dut, addr, value): diff --git a/src/soc/experiment/imem.py b/src/soc/experiment/imem.py index 1662c48f..5f0f622c 100644 --- a/src/soc/experiment/imem.py +++ b/src/soc/experiment/imem.py @@ -6,13 +6,17 @@ from nmigen.cli import rtlil class TestMemFetchUnit(FetchUnitInterface, Elaboratable): + def __init__(self, addr_wid=32, data_wid=32): + super().__init__(addr_wid=addr_wid, data_wid=data_wid) + # limit TestMemory to 2^6 entries of regwid size + self.mem = TestMemory(self.data_wid, 6, readonly=True) + def elaborate(self, platform): m = Module() regwid, addrwid = self.data_wid, self.addr_wid adr_lsb = self.adr_lsbs - # limit TestMemory to 2^6 entries of regwid size - m.submodules.mem = mem = TestMemory(regwid, 6, readonly=True) + m.submodules.mem = mem = self.mem do_fetch = Signal() # set when fetch while valid and not stalled m.d.comb += do_fetch.eq(self.a_valid_i & ~self.a_stall_i)