forked from M-Labs/artiq-zynq
cxp GW: add proper roi gating and multiple roi
This commit is contained in:
parent
799e96c5ad
commit
fd060859d2
@ -7,6 +7,7 @@ from misoc.cores.coaxpress.phy.high_speed_gtx import HostRXPHYs
|
|||||||
from misoc.cores.coaxpress.phy.low_speed_serdes import HostTXPHYs
|
from misoc.cores.coaxpress.phy.low_speed_serdes import HostTXPHYs
|
||||||
|
|
||||||
from artiq.gateware.rtio import rtlink
|
from artiq.gateware.rtio import rtlink
|
||||||
|
from artiq.gateware.rtio.phy.grabber import Serializer
|
||||||
|
|
||||||
from cxp_frame_pipeline import *
|
from cxp_frame_pipeline import *
|
||||||
|
|
||||||
@ -286,7 +287,7 @@ class CXP_Frame_Pipeline(Module, AutoCSR):
|
|||||||
|
|
||||||
class CXP_Grabber(Module, AutoCSR):
|
class CXP_Grabber(Module, AutoCSR):
|
||||||
# optimal stream packet size is 2 KiB - Section 9.5.2 (CXP-001-2021)
|
# optimal stream packet size is 2 KiB - Section 9.5.2 (CXP-001-2021)
|
||||||
def __init__(self, host, roi_engine_count=1, res_width=16, count_width=31):
|
def __init__(self, host, roi_engine_count=2, res_width=16, count_width=31):
|
||||||
assert count_width <= 31
|
assert count_width <= 31
|
||||||
|
|
||||||
self.crc_error_cnt = CSRStatus(16)
|
self.crc_error_cnt = CSRStatus(16)
|
||||||
@ -377,58 +378,70 @@ class CXP_Grabber(Module, AutoCSR):
|
|||||||
roi_boundary.eq(self.config.o.data))
|
roi_boundary.eq(self.config.o.data))
|
||||||
self.specials += MultiReg(roi_boundary, target, "cxp_gt_rx")
|
self.specials += MultiReg(roi_boundary, target, "cxp_gt_rx")
|
||||||
|
|
||||||
roi_out = roi.out
|
# roi_out = roi.out
|
||||||
update = Signal()
|
# update = Signal()
|
||||||
self.submodules.ps = ps = PulseSynchronizer("cxp_gt_rx", "sys")
|
# self.submodules.ps = ps = PulseSynchronizer("cxp_gt_rx", "sys")
|
||||||
self.sync.cxp_gt_rx += ps.i.eq(roi_out.update)
|
# self.sync.cxp_gt_rx += ps.i.eq(roi_out.update)
|
||||||
self.sync += update.eq(ps.o)
|
# self.sync += update.eq(ps.o)
|
||||||
|
|
||||||
sentinel = 2**count_width
|
# sentinel = 2**count_width
|
||||||
count_sys = Signal.like(roi_out.count)
|
# count_sys = Signal.like(roi_out.count)
|
||||||
|
|
||||||
self.specials += MultiReg(roi_out.count, count_sys),
|
# self.specials += MultiReg(roi_out.count, count_sys),
|
||||||
self.sync.rio += [
|
# self.sync.rio += [
|
||||||
# TODO: add gating
|
# # TODO: add gating
|
||||||
self.gate_data.i.stb.eq(update),
|
# self.gate_data.i.stb.eq(update),
|
||||||
# without the slice, unspecified bits will be 1 for some reason
|
# # without the slice, unspecified bits will be 1 for some reason
|
||||||
# i.e. data[count_wdith:] = 0b111111... when using data.eq(count_sys)
|
# # i.e. data[count_wdith:] = 0b111111... when using data.eq(count_sys)
|
||||||
self.gate_data.i.data[:count_width].eq(count_sys),
|
# self.gate_data.i.data[:count_width].eq(count_sys),
|
||||||
]
|
# ]
|
||||||
|
|
||||||
# DEBUG:
|
|
||||||
new_line_cnt_rx, new_line_cnt_sys = Signal(3*char_width), Signal(3*char_width)
|
|
||||||
l_size_rx, l_size_sys = Signal(3*char_width), Signal(3*char_width)
|
|
||||||
x_size_rx, x_size_sys = Signal(3*char_width), Signal(3*char_width)
|
|
||||||
y_size_rx, y_size_sys = Signal(3*char_width), Signal(3*char_width)
|
|
||||||
y_pix_rx, y_pix_sys = Signal(res_width), Signal(res_width)
|
|
||||||
self.sync.cxp_gt_rx += [
|
|
||||||
If(stream2pix.header_reader.new_line,
|
|
||||||
new_line_cnt_rx.eq(new_line_cnt_rx + 1),
|
|
||||||
),
|
|
||||||
|
|
||||||
l_size_rx.eq(stream2pix.header_reader.metadata.l_size),
|
self.submodules.synchronizer = synchronizer = CXP_Synchronizer(roi_engines)
|
||||||
x_size_rx.eq(stream2pix.header_reader.metadata.x_size),
|
self.submodules.serializer = serializer = Serializer(synchronizer.update, synchronizer.counts, self.gate_data.i)
|
||||||
y_size_rx.eq(stream2pix.header_reader.metadata.y_size),
|
|
||||||
|
|
||||||
y_pix_rx.eq(stream2pix.pixel4x[0].y),
|
self.sync.rio += If(self.gate_data.o.stb,
|
||||||
]
|
serializer.gate.eq(self.gate_data.o.data))
|
||||||
self.specials += [
|
|
||||||
MultiReg(new_line_cnt_rx, new_line_cnt_sys),
|
|
||||||
MultiReg(l_size_rx, l_size_sys),
|
# DEBUG:
|
||||||
MultiReg(x_size_rx, x_size_sys),
|
l_size_rx, l_size_sys = Signal(3*char_width), Signal(3*char_width)
|
||||||
MultiReg(y_size_rx, y_size_sys),
|
x_size_rx, x_size_sys = Signal(3*char_width), Signal(3*char_width)
|
||||||
MultiReg(y_pix_rx, y_pix_sys),
|
y_size_rx, y_size_sys = Signal(3*char_width), Signal(3*char_width)
|
||||||
]
|
y_pix_rx, y_pix_sys = Signal(res_width), Signal(res_width)
|
||||||
self.sync += [
|
self.sync.cxp_gt_rx += [
|
||||||
self.header_new_line.status.eq(new_line_cnt_sys),
|
l_size_rx.eq(stream2pix.header_reader.metadata.l_size),
|
||||||
self.pix_y.status.eq(y_pix_sys),
|
x_size_rx.eq(stream2pix.header_reader.metadata.x_size),
|
||||||
self.header_l_size.status.eq(l_size_sys),
|
y_size_rx.eq(stream2pix.header_reader.metadata.y_size),
|
||||||
self.header_x_size.status.eq(x_size_sys),
|
y_pix_rx.eq(stream2pix.pixel4x[0].y),
|
||||||
self.header_y_size.status.eq(y_size_sys),
|
]
|
||||||
self.roi_counter.status.eq(count_sys),
|
self.specials += [
|
||||||
If(update,
|
MultiReg(l_size_rx, l_size_sys),
|
||||||
self.roi_update.w.eq(1),
|
MultiReg(x_size_rx, x_size_sys),
|
||||||
).Elif(self.roi_update.re,
|
MultiReg(y_size_rx, y_size_sys),
|
||||||
self.roi_update.w.eq(0),
|
MultiReg(y_pix_rx, y_pix_sys),
|
||||||
),
|
]
|
||||||
]
|
self.sync += [
|
||||||
|
self.pix_y.status.eq(y_pix_sys),
|
||||||
|
self.header_l_size.status.eq(l_size_sys),
|
||||||
|
self.header_x_size.status.eq(x_size_sys),
|
||||||
|
self.header_y_size.status.eq(y_size_sys),
|
||||||
|
]
|
||||||
|
|
||||||
|
class CXP_Synchronizer(Module):
|
||||||
|
def __init__(self, roi_engines):
|
||||||
|
counts_in = [roi_engine.out.count for roi_engine in roi_engines]
|
||||||
|
|
||||||
|
# This assumes all ROI engines update at the same time.
|
||||||
|
self.update = Signal()
|
||||||
|
# stays valid until the next frame after self.update is pulsed.
|
||||||
|
self.counts = [Signal.like(count) for count in counts_in]
|
||||||
|
|
||||||
|
# # #
|
||||||
|
|
||||||
|
for i, o in zip(counts_in, self.counts):
|
||||||
|
self.specials += MultiReg(i, o)
|
||||||
|
|
||||||
|
self.submodules.ps = ps = PulseSynchronizer("cxp_gt_rx", "sys")
|
||||||
|
self.sync.cxp_gt_rx += ps.i.eq(roi_engines[0].out.update)
|
||||||
|
self.sync += self.update.eq(ps.o)
|
||||||
|
Loading…
Reference in New Issue
Block a user