forked from M-Labs/artiq-zynq
frameline GW: add roi proto
This commit is contained in:
parent
d6a0b4644c
commit
2cd588df35
@ -9,6 +9,7 @@ from src.gateware.cxp_pipeline import * # for sim only
|
||||
|
||||
from types import SimpleNamespace
|
||||
from math import lcm
|
||||
from operator import or_, add
|
||||
|
||||
pixel_width = 16
|
||||
pixel4x_layout = [
|
||||
@ -558,7 +559,7 @@ class Pixel_Parser(Module):
|
||||
self.pixel4x.append(Record([
|
||||
("x", res_width),
|
||||
("y", res_width),
|
||||
("d", pixel_width),
|
||||
("gray", pixel_width),
|
||||
("stb", 1),
|
||||
("eof", 1), # end of frame
|
||||
]))
|
||||
@ -588,10 +589,98 @@ class Pixel_Parser(Module):
|
||||
pix.stb.eq(self.sink.valid[i]),
|
||||
pix.x.eq(x_r),
|
||||
pix.y.eq(y_r),
|
||||
pix.d.eq(self.sink.data[pixel_width*i:pixel_width*(i+1)]),
|
||||
pix.gray.eq(self.sink.data[pixel_width*i:pixel_width*(i+1)]),
|
||||
)
|
||||
]
|
||||
|
||||
class ROI(Module):
|
||||
"""
|
||||
ROI Engine. For each frame, accumulates pixels values within a
|
||||
rectangular region of interest, and reports the total.
|
||||
"""
|
||||
def __init__(self, pixel_4x, count_len):
|
||||
assert count_len <= 31
|
||||
assert len(pixel_4x) == 4
|
||||
|
||||
self.cfg = Record([
|
||||
("x0", len(pixel_4x[0].x)),
|
||||
("y0", len(pixel_4x[0].y)),
|
||||
("x1", len(pixel_4x[0].x)),
|
||||
("y1", len(pixel_4x[0].y)),
|
||||
])
|
||||
|
||||
self.out = Record([
|
||||
("update", 1),
|
||||
("count", count_len),
|
||||
])
|
||||
|
||||
# # #
|
||||
#
|
||||
|
||||
self.roi_4x = []
|
||||
for _ in range(4):
|
||||
self.roi_4x.append(Record([
|
||||
("x_good", 1),
|
||||
("y_good", 1),
|
||||
("gray", len(pixel_4x[0].gray)),
|
||||
("stb", 1),
|
||||
("count", count_len),
|
||||
]))
|
||||
|
||||
|
||||
# x_good = [Signal() for _ in range(4)]
|
||||
# y_good = [Signal() for _ in range(4)]
|
||||
# gray = [Signal(len(pixel_4x[0].gray)) for _ in range(4)]
|
||||
# stb = [Signal() for _ in range(4)]
|
||||
# count = [Signal(count_len) for _ in range(4)]
|
||||
|
||||
for pix, roi in zip(pixel_4x, self.roi_4x):
|
||||
self.sync += [
|
||||
# stage 1 - generate "good" (in-ROI) signals
|
||||
If(pix.x == self.cfg.x0,
|
||||
roi.x_good.eq(1)
|
||||
),
|
||||
# NOTE: this gate doens't work as 4 pixes are coming in
|
||||
If(pix.x >= self.cfg.x1,
|
||||
roi.x_good.eq(0)
|
||||
),
|
||||
|
||||
# This is fine because 4x pixel are on the same line
|
||||
If(pix.y == self.cfg.y0,
|
||||
roi.y_good.eq(1)
|
||||
),
|
||||
If(pix.y == self.cfg.y1,
|
||||
roi.y_good.eq(0)
|
||||
),
|
||||
If(pix.eof,
|
||||
roi.x_good.eq(0),
|
||||
roi.y_good.eq(0)
|
||||
),
|
||||
roi.gray.eq(pix.gray),
|
||||
roi.stb.eq(pix.stb),
|
||||
|
||||
# stage 2 - accumulate
|
||||
If((roi.stb & roi.x_good & roi.y_good),
|
||||
roi.count.eq(roi.count + roi.gray)
|
||||
)
|
||||
]
|
||||
|
||||
eof = Signal()
|
||||
# stage 3 - update
|
||||
self.sync += [
|
||||
eof.eq(reduce(or_, [pix.eof for pix in pixel_4x])),
|
||||
|
||||
self.out.update.eq(0),
|
||||
If(eof,
|
||||
[roi.count.eq(0) for roi in self.roi_4x],
|
||||
self.out.update.eq(1),
|
||||
self.out.count.eq(reduce(add, [roi.count for roi in self.roi_4x]))
|
||||
|
||||
)
|
||||
]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class Frame_Deserializer(Module):
|
||||
@ -628,6 +717,7 @@ class Frame_Deserializer(Module):
|
||||
|
||||
self.submodules.parser = parser = Pixel_Parser(res_width)
|
||||
self.sync += parser.y_size.eq(self.y_size)
|
||||
self.pixel4x = parser.pixel4x
|
||||
|
||||
mux_cases = {
|
||||
"default": [
|
||||
@ -646,8 +736,8 @@ class Frame_Deserializer(Module):
|
||||
|
||||
|
||||
class ROI_Pipeline(Module):
|
||||
# TODO: but header xsize/ysize is only 24bits, change this to 24?
|
||||
def __init__(self, res_width=32):
|
||||
# largest x/y pixel size supported by frame header are 24 bits
|
||||
def __init__(self, res_width=24):
|
||||
|
||||
# NOTE: csr need to stay outside since this module need to be cdr in the CXP_FRAME_Pipeline module
|
||||
# NOTE: TapGeo other than 1X-1Y are not supported
|
||||
@ -658,6 +748,8 @@ class ROI_Pipeline(Module):
|
||||
self.submodules.header_decoder = header_decoder = Frame_Header_Decoder()
|
||||
self.submodules.deserializer = deserializer = Frame_Deserializer(res_width)
|
||||
|
||||
self.submodules.roi = ROI(deserializer.pixel4x, 31)
|
||||
|
||||
self.comb += [
|
||||
deserializer.new_frame.eq(header_decoder.new_frame),
|
||||
deserializer.l_size.eq(header_decoder.metadata.l_size),
|
||||
|
Loading…
Reference in New Issue
Block a user