from nmigen.cli import rtlil
from soc.minerva.wishbone import make_wb_layout
from nmutil.util import wrap
+from soc.bus.test.wb_rw import wb_read, wb_write
+
cxxsim = False
if cxxsim:
# hardwire the hardware IRQ priority
HW_PRIORITY = Const(0x80, 8)
-# 8 bit offsets for each presentation
-XIRR_POLL = 0x00
-XIRR = 0x04
-RESV0 = 0x08
-MFRR = 0x0c
+# 8 bit offsets for each presentation - all addresses are in "words"
+XIRR_POLL = 0x00 # 0x000
+XIRR = 0x01 # 0x004
+RESV0 = 0x02 # 0x008
+MFRR = 0x03 # 0x00c
class RegInternal(RecordObject):
spec.addr_wid = 30
spec.mask_wid = 4
spec.reg_wid = 32
- self.bus = Record(make_wb_layout(spec), name="icp_wb")
+ self.bus = Record(make_wb_layout(spec, cti=False), name="icp_wb")
self.ics_i = ICS2ICP("ics_i")
self.core_irq_o = Signal()
# We delay core_irq_out by a cycle to help with timing
sync += self.core_irq_o.eq(r.irq)
- comb += self.bus.dat_r.eq(r.wb_rd_data)
- comb += self.bus.ack.eq(r.wb_ack)
+ comb += self.bus.ack.eq(r.wb_ack & self.bus.cyc)
+ with m.If(self.bus.ack):
+ comb += self.bus.dat_r.eq(r.wb_rd_data)
v = RegInternal()
xirr_accept_rd = Signal()
be_out = Signal(32)
pending_priority = Signal(8)
+ min_pri = Signal(8)
comb += v.eq(r) # start from the register (r)
comb += v.wb_ack.eq(0)
comb += v.wb_ack.eq(1) # always ack
with m.If(self.bus.we): # write
# writes to both XIRR are the same
- with m.Switch( self.bus.adr[:8]):
+ with m.Switch(self.bus.adr[:6]):
with m.Case(XIRR_POLL):
# report "ICP XIRR_POLL write";
comb += v.cppr.eq(be_in[24:32])
#report "ICP XIRR UNSUPPORTED write ! sel=" & \
# to_hstring(self.bus.sel);
pass
- with m.Case(MFRR ):
+ with m.Case(MFRR):
comb += v.mfrr.eq(be_in[24:32])
with m.If(self.bus.sel == 0xf): # # 4 byte
# report "ICP MFRR write word:" & to_hstring(be_in);
with m.Else(): # read
- with m.Switch(self.bus.adr[:8]):
+ with m.Switch(self.bus.adr[:6]):
with m.Case(XIRR_POLL):
# report "ICP XIRR_POLL read";
- comb += be_out.eq(r.xisr & r.cppr)
+ comb += be_out.eq(Cat(r.xisr, r.cppr))
with m.Case(XIRR):
# report "ICP XIRR read";
comb += be_out.eq(Cat(r.xisr, r.cppr))
comb += xirr_accept_rd.eq(1)
with m.Case(MFRR):
# report "ICP MFRR read";
- comb += be_out.eq(r.mfrr)
+ comb += be_out[24:32].eq(r.mfrr)
comb += pending_priority.eq(0xff)
comb += v.xisr.eq(0x0)
# Check MFRR
with m.If(r.mfrr < pending_priority):
- comb += v.xisr.eq(Const(0x2)) # special XICS MFRR IRQ source number
- comb += pending_priority.eq(r.mfrr)
+ comb += v.xisr.eq(Const(0x2, 24)) # special XICS MFRR IRQ src num
+ comb += min_pri.eq(r.mfrr)
+ with m.Else():
+ comb += min_pri.eq(pending_priority)
# Accept the interrupt
with m.If(xirr_accept_rd):
# " cppr:" & to_hstring(r.cppr) &
# " xisr:" & to_hstring(r.xisr) &
# " mfrr:" & to_hstring(r.mfrr);
- comb += v.cppr.eq(pending_priority)
+ comb += v.cppr.eq(min_pri)
comb += v.wb_rd_data.eq(bswap(be_out))
# check if the core needs an interrupt notification (or clearing)
- comb += v.irq.eq(pending_priority < v.cppr)
- with m.If(v.irq):
+ with m.If(min_pri < v.cppr):
with m.If(~r.irq):
#report "IRQ set";
pass
+ comb += v.irq.eq(1)
with m.Elif(r.irq):
#report "IRQ clr";
pass
spec.addr_wid = 30
spec.mask_wid = 4
spec.reg_wid = 32
- self.bus = Record(make_wb_layout(spec), name="ics_wb")
+ self.bus = Record(make_wb_layout(spec, cti=False), name="ics_wb")
self.int_level_i = Signal(SRC_NUM)
self.icp_o = ICS2ICP("icp_o")
assert self.SRC_NUM == 16, "Fixup address decode with log2"
- comb += reg_is_xive.eq(self.bus.adr[11])
- comb += reg_is_config.eq(self.bus.adr[0:12] == 0x0)
- comb += reg_is_debug.eq(self.bus.adr[0:12] == 0x4)
+ comb += reg_is_xive.eq(self.bus.adr[9])
+ comb += reg_is_config.eq(self.bus.adr[0:10] == 0x0)
+ comb += reg_is_debug.eq(self.bus.adr[0:10] == 0x4)
# Register index XX FIXME: figure out bits from SRC_NUM
- comb += reg_idx.eq(self.bus.adr[2:6])
+ comb += reg_idx.eq(self.bus.adr[:4])
# Latch interrupt inputs for timing
sync += int_level_l.eq(self.int_level_i)
return list(self)
-def wb_write(dut, addr, data, sel=True):
-
- # read wb
- yield dut.bus.we.eq(1)
- yield dut.bus.cyc.eq(1)
- yield dut.bus.stb.eq(1)
- yield dut.bus.sel.eq(0b1111 if sel else 0b1) # 32-bit / 8-bit
- yield dut.bus.adr.eq(addr)
- yield dut.bus.dat_w.eq(data)
-
- # wait for ack to go high
- while True:
- ack = yield dut.bus.ack
- print ("ack", ack)
- if ack:
- break
- yield # loop until ack
- yield dut.bus.stb.eq(0) # drop stb so only 1 thing into pipeline
-
- # leave cyc/stb valid for 1 cycle while writing
- yield
-
- # clear out before returning data
- yield dut.bus.cyc.eq(0)
- yield dut.bus.stb.eq(0)
- yield dut.bus.we.eq(0)
- yield dut.bus.adr.eq(0)
- yield dut.bus.sel.eq(0)
- yield dut.bus.dat_w.eq(0)
-
-
-def wb_read(dut, addr, sel=True):
-
- # read wb
- yield dut.bus.cyc.eq(1)
- yield dut.bus.stb.eq(1)
- yield dut.bus.we.eq(0)
- yield dut.bus.sel.eq(0b1111 if sel else 0b1) # 32-bit / 8-bit
- yield dut.bus.adr.eq(addr)
-
- # wait for ack to go high
- while True:
- ack = yield dut.bus.ack
- print ("ack", ack)
- if ack:
- break
- yield # loop until ack
- yield dut.bus.stb.eq(0) # drop stb so only 1 thing into pipeline
-
- # get data on same cycle that ack raises
- data = yield dut.bus.dat_r
-
- # leave cyc/stb valid for 1 cycle while reading
- yield
-
- # clear out before returning data
- yield dut.bus.cyc.eq(0)
- yield dut.bus.stb.eq(0)
- yield dut.bus.we.eq(0)
- yield dut.bus.adr.eq(0)
- yield dut.bus.sel.eq(0)
- return data
-
def sim_xics_icp(dut):
# read wb XIRR_MFRR
- data = yield from wb_read(dut, MFRR)
+ data = yield from wb_read(dut.bus, MFRR)
print ("mfrr", hex(data), bin(data))
assert (yield dut.core_irq_o) == 0
yield
# read wb XIRR (8-bit)
- data = yield from wb_read(dut, XIRR, False)
+ data = yield from wb_read(dut.bus, XIRR, False)
print ("xirr", hex(data), bin(data))
assert (yield dut.core_irq_o) == 0
yield
# read wb XIRR (32-bit)
- data = yield from wb_read(dut, XIRR)
+ data = yield from wb_read(dut.bus, XIRR)
print ("xirr", hex(data), bin(data))
assert (yield dut.core_irq_o) == 0
yield
# read wb XIRR_POLL
- data = yield from wb_read(dut, XIRR_POLL)
+ data = yield from wb_read(dut.bus, XIRR_POLL)
print ("xirr poll", hex(data), bin(data))
assert (yield dut.core_irq_o) == 0
yield dut.ics_i.pri.eq(0x1e)
# read wb XIRR_MFRR
- data = yield from wb_read(dut, MFRR)
+ data = yield from wb_read(dut.bus, MFRR)
print ("mfrr", hex(data), bin(data))
assert (yield dut.core_irq_o) == 0
yield
# read wb XIRR (8-bit)
- data = yield from wb_read(dut, XIRR, False)
+ data = yield from wb_read(dut.bus, XIRR, False)
print ("xirr", hex(data), bin(data))
assert (yield dut.core_irq_o) == 0
yield
# read wb XIRR (32-bit)
- data = yield from wb_read(dut, XIRR)
+ data = yield from wb_read(dut.bus, XIRR)
print ("xirr", hex(data), bin(data))
assert (yield dut.core_irq_o) == 0
yield
# read wb XIRR_POLL
- data = yield from wb_read(dut, XIRR_POLL)
+ data = yield from wb_read(dut.bus, XIRR_POLL)
print ("xirr poll", hex(data), bin(data))
assert (yield dut.core_irq_o) == 0
######################
# write XIRR
data = 0xfe
- yield from wb_write(dut, XIRR, data)
+ yield from wb_write(dut.bus, XIRR, data)
print ("xirr written", hex(data), bin(data))
assert (yield dut.core_irq_o) == 1 # ok *now* it should be set
# read wb XIRR_POLL
- data = yield from wb_read(dut, XIRR_POLL, False)
+ data = yield from wb_read(dut.bus, XIRR_POLL, False)
print ("xirr poll", hex(data), bin(data))
assert (yield dut.core_irq_o) == 1 # should not clear
# read wb XIRR (8-bit)
- data = yield from wb_read(dut, XIRR, False)
+ data = yield from wb_read(dut.bus, XIRR, False)
print ("xirr", hex(data), bin(data))
assert (yield dut.core_irq_o) == 1 # should not clear
# read wb XIRR (32-bit)
- data = yield from wb_read(dut, XIRR)
+ data = yield from wb_read(dut.bus, XIRR)
print ("xirr", hex(data), bin(data))
yield
assert (yield dut.core_irq_o) == 0
def sim_xics(icp, ics):
# read config
- data = yield from wb_read(ics, 0)
+ data = yield from wb_read(ics.bus, 0)
print ("config", hex(data), bin(data))
data = swap32(data)
base = get_field(data, 24, 0)
yield
# read XIVE0
- data = yield from wb_read(ics, 0x800)
+ data = yield from wb_read(ics.bus, 0x800//4)
print ("xive0", hex(data), bin(data))
data = swap32(data)
irq = get_field(data, 1, 31)
yield # wait for interrupt to propagate through from ics to icp...
# read XIVE1
- data = yield from wb_read(ics, 0x804)
+ data = yield from wb_read(ics.bus, 0x804//4)
print ("xive1", hex(data), bin(data))
data = swap32(data)
irq = get_field(data, 1, 31)
# set XIVE1 priority to 0xf0
data = swap32(0xf0)
- yield from wb_write(ics, 0x804, data)
+ yield from wb_write(ics.bus, 0x804//4, data)
print ("XIVE1 priority written", hex(data), bin(data))
######################
# write XIRR
data = 0xfe
- yield from wb_write(icp, XIRR, data)
+ yield from wb_write(icp.bus, XIRR, data)
print ("xirr written", hex(data), bin(data))
assert (yield icp.core_irq_o) == 1 # ok *now* it should be set
# read wb XIRR (32-bit)
- data = yield from wb_read(icp, XIRR)
+ data = yield from wb_read(icp.bus, XIRR)
print ("xirr", hex(data), bin(data))
data = swap32(data)
cppr = get_field(data, 8, 24)