Fix source pause logic

This commit is contained in:
Alex Forencich 2018-10-31 13:42:08 -07:00
parent 7d6889add6
commit c08026277e
4 changed files with 144 additions and 126 deletions

View File

@ -158,8 +158,10 @@ class ARPFrame(object):
class ARPFrameSource():
def __init__(self):
self.active = False
self.has_logic = False
self.queue = []
self.clk = Signal(bool(0))
def send(self, frame):
self.queue.append(ARPFrame(frame))
@ -170,6 +172,13 @@ class ARPFrameSource():
def empty(self):
return not self.queue
def idle(self):
return not self.queue and not self.active
def wait(self):
while not self.idle():
yield self.clk.posedge
def create_logic(self,
clk,
rst,
@ -195,13 +204,7 @@ class ARPFrameSource():
self.has_logic = True
frame_ready_int = Signal(bool(False))
frame_valid_int = Signal(bool(False))
@always_comb
def pause_logic():
frame_ready_int.next = frame_ready and not pause
frame_valid.next = frame_valid_int and not pause
self.clk = clk
@instance
def logic():
@ -211,30 +214,33 @@ class ARPFrameSource():
yield clk.posedge, rst.posedge
if rst:
frame_valid_int.next = False
frame_valid.next = False
self.active = False
else:
if frame_ready_int:
frame_valid_int.next = False
if (frame_ready_int and frame_valid) or not frame_valid_int:
if self.queue:
frame = self.queue.pop(0)
eth_dest_mac.next = frame.eth_dest_mac
eth_src_mac.next = frame.eth_src_mac
eth_type.next = frame.eth_type
arp_htype.next = frame.arp_htype
arp_ptype.next = frame.arp_ptype
arp_hlen.next = frame.arp_hlen
arp_plen.next = frame.arp_plen
arp_oper.next = frame.arp_oper
arp_sha.next = frame.arp_sha
arp_spa.next = frame.arp_spa
arp_tha.next = frame.arp_tha
arp_tpa.next = frame.arp_tpa
frame_valid.next = self.active and (frame_valid or not pause)
if frame_ready and frame_valid:
frame_valid.next = False
self.active = False
if not self.active and self.queue:
frame = self.queue.pop(0)
eth_dest_mac.next = frame.eth_dest_mac
eth_src_mac.next = frame.eth_src_mac
eth_type.next = frame.eth_type
arp_htype.next = frame.arp_htype
arp_ptype.next = frame.arp_ptype
arp_hlen.next = frame.arp_hlen
arp_plen.next = frame.arp_plen
arp_oper.next = frame.arp_oper
arp_sha.next = frame.arp_sha
arp_spa.next = frame.arp_spa
arp_tha.next = frame.arp_tha
arp_tpa.next = frame.arp_tpa
if name is not None:
print("[%s] Sending frame %s" % (name, repr(frame)))
if name is not None:
print("[%s] Sending frame %s" % (name, repr(frame)))
frame_valid_int.next = True
frame_valid.next = not pause
self.active = True
return instances()

View File

@ -122,10 +122,12 @@ class EthFrame(object):
class EthFrameSource():
def __init__(self):
self.active = False
self.has_logic = False
self.queue = []
self.payload_source = axis_ep.AXIStreamSource()
self.header_queue = []
self.clk = Signal(bool(0))
def send(self, frame):
frame = EthFrame(frame)
@ -141,6 +143,13 @@ class EthFrameSource():
def empty(self):
return not self.queue
def idle(self):
return not self.queue and not self.active and self.payload_source.idle()
def wait(self):
while not self.idle():
yield self.clk.posedge
def create_logic(self,
clk,
rst,
@ -163,9 +172,7 @@ class EthFrameSource():
self.has_logic = True
eth_hdr_ready_int = Signal(bool(False))
eth_hdr_valid_int = Signal(bool(False))
eth_payload_pause = Signal(bool(False))
self.clk = clk
eth_payload_source = self.payload_source.create_logic(
clk=clk,
@ -176,15 +183,9 @@ class EthFrameSource():
tready=eth_payload_tready,
tlast=eth_payload_tlast,
tuser=eth_payload_tuser,
pause=eth_payload_pause,
pause=pause,
)
@always_comb
def pause_logic():
eth_hdr_ready_int.next = eth_hdr_ready and not pause
eth_hdr_valid.next = eth_hdr_valid_int and not pause
eth_payload_pause.next = pause # or eth_hdr_valid_int
@instance
def logic():
frame = EthFrame()
@ -193,21 +194,24 @@ class EthFrameSource():
yield clk.posedge, rst.posedge
if rst:
eth_hdr_valid_int.next = False
eth_hdr_valid.next = False
self.active = False
else:
if eth_hdr_ready_int:
eth_hdr_valid_int.next = False
if (eth_hdr_ready_int and eth_hdr_valid) or not eth_hdr_valid_int:
if self.header_queue:
frame = self.header_queue.pop(0)
eth_dest_mac.next = frame.eth_dest_mac
eth_src_mac.next = frame.eth_src_mac
eth_type.next = frame.eth_type
eth_hdr_valid.next = self.active and (eth_hdr_valid or not pause)
if eth_hdr_ready and eth_hdr_valid:
eth_hdr_valid.next = False
self.active = False
if not self.active and self.header_queue:
frame = self.header_queue.pop(0)
eth_dest_mac.next = frame.eth_dest_mac
eth_src_mac.next = frame.eth_src_mac
eth_type.next = frame.eth_type
if name is not None:
print("[%s] Sending frame %s" % (name, repr(frame)))
if name is not None:
print("[%s] Sending frame %s" % (name, repr(frame)))
eth_hdr_valid_int.next = True
eth_hdr_valid.next = not pause
self.active = True
if self.queue and not self.header_queue:
frame = self.queue.pop(0)

View File

@ -239,10 +239,12 @@ class IPFrame(object):
class IPFrameSource():
def __init__(self):
self.active = False
self.has_logic = False
self.queue = []
self.payload_source = axis_ep.AXIStreamSource()
self.header_queue = []
self.clk = Signal(bool(0))
def send(self, frame):
frame = IPFrame(frame)
@ -258,6 +260,13 @@ class IPFrameSource():
def empty(self):
return not self.queue
def idle(self):
return not self.queue and not self.active and self.payload_source.idle()
def wait(self):
while not self.idle():
yield self.clk.posedge
def create_logic(self,
clk,
rst,
@ -293,9 +302,7 @@ class IPFrameSource():
self.has_logic = True
ip_hdr_ready_int = Signal(bool(False))
ip_hdr_valid_int = Signal(bool(False))
ip_payload_pause = Signal(bool(False))
self.clk = clk
ip_payload_source = self.payload_source.create_logic(
clk=clk,
@ -306,50 +313,47 @@ class IPFrameSource():
tready=ip_payload_tready,
tlast=ip_payload_tlast,
tuser=ip_payload_tuser,
pause=ip_payload_pause,
pause=pause,
)
@always_comb
def pause_logic():
ip_hdr_ready_int.next = ip_hdr_ready and not pause
ip_hdr_valid.next = ip_hdr_valid_int and not pause
ip_payload_pause.next = pause
@instance
def logic():
while True:
yield clk.posedge, rst.posedge
if rst:
ip_hdr_valid_int.next = False
ip_hdr_valid.next = False
self.active = False
else:
if ip_hdr_ready_int:
ip_hdr_valid_int.next = False
if (ip_hdr_ready_int and ip_hdr_valid) or not ip_hdr_valid_int:
if self.header_queue:
frame = self.header_queue.pop(0)
frame.build()
eth_dest_mac.next = frame.eth_dest_mac
eth_src_mac.next = frame.eth_src_mac
eth_type.next = frame.eth_type
ip_version.next = frame.ip_version
ip_ihl.next = frame.ip_ihl
ip_dscp.next = frame.ip_dscp
ip_ecn.next = frame.ip_ecn
ip_length.next = frame.ip_length
ip_identification.next = frame.ip_identification
ip_flags.next = frame.ip_flags
ip_fragment_offset.next = frame.ip_fragment_offset
ip_ttl.next = frame.ip_ttl
ip_protocol.next = frame.ip_protocol
ip_header_checksum.next = frame.ip_header_checksum
ip_source_ip.next = frame.ip_source_ip
ip_dest_ip.next = frame.ip_dest_ip
ip_hdr_valid.next = self.active and (ip_hdr_valid or not pause)
if ip_hdr_ready and ip_hdr_valid:
ip_hdr_valid.next = False
self.active = False
if not self.active and self.header_queue:
frame = self.header_queue.pop(0)
frame.build()
eth_dest_mac.next = frame.eth_dest_mac
eth_src_mac.next = frame.eth_src_mac
eth_type.next = frame.eth_type
ip_version.next = frame.ip_version
ip_ihl.next = frame.ip_ihl
ip_dscp.next = frame.ip_dscp
ip_ecn.next = frame.ip_ecn
ip_length.next = frame.ip_length
ip_identification.next = frame.ip_identification
ip_flags.next = frame.ip_flags
ip_fragment_offset.next = frame.ip_fragment_offset
ip_ttl.next = frame.ip_ttl
ip_protocol.next = frame.ip_protocol
ip_header_checksum.next = frame.ip_header_checksum
ip_source_ip.next = frame.ip_source_ip
ip_dest_ip.next = frame.ip_dest_ip
if name is not None:
print("[%s] Sending frame %s" % (name, repr(frame)))
if name is not None:
print("[%s] Sending frame %s" % (name, repr(frame)))
ip_hdr_valid_int.next = True
ip_hdr_valid.next = not pause
self.active = True
if self.queue and not self.header_queue:
frame = self.queue.pop(0)

View File

@ -324,10 +324,12 @@ class UDPFrame(object):
class UDPFrameSource():
def __init__(self):
self.active = False
self.has_logic = False
self.queue = []
self.payload_source = axis_ep.AXIStreamSource()
self.header_queue = []
self.clk = Signal(bool(0))
def send(self, frame):
frame = UDPFrame(frame)
@ -343,6 +345,13 @@ class UDPFrameSource():
def empty(self):
return not self.queue
def idle(self):
return not self.queue and not self.active and self.payload_source.idle()
def wait(self):
while not self.idle():
yield self.clk.posedge
def create_logic(self,
clk,
rst,
@ -382,9 +391,7 @@ class UDPFrameSource():
self.has_logic = True
udp_hdr_ready_int = Signal(bool(False))
udp_hdr_valid_int = Signal(bool(False))
udp_payload_pause = Signal(bool(False))
self.clk = clk
udp_payload_source = self.payload_source.create_logic(
clk=clk,
@ -395,54 +402,51 @@ class UDPFrameSource():
tready=udp_payload_tready,
tlast=udp_payload_tlast,
tuser=udp_payload_tuser,
pause=udp_payload_pause,
pause=pause,
)
@always_comb
def pause_logic():
udp_hdr_ready_int.next = udp_hdr_ready and not pause
udp_hdr_valid.next = udp_hdr_valid_int and not pause
udp_payload_pause.next = pause
@instance
def logic():
while True:
yield clk.posedge, rst.posedge
if rst:
udp_hdr_valid_int.next = False
udp_hdr_valid.next = False
self.active = False
else:
if udp_hdr_ready_int:
udp_hdr_valid_int.next = False
if (udp_hdr_ready_int and udp_hdr_valid) or not udp_hdr_valid_int:
if self.header_queue:
frame = self.header_queue.pop(0)
frame.build()
eth_dest_mac.next = frame.eth_dest_mac
eth_src_mac.next = frame.eth_src_mac
eth_type.next = frame.eth_type
ip_version.next = frame.ip_version
ip_ihl.next = frame.ip_ihl
ip_dscp.next = frame.ip_dscp
ip_ecn.next = frame.ip_ecn
ip_length.next = frame.ip_length
ip_identification.next = frame.ip_identification
ip_flags.next = frame.ip_flags
ip_fragment_offset.next = frame.ip_fragment_offset
ip_ttl.next = frame.ip_ttl
ip_protocol.next = frame.ip_protocol
ip_header_checksum.next = frame.ip_header_checksum
ip_source_ip.next = frame.ip_source_ip
ip_dest_ip.next = frame.ip_dest_ip
udp_source_port.next = frame.udp_source_port
udp_dest_port.next = frame.udp_dest_port
udp_length.next = frame.udp_length
udp_checksum.next = frame.udp_checksum
udp_hdr_valid.next = self.active and (udp_hdr_valid or not pause)
if udp_hdr_ready and udp_hdr_valid:
udp_hdr_valid.next = False
self.active = False
if not self.active and self.header_queue:
frame = self.header_queue.pop(0)
frame.build()
eth_dest_mac.next = frame.eth_dest_mac
eth_src_mac.next = frame.eth_src_mac
eth_type.next = frame.eth_type
ip_version.next = frame.ip_version
ip_ihl.next = frame.ip_ihl
ip_dscp.next = frame.ip_dscp
ip_ecn.next = frame.ip_ecn
ip_length.next = frame.ip_length
ip_identification.next = frame.ip_identification
ip_flags.next = frame.ip_flags
ip_fragment_offset.next = frame.ip_fragment_offset
ip_ttl.next = frame.ip_ttl
ip_protocol.next = frame.ip_protocol
ip_header_checksum.next = frame.ip_header_checksum
ip_source_ip.next = frame.ip_source_ip
ip_dest_ip.next = frame.ip_dest_ip
udp_source_port.next = frame.udp_source_port
udp_dest_port.next = frame.udp_dest_port
udp_length.next = frame.udp_length
udp_checksum.next = frame.udp_checksum
if name is not None:
print("[%s] Sending frame %s" % (name, repr(frame)))
if name is not None:
print("[%s] Sending frame %s" % (name, repr(frame)))
udp_hdr_valid_int.next = True
udp_hdr_valid.next = not pause
self.active = True
if self.queue and not self.header_queue:
frame = self.queue.pop(0)