from copy import deepcopy
from random import randint, seed
+from nmigen_soc.wishbone.bus import Interface
+
from nmigen.cli import main
from nmutil.iocontrol import RecordObject
from nmigen.utils import log2_int
self.stall_out = Signal()
- self.wb_out = WBMasterOut("wb_out")
- self.wb_in = WBSlaveOut("wb_in")
+ # standard naming (wired to non-standard for compatibility)
+ self.bus = Interface(addr_width=32,
+ data_width=64,
+ granularity=8,
+ features={'stall'},
+ alignment=0,
+ name="dcache")
self.log_out = Signal(20)
account by using 1-cycle delayed signals for load hits.
"""
comb = m.d.comb
- wb_in = self.wb_in
+ bus = self.bus
for i in range(NUM_WAYS):
do_read = Signal(name="do_rd%d" % i)
with m.If(r1.dcbz):
comb += wr_data.eq(0)
with m.Else():
- comb += wr_data.eq(wb_in.dat)
+ comb += wr_data.eq(bus.dat_r)
comb += wr_addr.eq(r1.store_row)
comb += wr_sel.eq(~0) # all 1s
with m.If((r1.state == State.RELOAD_WAIT_ACK)
- & wb_in.ack & (replace_way == i)):
+ & bus.ack & (replace_way == i)):
comb += do_write.eq(1)
# Mask write selects with do_write since BRAM
comb = m.d.comb
sync = m.d.sync
- wb_in = self.wb_in
+ bus = self.bus
d_in = self.d_in
req = MemAccessRequest("mreq_ds")
with m.If(r1.dcbz):
sync += r1.forward_data1.eq(0)
with m.Else():
- sync += r1.forward_data1.eq(wb_in.dat)
+ sync += r1.forward_data1.eq(bus.dat_r)
sync += r1.forward_sel1.eq(~0) # all 1s
sync += r1.forward_way1.eq(replace_way)
sync += r1.forward_row1.eq(r1.store_row)
comb += ld_stbs_done.eq(~r1.wb.stb)
# If we are still sending requests, was one accepted?
- with m.If((~wb_in.stall) & r1.wb.stb):
+ with m.If((~bus.stall) & r1.wb.stb):
# That was the last word? We are done sending.
# Clear stb and set ld_stbs_done so we can handle an
# eventual last ack on the same cycle.
sync += r1.wb.adr[:LINE_OFF_BITS-ROW_OFF_BITS].eq(row+1)
# Incoming acks processing
- sync += r1.forward_valid1.eq(wb_in.ack)
- with m.If(wb_in.ack):
+ sync += r1.forward_valid1.eq(bus.ack)
+ with m.If(bus.ack):
srow = Signal(ROW_LINE_BITS)
comb += srow.eq(r1.store_row)
sync += r1.rows_valid[srow].eq(1)
sync += r1.acks_pending.eq(adjust_acks)
# Clear stb when slave accepted request
- with m.If(~wb_in.stall):
+ with m.If(~bus.stall):
# See if there is another store waiting
# to be done which is in the same real page.
with m.If(req.valid):
comb += st_stbs_done.eq(1)
# Got ack ? See if complete.
- with m.If(wb_in.ack):
+ with m.If(bus.ack):
with m.If(st_stbs_done & (adjust_acks == 1)):
sync += r1.state.eq(State.IDLE)
sync += r1.wb.cyc.eq(0)
with m.Case(State.NC_LOAD_WAIT_ACK):
# Clear stb when slave accepted request
- with m.If(~wb_in.stall):
+ with m.If(~bus.stall):
sync += r1.wb.stb.eq(0)
# Got ack ? complete.
- with m.If(wb_in.ack):
+ with m.If(bus.ack):
sync += r1.state.eq(State.IDLE)
sync += r1.full.eq(0)
sync += r1.slow_valid.eq(1)
def dcache_log(self, m, r1, valid_ra, tlb_hit_way, stall_out):
sync = m.d.sync
- d_out, wb_in, log_out = self.d_out, self.wb_in, self.log_out
+ d_out, bus, log_out = self.d_out, self.bus, self.log_out
sync += log_out.eq(Cat(r1.state[:3], valid_ra, tlb_hit_way[:3],
stall_out, req_op[:3], d_out.valid, d_out.error,
- r1.wb.cyc, r1.wb.stb, wb_in.ack, wb_in.stall,
+ r1.wb.cyc, r1.wb.stb, bus.ack, bus.stall,
r1.real_adr[3:6]))
def elaborate(self, platform):
comb += r0_valid.eq(r0_full & ~r1.full & ~d_in.hold)
comb += self.stall_out.eq(r0_stall)
- # Wire up wishbone request latch out of stage 1
- comb += self.wb_out.eq(r1.wb)
# deal with litex not doing wishbone pipeline mode
# XXX in wrong way. FIFOs are needed in the SRAM test
# so that stb/ack match up
- comb += self.wb_in.stall.eq(self.wb_out.cyc & ~self.wb_in.ack)
+ comb += self.bus.stall.eq(self.bus.cyc & ~self.bus.ack)
+
+ # Wire up wishbone request latch out of stage 1
+ comb += self.bus.we.eq(r1.wb.we)
+ comb += self.bus.adr.eq(r1.wb.adr)
+ comb += self.bus.sel.eq(r1.wb.sel)
+ comb += self.bus.stb.eq(r1.wb.stb)
+ comb += self.bus.dat_w.eq(r1.wb.dat)
+ comb += self.bus.cyc.eq(r1.wb.cyc)
# call sub-functions putting everything together, using shared
# signals established above
m.submodules.dcache = dut
m.submodules.sram = sram
- m.d.comb += sram.bus.cyc.eq(dut.wb_out.cyc)
- m.d.comb += sram.bus.stb.eq(dut.wb_out.stb)
- m.d.comb += sram.bus.we.eq(dut.wb_out.we)
- m.d.comb += sram.bus.sel.eq(dut.wb_out.sel)
- m.d.comb += sram.bus.adr.eq(dut.wb_out.adr)
- m.d.comb += sram.bus.dat_w.eq(dut.wb_out.dat)
+ m.d.comb += sram.bus.cyc.eq(dut.bus.cyc)
+ m.d.comb += sram.bus.stb.eq(dut.bus.stb)
+ m.d.comb += sram.bus.we.eq(dut.bus.we)
+ m.d.comb += sram.bus.sel.eq(dut.bus.sel)
+ m.d.comb += sram.bus.adr.eq(dut.bus.adr)
+ m.d.comb += sram.bus.dat_w.eq(dut.bus.dat_w)
- m.d.comb += dut.wb_in.ack.eq(sram.bus.ack)
- m.d.comb += dut.wb_in.dat.eq(sram.bus.dat_r)
+ m.d.comb += dut.bus.ack.eq(sram.bus.ack)
+ m.d.comb += dut.bus.dat_r.eq(sram.bus.dat_r)
dcache_write_gtkw(test_name)
('d_out', [
'd_out_valid', 'd_out_data[63:0]'
]),
+ # XXX TODO, update to standard wishbone Signals (single "bus" Interface)
('wb_out', [
'wb_out_cyc', 'wb_out_stb', 'wb_out_we',
'wb_out_adr[31:0]', 'wb_out_sel[7:0]', 'wb_out_dat[63:0]'
m.submodules.dcache = dut
m.submodules.sram = sram
- m.d.comb += sram.bus.cyc.eq(dut.wb_out.cyc)
- m.d.comb += sram.bus.stb.eq(dut.wb_out.stb)
- m.d.comb += sram.bus.we.eq(dut.wb_out.we)
- m.d.comb += sram.bus.sel.eq(dut.wb_out.sel)
- m.d.comb += sram.bus.adr.eq(dut.wb_out.adr)
- m.d.comb += sram.bus.dat_w.eq(dut.wb_out.dat)
-
- m.d.comb += dut.wb_in.ack.eq(sram.bus.ack)
- m.d.comb += dut.wb_in.dat.eq(sram.bus.dat_r)
+ m.d.comb += sram.bus.cyc.eq(dut.bus.cyc)
+ m.d.comb += sram.bus.stb.eq(dut.bus.stb)
+ m.d.comb += sram.bus.we.eq(dut.bus.we)
+ m.d.comb += sram.bus.sel.eq(dut.bus.sel)
+ m.d.comb += sram.bus.adr.eq(dut.bus.adr)
+ m.d.comb += sram.bus.dat_w.eq(dut.bus.dat_w)
+
+ m.d.comb += dut.bus.ack.eq(sram.bus.ack)
+ m.d.comb += dut.bus.dat_r.eq(sram.bus.dat_r)
dcache_write_gtkw(test_name)
l_in, l_out = mmu.l_in, mmu.l_out
d_in, d_out = dcache.d_in, dcache.d_out
- wb_out, wb_in = dcache.wb_out, dcache.wb_in
# link mmu and dcache together
m.d.comb += dcache.m_in.eq(mmu.d_out) # MMUToDCacheType
l_in, l_out = mmu.l_in, mmu.l_out
d_in, d_out = dcache.d_in, dcache.d_out
- wb_out, wb_in = dcache.wb_out, dcache.wb_in
# link mmu and dcache together
m.d.comb += dcache.m_in.eq(mmu.d_out) # MMUToDCacheType
l_in, l_out = mmu.l_in, mmu.l_out
d_in, d_out = dcache.d_in, dcache.d_out
- wb_out, wb_in = dcache.wb_out, dcache.wb_in
# link mmu and dcache together
m.d.comb += dcache.m_in.eq(mmu.d_out) # MMUToDCacheType
l_in, l_out = mmu.l_in, mmu.l_out
d_in, d_out = dcache.d_in, dcache.d_out
- wb_out, wb_in = dcache.wb_out, dcache.wb_in
# link mmu and dcache together
m.d.comb += dcache.m_in.eq(mmu.d_out) # MMUToDCacheType
if stop:
log("stop")
return
- cyc = yield (c.wb_out.cyc)
- stb = yield (c.wb_out.stb)
+ cyc = yield (c.bus.cyc)
+ stb = yield (c.bus.stb)
if cyc and stb:
break
yield
- addr = (yield c.wb_out.adr) << 3
+ addr = (yield c.bus.adr) << 3
if addr not in mem:
log("%s LOOKUP FAIL %x (return zero)" % (name, addr))
yield
data = mem.get(addr, 0)
- yield c.wb_in.dat.eq(data)
+ yield c.bus.dat_r.eq(data)
log("%s get %x data %x" % (name, addr, data))
- yield c.wb_in.ack.eq(1)
+ yield c.bus.ack.eq(1)
yield
- yield c.wb_in.ack.eq(0)
+ yield c.bus.ack.eq(0)
yield
while True: # wait for dc_valid
if stop:
return
- cyc = yield (dc.wb_out.cyc)
- stb = yield (dc.wb_out.stb)
+ cyc = yield (dc.bus.cyc)
+ stb = yield (dc.bus.stb)
if cyc and stb:
break
yield
- addr = (yield dc.wb_out.adr) << 3
+ addr = (yield dc.bus.adr) << 3
if addr not in mem:
print (" WB LOOKUP NO entry @ %x, returning zero" % (addr))
data = mem.get(addr, 0)
- yield dc.wb_in.dat.eq(data)
+ yield dc.bus.dat_r.eq(data)
print (" DCACHE get %x data %x" % (addr, data))
- yield dc.wb_in.ack.eq(1)
+ yield dc.bus.ack.eq(1)
yield
- yield dc.wb_in.ack.eq(0)
+ yield dc.bus.ack.eq(0)
yield
comb += exc.segment_fault.eq(m_in.segerr)
# TODO, connect dcache wb_in/wb_out to "standard" nmigen Wishbone bus
- comb += dbus.adr.eq(dcache.wb_out.adr)
- comb += dbus.dat_w.eq(dcache.wb_out.dat)
- comb += dbus.sel.eq(dcache.wb_out.sel)
- comb += dbus.cyc.eq(dcache.wb_out.cyc)
- comb += dbus.stb.eq(dcache.wb_out.stb)
- comb += dbus.we.eq(dcache.wb_out.we)
-
- comb += dcache.wb_in.dat.eq(dbus.dat_r)
- comb += dcache.wb_in.ack.eq(dbus.ack)
+ comb += dbus.adr.eq(dcache.bus.adr)
+ comb += dbus.dat_w.eq(dcache.bus.dat_w)
+ comb += dbus.sel.eq(dcache.bus.sel)
+ comb += dbus.cyc.eq(dcache.bus.cyc)
+ comb += dbus.stb.eq(dcache.bus.stb)
+ comb += dbus.we.eq(dcache.bus.we)
+
+ comb += dcache.bus.dat_r.eq(dbus.dat_r)
+ comb += dcache.bus.ack.eq(dbus.ack)
if hasattr(dbus, "stall"):
- comb += dcache.wb_in.stall.eq(dbus.stall)
+ comb += dcache.bus.stall.eq(dbus.stall)
# update out d data when flag set
with m.If(self.d_w_valid):
l_in, l_out = mmu.l_in, mmu.l_out
d_in, d_out = dcache.d_in, dcache.d_out
- wb_out, wb_in = dcache.wb_out, dcache.wb_in
# link ldst and MMU together
comb += l_in.eq(ldst.m_out)