from nmigen.utils import log2_int
from nmigen import Elaboratable, Module, Signal
+from nmutil.latch import SRLatch
class Pi2LSUI(PortInterfaceBase):
if lsui is None:
lsui = LoadStoreUnitInterface(addr_wid, self.addrbits, data_wid)
self.lsui = lsui
+ self.valid_l = SRLatch(False, name="valid")
def set_wr_addr(self, m, addr, mask):
+ m.d.comb += self.valid_l.s.eq(1)
m.d.comb += self.lsui.x_mask_i.eq(mask)
m.d.comb += self.lsui.x_addr_i.eq(addr)
- m.d.comb += self.lsui.x_valid_i.eq(1)
def set_rd_addr(self, m, addr, mask):
+ m.d.comb += self.valid_l.s.eq(1)
m.d.comb += self.lsui.x_mask_i.eq(mask)
m.d.comb += self.lsui.x_addr_i.eq(addr)
- m.d.comb += self.lsui.x_valid_i.eq(1)
def set_wr_data(self, m, data, wen): # mask already done in addr setup
m.d.comb += self.lsui.x_st_data_i.eq(data)
m = super().elaborate(platform)
pi, lsui, addrbits = self.pi, self.lsui, self.addrbits
+ m.submodules.valid_l = self.valid_l
+ ld_in_progress = Signal()
+
+ # pass ld/st through to LSUI
m.d.comb += lsui.x_ld_i.eq(pi.is_ld_i)
m.d.comb += lsui.x_st_i.eq(pi.is_st_i)
+ # indicate valid at both ends
+ m.d.comb += self.lsui.m_valid_i.eq(self.valid_l.q)
+ m.d.comb += self.lsui.x_valid_i.eq(self.valid_l.q)
+
+ # reset the valid latch when not busy
+ m.d.comb += self.valid_l.r.eq(~pi.busy_o)#self.lsui.x_busy_o)
+
return m
# is a "Memory" test-class) the memory read data is valid.
comb += reset_l.s.eq(0)
comb += reset_l.r.eq(0)
+ lddata = Signal(self.regwid, reset_less=True)
+ data, ldok = self.get_rd_data(m)
+ comb += lddata.eq((data & lenexp.rexp_o) >>
+ (lenexp.addr_i*8))
with m.If(ld_active.q & adrok_l.q):
# shift data down before pushing out. requires masking
# from the *byte*-expanded version of LenExpand output
- lddata = Signal(self.regwid, reset_less=True)
- data, ldok = self.get_rd_data(m)
- comb += lddata.eq((data & lenexp.rexp_o) >>
- (lenexp.addr_i*8))
comb += pi.ld.data.eq(lddata) # put data out
comb += pi.ld.ok.eq(ldok) # indicate data valid
comb += reset_l.s.eq(ldok) # reset mode after 1 cycle
print (" %6i %016x" % (i, actual_mem))
-def check_sim_memory(dut, l0, sim, code):
+def dump_sim_memory(dut, l0, sim, code):
mem = get_l0_mem(l0)
print ("sim mem dump")
for k, v in sim.mem.mem.items():
actual_mem = yield mem._array[i]
print (" %6i %016x" % (i, actual_mem))
+
+def check_sim_memory(dut, l0, sim, code):
+ mem = get_l0_mem(l0)
+
for i in range(mem.depth):
expected_mem = sim.mem.ld(i*8, 8, False)
actual_mem = yield mem._array[i]
from soc.experiment.l0_cache import TstL0CacheBuffer
m.submodules.l0 = l0 = TstL0CacheBuffer(n_units=1, regwid=64,
addrwid=3,
- ifacetype='testpi')
+ ifacetype='test_bare_wb')
pi = l0.l0.dports[0]
m.submodules.cu = cu = self.fukls(pi, awid=3)
m.d.comb += cu.ad.go.eq(cu.ad.rel) # link addr-go direct to rel
break
yield
+ if self.funit == Function.LDST:
+ yield from dump_sim_memory(self, l0, sim, code)
+
yield from self.iodef.check_cu_outputs(res, pdecode2,
sim, code)