frameline GW: fix roi

frameline GW: remove unused import

frameline GW: add econ roi
This commit is contained in:
morgan 2025-01-24 11:53:38 +08:00
parent 8d9b030a24
commit 58b05a2877

View File

@ -1,5 +1,4 @@
from migen import *
from migen.genlib.coding import PriorityEncoder
from misoc.interconnect.csr import *
from misoc.interconnect import stream
from misoc.cores.liteeth_mini.mac.crc import LiteEthMACCRCEngine
@ -631,31 +630,26 @@ class ROI(Module):
# # #
# TODO: remove the self. from self.roi_4x
self.roi_4x = []
for _ in range(4):
self.roi_4x.append(Record([
roi_4x = [
Record([
("x_good", 1),
("y_good", 1),
("gray", len(pixel_4x[0].gray)),
("stb", 1),
("count", count_width),
]))
]) for _ in range(4)
for pix, roi in zip(pixel_4x, self.roi_4x):
]
for pix, roi in zip(pixel_4x, roi_4x):
self.sync += [
# TODO: replace the comparision with preprocess equal
# e.g. pix.x == self.cfg.x0 - i
# stage 1 - generate "good" (in-ROI) signals
If(pix.x <= self.cfg.x0,
roi.x_good.eq(0),
If((self.cfg.x0 <= pix.x) & (pix.x < self.cfg.x1),
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
# the 4 pixels are on the same y level, no need for extra calculation
If(pix.y == self.cfg.y0,
roi.y_good.eq(1)
),
@ -683,12 +677,115 @@ class ROI(Module):
self.sync += [
eof.eq(reduce(or_, [pix.eof for pix in pixel_4x])),
eof_buf.eq(eof),
count_buf[0].eq(self.roi_4x[0].count + self.roi_4x[1].count),
count_buf[1].eq(self.roi_4x[2].count + self.roi_4x[3].count),
count_buf[0].eq(roi_4x[0].count + roi_4x[1].count),
count_buf[1].eq(roi_4x[2].count + roi_4x[3].count),
self.out.update.eq(0),
If(eof_buf,
[roi.count.eq(0) for roi in self.roi_4x],
[roi.count.eq(0) for roi in roi_4x],
self.out.update.eq(1),
self.out.count.eq(reduce(add, count_buf))
),
]
class Economical_ROI(Module):
"""
ROI Engine. For each frame, accumulates pixels values within a
rectangular region of interest, and reports the total.
This econ version limits the distance between x0 and x1 need to be at least 4 pixel long
"""
def __init__(self, pixel_4x, count_width):
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),
# registered output - can be used as CDC input
("count", count_width),
])
# # #
roi_4x = [
Record([
("x_good", 1),
("y_good", 1),
("gray", len(pixel_4x[0].gray)),
("stb", 1),
("count", count_width),
]) for _ in range(4)
]
# Pipeline the offset calculation
x0_offset = [Signal.like(self.cfg.x0) for _ in range(4)]
x1_offset = [Signal.like(self.cfg.x1) for _ in range(4)]
for offset, (x0, x1) in enumerate(zip(x0_offset, x1_offset)):
self.sync += [
x0.eq(self.cfg.x0 + offset),
x1.eq(self.cfg.x1 + offset),
]
for pix, roi in zip(pixel_4x, roi_4x):
# stage 1 - generate "good" (in-ROI) signals
# if p in [x0, x0+3] => x_good == 1
# if p in [x1, x1+3] => x_good == 0
# when [x0, x0+3] overlap with [x1, x1+3]:
# some x_good won't have the chance to fall and keep accmulated extra data
# Thus, x1-x0 >= 4 need to be match for pixel to accmulated correctly
for x0, x1 in zip(x0_offset, x1_offset):
self.sync += [
If(pix.x == x0,
roi.x_good.eq(1),
),
If(pix.x == x1,
roi.x_good.eq(0),
),
]
self.sync += [
# the 4 pixels are on the same y level, no need for extra calculation
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()
eof_buf = Signal()
count_buf = [Signal(count_width), Signal(count_width)]
# stage 3 - update
self.sync += [
eof.eq(reduce(or_, [pix.eof for pix in pixel_4x])),
eof_buf.eq(eof),
count_buf[0].eq(roi_4x[0].count + roi_4x[1].count),
count_buf[1].eq(roi_4x[2].count + roi_4x[3].count),
self.out.update.eq(0),
If(eof_buf,
[roi.count.eq(0) for roi in roi_4x],
self.out.update.eq(1),
self.out.count.eq(reduce(add, count_buf))
),