mirror of
https://github.com/alexforencich/verilog-axi.git
synced 2025-01-28 07:02:56 +08:00
Support pausing channels in AXI models
This commit is contained in:
parent
048c0bb5e5
commit
4ee04f6682
110
tb/axi.py
110
tb/axi.py
@ -179,6 +179,12 @@ class AXIMaster(object):
|
||||
m_axi_ruser=None,
|
||||
m_axi_rvalid=Signal(bool(False)),
|
||||
m_axi_rready=Signal(bool(False)),
|
||||
pause=False,
|
||||
awpause=False,
|
||||
wpause=False,
|
||||
bpause=False,
|
||||
arpause=False,
|
||||
rpause=False,
|
||||
name=None
|
||||
):
|
||||
|
||||
@ -215,6 +221,30 @@ class AXIMaster(object):
|
||||
self.has_logic = True
|
||||
self.clk = clk
|
||||
|
||||
m_axi_awvalid_int = Signal(bool(False))
|
||||
m_axi_awready_int = Signal(bool(False))
|
||||
m_axi_wvalid_int = Signal(bool(False))
|
||||
m_axi_wready_int = Signal(bool(False))
|
||||
m_axi_bvalid_int = Signal(bool(False))
|
||||
m_axi_bready_int = Signal(bool(False))
|
||||
m_axi_arvalid_int = Signal(bool(False))
|
||||
m_axi_arready_int = Signal(bool(False))
|
||||
m_axi_rvalid_int = Signal(bool(False))
|
||||
m_axi_rready_int = Signal(bool(False))
|
||||
|
||||
@always_comb
|
||||
def pause_logic():
|
||||
m_axi_awvalid.next = m_axi_awvalid_int and not (pause or awpause)
|
||||
m_axi_awready_int.next = m_axi_awready and not (pause or awpause)
|
||||
m_axi_wvalid.next = m_axi_wvalid_int and not (pause or wpause)
|
||||
m_axi_wready_int.next = m_axi_wready and not (pause or wpause)
|
||||
m_axi_bvalid_int.next = m_axi_bvalid and not (pause or bpause)
|
||||
m_axi_bready.next = m_axi_bready_int and not (pause or bpause)
|
||||
m_axi_arvalid.next = m_axi_arvalid_int and not (pause or arpause)
|
||||
m_axi_arready_int.next = m_axi_arready and not (pause or arpause)
|
||||
m_axi_rvalid_int.next = m_axi_rvalid and not (pause or rpause)
|
||||
m_axi_rready.next = m_axi_rready_int and not (pause or rpause)
|
||||
|
||||
@instance
|
||||
def write_logic():
|
||||
while True:
|
||||
@ -329,14 +359,14 @@ class AXIMaster(object):
|
||||
m_axi_awregion.next = region
|
||||
if m_axi_awuser is not None:
|
||||
m_axi_awuser.next = user
|
||||
m_axi_awvalid.next = True
|
||||
m_axi_awvalid_int.next = True
|
||||
|
||||
yield clk.posedge
|
||||
|
||||
while m_axi_awvalid and not m_axi_awready:
|
||||
while m_axi_awvalid_int and not m_axi_awready_int:
|
||||
yield clk.posedge
|
||||
|
||||
m_axi_awvalid.next = False
|
||||
m_axi_awvalid_int.next = False
|
||||
|
||||
@instance
|
||||
def write_data_interface_logic():
|
||||
@ -345,23 +375,23 @@ class AXIMaster(object):
|
||||
yield clk.posedge
|
||||
|
||||
m_axi_wdata.next, m_axi_wstrb.next, m_axi_wlast.next = self.int_write_data_queue.pop(0)
|
||||
m_axi_wvalid.next = True
|
||||
m_axi_wvalid_int.next = True
|
||||
|
||||
yield clk.posedge
|
||||
|
||||
while m_axi_wvalid and not m_axi_wready:
|
||||
while m_axi_wvalid_int and not m_axi_wready_int:
|
||||
yield clk.posedge
|
||||
|
||||
m_axi_wvalid.next = False
|
||||
m_axi_wvalid_int.next = False
|
||||
|
||||
@instance
|
||||
def write_resp_interface_logic():
|
||||
while True:
|
||||
m_axi_bready.next = True
|
||||
m_axi_bready_int.next = True
|
||||
|
||||
yield clk.posedge
|
||||
|
||||
if m_axi_bready & m_axi_bvalid:
|
||||
if m_axi_bready and m_axi_bvalid_int:
|
||||
if m_axi_bid is not None:
|
||||
bid = int(m_axi_bid)
|
||||
else:
|
||||
@ -491,23 +521,23 @@ class AXIMaster(object):
|
||||
m_axi_arregion.next = region
|
||||
if m_axi_aruser is not None:
|
||||
m_axi_aruser.next = user
|
||||
m_axi_arvalid.next = True
|
||||
m_axi_arvalid_int.next = True
|
||||
|
||||
yield clk.posedge
|
||||
|
||||
while m_axi_arvalid and not m_axi_arready:
|
||||
while m_axi_arvalid_int and not m_axi_arready_int:
|
||||
yield clk.posedge
|
||||
|
||||
m_axi_arvalid.next = False
|
||||
m_axi_arvalid_int.next = False
|
||||
|
||||
@instance
|
||||
def read_resp_interface_logic():
|
||||
while True:
|
||||
m_axi_rready.next = True
|
||||
m_axi_rready_int.next = True
|
||||
|
||||
yield clk.posedge
|
||||
|
||||
if m_axi_rready & m_axi_rvalid:
|
||||
if m_axi_rready and m_axi_rvalid_int:
|
||||
if m_axi_rid is not None:
|
||||
rid = int(m_axi_rid)
|
||||
else:
|
||||
@ -587,6 +617,12 @@ class AXIRam(object):
|
||||
s_axi_rlast=Signal(bool(True)),
|
||||
s_axi_rvalid=Signal(bool(False)),
|
||||
s_axi_rready=Signal(bool(False)),
|
||||
pause=False,
|
||||
awpause=False,
|
||||
wpause=False,
|
||||
bpause=False,
|
||||
arpause=False,
|
||||
rpause=False,
|
||||
name=None
|
||||
):
|
||||
|
||||
@ -617,6 +653,30 @@ class AXIRam(object):
|
||||
|
||||
assert bw in (1, 2, 4, 8, 16, 32, 64, 128)
|
||||
|
||||
s_axi_awvalid_int = Signal(bool(False))
|
||||
s_axi_awready_int = Signal(bool(False))
|
||||
s_axi_wvalid_int = Signal(bool(False))
|
||||
s_axi_wready_int = Signal(bool(False))
|
||||
s_axi_bvalid_int = Signal(bool(False))
|
||||
s_axi_bready_int = Signal(bool(False))
|
||||
s_axi_arvalid_int = Signal(bool(False))
|
||||
s_axi_arready_int = Signal(bool(False))
|
||||
s_axi_rvalid_int = Signal(bool(False))
|
||||
s_axi_rready_int = Signal(bool(False))
|
||||
|
||||
@always_comb
|
||||
def pause_logic():
|
||||
s_axi_awvalid_int.next = s_axi_awvalid and not (pause or awpause)
|
||||
s_axi_awready.next = s_axi_awready_int and not (pause or awpause)
|
||||
s_axi_wvalid_int.next = s_axi_wvalid and not (pause or wpause)
|
||||
s_axi_wready.next = s_axi_wready_int and not (pause or wpause)
|
||||
s_axi_bvalid.next = s_axi_bvalid_int and not (pause or bpause)
|
||||
s_axi_bready_int.next = s_axi_bready and not (pause or bpause)
|
||||
s_axi_arvalid_int.next = s_axi_arvalid and not (pause or arpause)
|
||||
s_axi_arready.next = s_axi_arready_int and not (pause or arpause)
|
||||
s_axi_rvalid.next = s_axi_rvalid_int and not (pause or rpause)
|
||||
s_axi_rready_int.next = s_axi_rready and not (pause or rpause)
|
||||
|
||||
@instance
|
||||
def write_logic():
|
||||
while True:
|
||||
@ -682,11 +742,11 @@ class AXIRam(object):
|
||||
@instance
|
||||
def write_addr_interface_logic():
|
||||
while True:
|
||||
s_axi_awready.next = True
|
||||
s_axi_awready_int.next = True
|
||||
|
||||
yield clk.posedge
|
||||
|
||||
if s_axi_awready & s_axi_awvalid:
|
||||
if s_axi_awready and s_axi_awvalid_int:
|
||||
addr = int(s_axi_awaddr)
|
||||
if s_axi_awid is not None:
|
||||
awid = int(s_axi_awid)
|
||||
@ -704,11 +764,11 @@ class AXIRam(object):
|
||||
@instance
|
||||
def write_data_interface_logic():
|
||||
while True:
|
||||
s_axi_wready.next = True
|
||||
s_axi_wready_int.next = True
|
||||
|
||||
yield clk.posedge
|
||||
|
||||
if s_axi_wready & s_axi_wvalid:
|
||||
if s_axi_wready and s_axi_wvalid_int:
|
||||
data = int(s_axi_wdata)
|
||||
strb = int(s_axi_wstrb)
|
||||
last = bool(s_axi_wlast)
|
||||
@ -725,14 +785,14 @@ class AXIRam(object):
|
||||
if s_axi_bid is not None:
|
||||
s_axi_bid.next = bid
|
||||
s_axi_bresp.next = bresp
|
||||
s_axi_bvalid.next = True
|
||||
s_axi_bvalid_int.next = True
|
||||
|
||||
yield clk.posedge
|
||||
|
||||
while s_axi_bvalid and not s_axi_bready:
|
||||
while s_axi_bvalid_int and not s_axi_bready_int:
|
||||
yield clk.posedge
|
||||
|
||||
s_axi_bvalid.next = False
|
||||
s_axi_bvalid_int.next = False
|
||||
|
||||
@instance
|
||||
def read_logic():
|
||||
@ -785,11 +845,11 @@ class AXIRam(object):
|
||||
@instance
|
||||
def read_addr_interface_logic():
|
||||
while True:
|
||||
s_axi_arready.next = True
|
||||
s_axi_arready_int.next = True
|
||||
|
||||
yield clk.posedge
|
||||
|
||||
if s_axi_arready & s_axi_arvalid:
|
||||
if s_axi_arready and s_axi_arvalid_int:
|
||||
addr = int(s_axi_araddr)
|
||||
if s_axi_arid is not None:
|
||||
arid = int(s_axi_arid)
|
||||
@ -816,14 +876,14 @@ class AXIRam(object):
|
||||
s_axi_rdata.next = rdata
|
||||
s_axi_rresp.next = rresp
|
||||
s_axi_rlast.next = rlast
|
||||
s_axi_rvalid.next = True
|
||||
s_axi_rvalid_int.next = True
|
||||
|
||||
yield clk.posedge
|
||||
|
||||
while s_axi_rvalid and not s_axi_rready:
|
||||
while s_axi_rvalid_int and not s_axi_rready_int:
|
||||
yield clk.posedge
|
||||
|
||||
s_axi_rvalid.next = False
|
||||
s_axi_rvalid_int.next = False
|
||||
|
||||
return instances()
|
||||
|
||||
|
@ -79,6 +79,7 @@ def bench():
|
||||
|
||||
# AXI4 master
|
||||
axi_master_inst = axi.AXIMaster()
|
||||
axi_master_pause = Signal(bool(False))
|
||||
|
||||
axi_master_logic = axi_master_inst.create_logic(
|
||||
clk,
|
||||
@ -122,11 +123,13 @@ def bench():
|
||||
m_axi_rlast=port0_axi_rlast,
|
||||
m_axi_rvalid=port0_axi_rvalid,
|
||||
m_axi_rready=port0_axi_rready,
|
||||
pause=axi_master_pause,
|
||||
name='master'
|
||||
)
|
||||
|
||||
# AXI4 RAM model
|
||||
axi_ram_inst = axi.AXIRam(2**16)
|
||||
axi_ram_pause = Signal(bool(False))
|
||||
|
||||
axi_ram_port0 = axi_ram_inst.create_port(
|
||||
clk,
|
||||
@ -165,6 +168,7 @@ def bench():
|
||||
s_axi_rlast=port0_axi_rlast,
|
||||
s_axi_rvalid=port0_axi_rvalid,
|
||||
s_axi_rready=port0_axi_rready,
|
||||
pause=axi_ram_pause,
|
||||
name='port0'
|
||||
)
|
||||
|
||||
@ -172,6 +176,28 @@ def bench():
|
||||
def clkgen():
|
||||
clk.next = not clk
|
||||
|
||||
def wait_normal():
|
||||
while not axi_master_inst.idle():
|
||||
yield clk.posedge
|
||||
|
||||
def wait_pause_master():
|
||||
while not axi_master_inst.idle():
|
||||
axi_master_pause.next = True
|
||||
yield clk.posedge
|
||||
yield clk.posedge
|
||||
yield clk.posedge
|
||||
axi_master_pause.next = False
|
||||
yield clk.posedge
|
||||
|
||||
def wait_pause_slave():
|
||||
while not axi_master_inst.idle():
|
||||
axi_ram_pause.next = True
|
||||
yield clk.posedge
|
||||
yield clk.posedge
|
||||
yield clk.posedge
|
||||
axi_ram_pause.next = False
|
||||
yield clk.posedge
|
||||
|
||||
@instance
|
||||
def check():
|
||||
yield delay(100)
|
||||
@ -244,19 +270,20 @@ def bench():
|
||||
for length in range(1,8):
|
||||
for offset in range(4,8):
|
||||
for size in (2, 1, 0):
|
||||
axi_ram_inst.write_mem(256*(16*offset+length), b'\xAA'*32)
|
||||
axi_master_inst.init_write(256*(16*offset+length)+offset, b'\x11\x22\x33\x44\x55\x66\x77\x88'[0:length], size=size)
|
||||
for wait in wait_normal, wait_pause_master, wait_pause_slave:
|
||||
axi_ram_inst.write_mem(256*(16*offset+length), b'\xAA'*32)
|
||||
axi_master_inst.init_write(256*(16*offset+length)+offset, b'\x11\x22\x33\x44\x55\x66\x77\x88'[0:length], size=size)
|
||||
|
||||
yield axi_master_inst.wait()
|
||||
yield clk.posedge
|
||||
yield wait()
|
||||
yield clk.posedge
|
||||
|
||||
data = axi_ram_inst.read_mem(256*(16*offset+length), 32)
|
||||
for i in range(0, len(data), 16):
|
||||
print(" ".join(("{:02x}".format(c) for c in bytearray(data[i:i+16]))))
|
||||
data = axi_ram_inst.read_mem(256*(16*offset+length), 32)
|
||||
for i in range(0, len(data), 16):
|
||||
print(" ".join(("{:02x}".format(c) for c in bytearray(data[i:i+16]))))
|
||||
|
||||
assert axi_ram_inst.read_mem(256*(16*offset+length)+offset, length) == b'\x11\x22\x33\x44\x55\x66\x77\x88'[0:length]
|
||||
assert axi_ram_inst.read_mem(256*(16*offset+length)+offset-1, 1) == b'\xAA'
|
||||
assert axi_ram_inst.read_mem(256*(16*offset+length)+offset+length, 1) == b'\xAA'
|
||||
assert axi_ram_inst.read_mem(256*(16*offset+length)+offset, length) == b'\x11\x22\x33\x44\x55\x66\x77\x88'[0:length]
|
||||
assert axi_ram_inst.read_mem(256*(16*offset+length)+offset-1, 1) == b'\xAA'
|
||||
assert axi_ram_inst.read_mem(256*(16*offset+length)+offset+length, 1) == b'\xAA'
|
||||
|
||||
yield delay(100)
|
||||
|
||||
@ -267,14 +294,15 @@ def bench():
|
||||
for length in range(1,8):
|
||||
for offset in range(4,8):
|
||||
for size in (2, 1, 0):
|
||||
axi_master_inst.init_read(256*(16*offset+length)+offset, length, size=size)
|
||||
for wait in wait_normal, wait_pause_master, wait_pause_slave:
|
||||
axi_master_inst.init_read(256*(16*offset+length)+offset, length, size=size)
|
||||
|
||||
yield axi_master_inst.wait()
|
||||
yield clk.posedge
|
||||
yield wait()
|
||||
yield clk.posedge
|
||||
|
||||
data = axi_master_inst.get_read_data()
|
||||
assert data[0] == 256*(16*offset+length)+offset
|
||||
assert data[1] == b'\x11\x22\x33\x44\x55\x66\x77\x88'[0:length]
|
||||
data = axi_master_inst.get_read_data()
|
||||
assert data[0] == 256*(16*offset+length)+offset
|
||||
assert data[1] == b'\x11\x22\x33\x44\x55\x66\x77\x88'[0:length]
|
||||
|
||||
yield delay(100)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user