Implement generators for source and sink pausing
This commit is contained in:
@@ -223,6 +223,10 @@ class AxiStreamSource(object):
|
|||||||
self.active = False
|
self.active = False
|
||||||
self.queue = deque()
|
self.queue = deque()
|
||||||
|
|
||||||
|
self.pause = False
|
||||||
|
self._pause_generator = None
|
||||||
|
self._pause_cr = None
|
||||||
|
|
||||||
self.queue_occupancy_bytes = 0
|
self.queue_occupancy_bytes = 0
|
||||||
self.queue_occupancy_frames = 0
|
self.queue_occupancy_frames = 0
|
||||||
|
|
||||||
@@ -273,6 +277,19 @@ class AxiStreamSource(object):
|
|||||||
while not self.idle():
|
while not self.idle():
|
||||||
await RisingEdge(self.clock)
|
await RisingEdge(self.clock)
|
||||||
|
|
||||||
|
def set_pause_generator(self, generator=None):
|
||||||
|
if self._pause_cr is not None:
|
||||||
|
self._pause_cr.kill()
|
||||||
|
self._pause_cr = None
|
||||||
|
|
||||||
|
self._pause_generator = generator
|
||||||
|
|
||||||
|
if self._pause_generator is not None:
|
||||||
|
self._pause_cr = cocotb.fork(self._run_pause())
|
||||||
|
|
||||||
|
def clear_pause_generator(self):
|
||||||
|
self.set_pause_generator(None)
|
||||||
|
|
||||||
async def _run(self):
|
async def _run(self):
|
||||||
frame = None
|
frame = None
|
||||||
self.active = False
|
self.active = False
|
||||||
@@ -314,7 +331,7 @@ class AxiStreamSource(object):
|
|||||||
await RisingEdge(self.clock)
|
await RisingEdge(self.clock)
|
||||||
|
|
||||||
if (tready_sample and tvalid_sample) or not tvalid_sample:
|
if (tready_sample and tvalid_sample) or not tvalid_sample:
|
||||||
if frame: # and not pause
|
if frame and not self.pause:
|
||||||
tdata_val = 0
|
tdata_val = 0
|
||||||
tlast_val = 0
|
tlast_val = 0
|
||||||
tkeep_val = 0
|
tkeep_val = 0
|
||||||
@@ -356,6 +373,11 @@ class AxiStreamSource(object):
|
|||||||
self.bus.tlast <= 0
|
self.bus.tlast <= 0
|
||||||
self.active = bool(frame)
|
self.active = bool(frame)
|
||||||
|
|
||||||
|
async def _run_pause(self):
|
||||||
|
for val in self._pause_generator:
|
||||||
|
self.pause = val
|
||||||
|
await RisingEdge(self.clock)
|
||||||
|
|
||||||
|
|
||||||
class AxiStreamSink(object):
|
class AxiStreamSink(object):
|
||||||
|
|
||||||
@@ -376,6 +398,10 @@ class AxiStreamSink(object):
|
|||||||
self.sync = Event()
|
self.sync = Event()
|
||||||
self.read_queue = []
|
self.read_queue = []
|
||||||
|
|
||||||
|
self.pause = False
|
||||||
|
self._pause_generator = None
|
||||||
|
self._pause_cr = None
|
||||||
|
|
||||||
self.queue_occupancy_bytes = 0
|
self.queue_occupancy_bytes = 0
|
||||||
self.queue_occupancy_frames = 0
|
self.queue_occupancy_frames = 0
|
||||||
self.queue_occupancy_limit_bytes = None
|
self.queue_occupancy_limit_bytes = None
|
||||||
@@ -436,6 +462,19 @@ class AxiStreamSink(object):
|
|||||||
else:
|
else:
|
||||||
await self.sync.wait()
|
await self.sync.wait()
|
||||||
|
|
||||||
|
def set_pause_generator(self, generator=None):
|
||||||
|
if self._pause_cr is not None:
|
||||||
|
self._pause_cr.kill()
|
||||||
|
self._pause_cr = None
|
||||||
|
|
||||||
|
self._pause_generator = generator
|
||||||
|
|
||||||
|
if self._pause_generator is not None:
|
||||||
|
self._pause_cr = cocotb.fork(self._run_pause())
|
||||||
|
|
||||||
|
def clear_pause_generator(self):
|
||||||
|
self.set_pause_generator(None)
|
||||||
|
|
||||||
async def _run(self):
|
async def _run(self):
|
||||||
frame = AxiStreamFrame()
|
frame = AxiStreamFrame()
|
||||||
frame.tdata = []
|
frame.tdata = []
|
||||||
@@ -504,5 +543,10 @@ class AxiStreamSink(object):
|
|||||||
elif self.queue_occupancy_limit_frames and self.queue_occupancy_frames > self.queue_occupancy_limit_frames:
|
elif self.queue_occupancy_limit_frames and self.queue_occupancy_frames > self.queue_occupancy_limit_frames:
|
||||||
self.bus.tready <= 0
|
self.bus.tready <= 0
|
||||||
else:
|
else:
|
||||||
self.bus.tready <= 1 # not pause
|
self.bus.tready <= (not self.pause)
|
||||||
|
|
||||||
|
async def _run_pause(self):
|
||||||
|
for val in self._pause_generator:
|
||||||
|
self.pause = val
|
||||||
|
await RisingEdge(self.clock)
|
||||||
|
|
||||||
|
|||||||
@@ -93,7 +93,10 @@ class StreamSource(object):
|
|||||||
getattr(self.bus, sig).setimmediatevalue(v)
|
getattr(self.bus, sig).setimmediatevalue(v)
|
||||||
|
|
||||||
self.active = False
|
self.active = False
|
||||||
|
|
||||||
self.pause = False
|
self.pause = False
|
||||||
|
self._pause_generator = None
|
||||||
|
self._pause_cr = None
|
||||||
|
|
||||||
cocotb.fork(self._run_source())
|
cocotb.fork(self._run_source())
|
||||||
cocotb.fork(self._run())
|
cocotb.fork(self._run())
|
||||||
@@ -127,6 +130,19 @@ class StreamSource(object):
|
|||||||
self.drive_obj = None
|
self.drive_obj = None
|
||||||
self.drive_sync.set()
|
self.drive_sync.set()
|
||||||
|
|
||||||
|
def set_pause_generator(self, generator=None):
|
||||||
|
if self._pause_cr is not None:
|
||||||
|
self._pause_cr.kill()
|
||||||
|
self._pause_cr = None
|
||||||
|
|
||||||
|
self._pause_generator = generator
|
||||||
|
|
||||||
|
if self._pause_generator is not None:
|
||||||
|
self._pause_cr = cocotb.fork(self._run_pause())
|
||||||
|
|
||||||
|
def clear_pause_generator(self):
|
||||||
|
self.set_pause_generator(None)
|
||||||
|
|
||||||
async def _run_source(self):
|
async def _run_source(self):
|
||||||
while True:
|
while True:
|
||||||
await ReadOnly()
|
await ReadOnly()
|
||||||
@@ -166,6 +182,11 @@ class StreamSource(object):
|
|||||||
|
|
||||||
await self.drive(self.queue.popleft())
|
await self.drive(self.queue.popleft())
|
||||||
|
|
||||||
|
async def _run_pause(self):
|
||||||
|
for val in self._pause_generator:
|
||||||
|
self.pause = val
|
||||||
|
await RisingEdge(self.clock)
|
||||||
|
|
||||||
|
|
||||||
class StreamSink(object):
|
class StreamSink(object):
|
||||||
|
|
||||||
@@ -207,6 +228,8 @@ class StreamSink(object):
|
|||||||
self.queue_sync = Event()
|
self.queue_sync = Event()
|
||||||
|
|
||||||
self.pause = False
|
self.pause = False
|
||||||
|
self._pause_generator = None
|
||||||
|
self._pause_cr = None
|
||||||
|
|
||||||
cocotb.fork(self._run_sink())
|
cocotb.fork(self._run_sink())
|
||||||
|
|
||||||
@@ -237,6 +260,19 @@ class StreamSink(object):
|
|||||||
self.queue.append(obj)
|
self.queue.append(obj)
|
||||||
self.queue_sync.set()
|
self.queue_sync.set()
|
||||||
|
|
||||||
|
def set_pause_generator(self, generator=None):
|
||||||
|
if self._pause_cr is not None:
|
||||||
|
self._pause_cr.kill()
|
||||||
|
self._pause_cr = None
|
||||||
|
|
||||||
|
self._pause_generator = generator
|
||||||
|
|
||||||
|
if self._pause_generator is not None:
|
||||||
|
self._pause_cr = cocotb.fork(self._run_pause())
|
||||||
|
|
||||||
|
def clear_pause_generator(self):
|
||||||
|
self.set_pause_generator(None)
|
||||||
|
|
||||||
async def _run_sink(self):
|
async def _run_sink(self):
|
||||||
while True:
|
while True:
|
||||||
await ReadOnly()
|
await ReadOnly()
|
||||||
@@ -261,6 +297,11 @@ class StreamSink(object):
|
|||||||
if self.ready is not None:
|
if self.ready is not None:
|
||||||
self.ready <= (not self.pause)
|
self.ready <= (not self.pause)
|
||||||
|
|
||||||
|
async def _run_pause(self):
|
||||||
|
for val in self._pause_generator:
|
||||||
|
self.pause = val
|
||||||
|
await RisingEdge(self.clock)
|
||||||
|
|
||||||
|
|
||||||
class StreamMonitor(object):
|
class StreamMonitor(object):
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user