from nmigen_soc.wishbone.sram import SRAM
from nmigen import Memory, Signal, Module
-from soc.minerva.units.loadstore import BareLoadStoreUnit, CacheLoadStoreUnit
+from soc.minerva.units.loadstore import BareLoadStoreUnit, CachedLoadStoreUnit
class TestSRAMBareLoadStoreUnit(BareLoadStoreUnit):
allows the type of LoadStoreUnit to be run-time selectable
"""
-from soc.experiment.pimem import TestMemoryLoadStoreUnit
+from soc.experiment.lsmem import TestMemLoadStoreUnit
from soc.bus.test.test_minerva import TestSRAMBareLoadStoreUnit
-class ConfigureableLoadStoreUnit:
+class ConfigLoadStoreUnit:
def __init__(self, pspec):
- lsidict = {'testmem': TestMemoryLoadStoreUnit,
- 'test_bare_wb': TestBareLoadStoreUnit,
+ lsidict = {'testmem': TestMemLoadStoreUnit,
+ 'test_bare_wb': TestSRAMBareLoadStoreUnit,
#'test_cache_wb': TestCacheLoadStoreUnit
}
lsikls = lsidict[pspec.ldst_ifacetype]
--- /dev/null
+from soc.minerva.units.loadstore import LoadStoreUnitInterface
+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.loadstore import ConfigLoadStoreUnit
+from collections import namedtuple
+
+
+def write_to_addr(dut, addr, value):
+ yield dut.x_addr_i.eq(addr)
+ yield dut.x_st_data_i.eq(value)
+ yield dut.x_st_i.eq(1)
+ yield dut.x_mask_i.eq(-1)
+ yield dut.x_valid_i.eq(1)
+ yield dut.x_stall_i.eq(1)
+ yield
+ yield
+
+ yield dut.x_stall_i.eq(0)
+ yield
+ yield dut.x_st_i.eq(0)
+ while (yield dut.x_stall_i):
+ yield
+
+
+def read_from_addr(dut, addr):
+ yield dut.x_addr_i.eq(addr)
+ yield dut.x_ld_i.eq(1)
+ yield dut.x_valid_i.eq(1)
+ yield dut.x_stall_i.eq(1)
+ yield
+ yield dut.x_stall_i.eq(0)
+ yield
+ yield dut.x_ld_i.eq(0)
+ yield Settle()
+ while (yield dut.x_stall_i):
+ yield
+ assert (yield dut.x_valid_i)
+ return (yield dut.m_ld_data_o)
+
+
+def write_byte(dut, addr, val):
+ offset = addr & 0x3
+ yield dut.x_addr_i.eq(addr)
+ yield dut.x_st_i.eq(1)
+ yield dut.x_st_data_i.eq(val << (offset * 8))
+ yield dut.x_mask_i.eq(1 << offset)
+ yield dut.x_valid_i.eq(1)
+
+ yield
+ yield dut.x_st_i.eq(0)
+ while (yield dut.x_stall_i):
+ yield
+
+
+def read_byte(dut, addr):
+ offset = addr & 0x3
+ yield dut.x_addr_i.eq(addr)
+ yield dut.x_ld_i.eq(1)
+ yield dut.x_valid_i.eq(1)
+ yield
+ yield dut.x_ld_i.eq(0)
+ yield Settle()
+ while (yield dut.x_stall_i):
+ yield
+ assert (yield dut.x_valid_i)
+ val = (yield dut.m_ld_data_o)
+ return (val >> (offset * 8)) & 0xff
+
+
+if __name__ == '__main__':
+ m = Module()
+ Pspec = namedtuple('Pspec', ['ldst_ifacetype',
+ 'addr_wid', 'mask_wid', 'reg_wid'])
+ pspec = Pspec(ldst_ifacetype='testmem', addr_wid=64, mask_wid=3, reg_wid=64)
+ dut = ConfigLoadStoreUnit(pspec).lsi
+ m.submodules.dut = dut
+
+ sim = Simulator(m)
+ sim.add_clock(1e-6)
+
+ def process():
+
+ values = [random.randint(0, (1<<32)-1) for x in range(16)]
+
+ for addr, val in enumerate(values):
+ yield from write_to_addr(dut, addr << 2, val)
+ for addr, val in enumerate(values):
+ x = yield from read_from_addr(dut, addr << 2)
+ assert x == val
+
+ values = [random.randint(0, 255) for x in range(16*4)]
+ for addr, val in enumerate(values):
+ yield from write_byte(dut, addr, val)
+ for addr, val in enumerate(values):
+ x = yield from read_byte(dut, addr)
+ assert x == val
+
+ sim.add_sync_process(process)
+ with sim.write_vcd("test_loadstore_tm.vcd", traces=[]):
+ sim.run()
+
from nmigen import Signal, Module, Elaboratable, Mux
from nmigen.utils import log2_int
from soc.experiment.testmem import TestMemory # TODO: replace with TMLSUI
-import random
-
-from nmigen.back.pysim import Simulator, Settle
+from nmigen.cli import rtlil
class TestMemLoadStoreUnit(LoadStoreUnitInterface, Elaboratable):
- def __init__(self, regwid, addrwid, mask_wid=4):
+ def __init__(self, addr_wid=32, mask_wid=4, data_wid=32):
super().__init__()
- self.regwid = regwid
- self.addrwid = addrwid
+ self.regwid = data_wid
+ self.addrwid = addr_wid
self.mask_wid = mask_wid
def elaborate(self, platform):
m = Module()
regwid, addrwid, mask_wid = self.regwid, self.addrwid, self.mask_wid
- adr_lsb = log2_int(mask_wid)
+ adr_lsb = self.adr_lsbs
- m.submodules.mem = mem = TestMemory(regwid, addrwid, granularity=8)
+ # limit TestMemory to 2^6 entries of regwid size
+ m.submodules.mem = mem = TestMemory(regwid, 6, granularity=8)
do_load = Signal() # set when doing a load while valid and not stalled
do_store = Signal() # set when doing a store while valid and not stalled
return m
-def write_to_addr(dut, addr, value):
- yield dut.x_addr_i.eq(addr)
- yield dut.x_st_data_i.eq(value)
- yield dut.x_st_i.eq(1)
- yield dut.x_mask_i.eq(-1)
- yield dut.x_valid_i.eq(1)
- yield dut.x_stall_i.eq(1)
- yield
- yield
-
- yield dut.x_stall_i.eq(0)
- yield
- yield dut.x_st_i.eq(0)
- while (yield dut.x_stall_i):
- yield
-
-
-def read_from_addr(dut, addr):
- yield dut.x_addr_i.eq(addr)
- yield dut.x_ld_i.eq(1)
- yield dut.x_valid_i.eq(1)
- yield dut.x_stall_i.eq(1)
- yield
- yield dut.x_stall_i.eq(0)
- yield
- yield dut.x_ld_i.eq(0)
- yield Settle()
- while (yield dut.x_stall_i):
- yield
- assert (yield dut.x_valid_i)
- return (yield dut.m_ld_data_o)
-
-
-def write_byte(dut, addr, val):
- offset = addr & 0x3
- yield dut.x_addr_i.eq(addr)
- yield dut.x_st_i.eq(1)
- yield dut.x_st_data_i.eq(val << (offset * 8))
- yield dut.x_mask_i.eq(1 << offset)
- yield dut.x_valid_i.eq(1)
-
- yield
- yield dut.x_st_i.eq(0)
- while (yield dut.x_stall_i):
- yield
-
-
-def read_byte(dut, addr):
- offset = addr & 0x3
- yield dut.x_addr_i.eq(addr)
- yield dut.x_ld_i.eq(1)
- yield dut.x_valid_i.eq(1)
- yield
- yield dut.x_ld_i.eq(0)
- yield Settle()
- while (yield dut.x_stall_i):
- yield
- assert (yield dut.x_valid_i)
- val = (yield dut.m_ld_data_o)
- return (val >> (offset * 8)) & 0xff
-
-
if __name__ == '__main__':
- m = Module()
dut = TestMemLoadStoreUnit(regwid=32, addrwid=4)
- m.submodules.dut = dut
-
- sim = Simulator(m)
- sim.add_clock(1e-6)
-
- def process():
-
- values = [random.randint(0, (1<<32)-1) for x in range(16)]
-
- for addr, val in enumerate(values):
- yield from write_to_addr(dut, addr << 2, val)
- for addr, val in enumerate(values):
- x = yield from read_from_addr(dut, addr << 2)
- assert x == val
-
- values = [random.randint(0, 255) for x in range(16*4)]
- for addr, val in enumerate(values):
- yield from write_byte(dut, addr, val)
- for addr, val in enumerate(values):
- x = yield from read_byte(dut, addr)
- assert x == val
+ vl = rtlil.convert(dut, ports=[]) # TODOdut.ports())
+ with open("test_lsmem.il", "w") as f:
+ f.write(vl)
- sim.add_sync_process(process)
- with sim.write_vcd("lsmem.vcd", "lsmem.gtkw", traces=[]):
- sim.run()
from nmigen.lib.fifo import SyncFIFO
from soc.minerva.cache import L1Cache
-from soc.minerva.wishbone import wishbone_layout, WishboneArbiter, Cycle
+from soc.minerva.wishbone import make_wb_layout, WishboneArbiter, Cycle
__all__ = ["LoadStoreUnitInterface", "BareLoadStoreUnit",
class LoadStoreUnitInterface:
def __init__(self, addr_wid=32, mask_wid=4, data_wid=32):
- self.dbus = Record(mk_wb_layout(addr_wid, mask_wid, data_wid))
+ self.dbus = Record(make_wb_layout(addr_wid, mask_wid, data_wid))
self.mask_wid = mask_wid
self.addr_wid = addr_wid
self.data_wid = data_wid
- self.adr_lsbs = log2_int_mask_wid) # LSBs of addr covered by mask
- badwid = addr_wid-log2_int(self.adr_lsbs) # TODO: is this correct?
+ self.adr_lsbs = log2_int(mask_wid) # LSBs of addr covered by mask
+ badwid = addr_wid-self.adr_lsbs # TODO: is this correct?
# INPUTS
self.x_addr_i = Signal(addr_wid) # address used for loads/stores
def make_wb_layout(addr_wid, mask_wid, data_wid):
- adr_lsbs = log2_int_mask_wid) # LSBs of addr covered by mask
- badwid = addr_wid-log2_int(adr_lsbs) # MSBs (not covered by mask)
+ adr_lsbs = log2_int(mask_wid) # LSBs of addr covered by mask
+ badwid = addr_wid-adr_lsbs # MSBs (not covered by mask)
return [
("adr", badwid , DIR_FANOUT),