--- /dev/null
+"""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
+
--- /dev/null
+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')
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)