forked from M-Labs/artiq-zynq
frameline: add single lane pixel converter
This commit is contained in:
parent
b34d68797d
commit
39c4fe5f6e
@ -22,9 +22,10 @@ pixel4x_layout = [
|
|||||||
("valid", 4),
|
("valid", 4),
|
||||||
]
|
]
|
||||||
|
|
||||||
class End_Of_Line_Inserter(Module):
|
# TODO: rename this to signalify eol marker & kcode/other data dropper
|
||||||
|
class End_Of_Line_Marker(Module):
|
||||||
"""
|
"""
|
||||||
Insert eop to indicate end of line
|
Repurpose eop to indicate end of line
|
||||||
And drop the K codes and Duplicate char
|
And drop the K codes and Duplicate char
|
||||||
|
|
||||||
"""
|
"""
|
||||||
@ -264,7 +265,10 @@ class Stream_Broadcaster(Module):
|
|||||||
NextState("WAIT_HEADER"),
|
NextState("WAIT_HEADER"),
|
||||||
)
|
)
|
||||||
|
|
||||||
class Frame_Header_Decoder(Module):
|
class Frame_Header_Reader(Module):
|
||||||
|
"""
|
||||||
|
Extract the frame header information
|
||||||
|
"""
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.decode_err = Signal()
|
self.decode_err = Signal()
|
||||||
|
|
||||||
@ -827,7 +831,7 @@ class Pixel_Parser(Module):
|
|||||||
# inserter Tracker w/ coord
|
# inserter Tracker w/ coord
|
||||||
#
|
#
|
||||||
|
|
||||||
self.submodules.eol_inserter = eol_inserter = End_Of_Line_Inserter()
|
self.submodules.eol_inserter = eol_inserter = End_Of_Line_Marker()
|
||||||
self.sync += eol_inserter.l_size.eq(self.l_size)
|
self.sync += eol_inserter.l_size.eq(self.l_size)
|
||||||
self.sink = eol_inserter.sink
|
self.sink = eol_inserter.sink
|
||||||
|
|
||||||
@ -883,7 +887,7 @@ class Pixel_Pipeline(Module):
|
|||||||
self.submodules.buffer = buffer = SyncFIFO(word_layout_dchar, 32, True)
|
self.submodules.buffer = buffer = SyncFIFO(word_layout_dchar, 32, True)
|
||||||
# self.submodules.buffer = buffer = Buffer(word_layout_dchar) # to improve timing from broadcaster
|
# self.submodules.buffer = buffer = Buffer(word_layout_dchar) # to improve timing from broadcaster
|
||||||
self.submodules.crc_checker = crc_checker = CXPCRC32_Checker()
|
self.submodules.crc_checker = crc_checker = CXPCRC32_Checker()
|
||||||
self.submodules.header_decoder = header_decoder = Frame_Header_Decoder()
|
self.submodules.header_decoder = header_decoder = Frame_Header_Reader()
|
||||||
self.submodules.parser = parser = Pixel_Parser(res_width)
|
self.submodules.parser = parser = Pixel_Parser(res_width)
|
||||||
|
|
||||||
self.submodules.roi = ROI(parser.pixel4x, count_width)
|
self.submodules.roi = ROI(parser.pixel4x, count_width)
|
||||||
@ -904,3 +908,70 @@ class Pixel_Pipeline(Module):
|
|||||||
# self.pix = self.pipeline[-1].pix
|
# self.pix = self.pipeline[-1].pix
|
||||||
# self.source = self.pipeline[-1].source
|
# self.source = self.pipeline[-1].source
|
||||||
# self.comb += self.source.ack.eq(1) # simulated a proper consumer, idk why but without this it will destory timing
|
# self.comb += self.source.ack.eq(1) # simulated a proper consumer, idk why but without this it will destory timing
|
||||||
|
|
||||||
|
class Stream2Pixel4x_Converter(Module):
|
||||||
|
"""
|
||||||
|
Convert the raw frame data into pixel data
|
||||||
|
|
||||||
|
Currently only support:
|
||||||
|
- Pixel format: mono8, mono10, mono12, mono14, mono16
|
||||||
|
- Tap geometry: 1X-1Y
|
||||||
|
- Scaning mode: area scanning
|
||||||
|
|
||||||
|
"""
|
||||||
|
def __init__(self, res_width, count_width):
|
||||||
|
|
||||||
|
# 32+8(dchar)
|
||||||
|
# ----/----> crc checker ------> frame header ------> eol inserter
|
||||||
|
# decoder
|
||||||
|
#
|
||||||
|
# 32 pixel 4x
|
||||||
|
# ---/---> 32:8/10/12/14/16 Pixel Gearboxes ----/----> Pixel Coordinate ------> pixel 4x
|
||||||
|
# Tracker w/ coord
|
||||||
|
#
|
||||||
|
|
||||||
|
self.submodules.crc_checker = crc_checker = CXPCRC32_Checker()
|
||||||
|
self.submodules.header_reader = header_reader = Frame_Header_Reader()
|
||||||
|
|
||||||
|
# Pixel Praser
|
||||||
|
self.submodules.eol_inserter = eol_inserter = End_Of_Line_Marker()
|
||||||
|
self.sync += eol_inserter.l_size.eq(header_reader.metadata.l_size)
|
||||||
|
self.sink = eol_inserter.sink
|
||||||
|
|
||||||
|
|
||||||
|
self.pipeline = [crc_checker, header_reader, eol_inserter]
|
||||||
|
for s, d in zip(self.pipeline, self.pipeline[1:]):
|
||||||
|
self.comb += s.source.connect(d.sink)
|
||||||
|
self.sink = self.pipeline[0].sink
|
||||||
|
|
||||||
|
|
||||||
|
gearboxes = {}
|
||||||
|
for s in [8, 10, 12, 14, 16]:
|
||||||
|
gearbox = Pixel_Gearbox(s)
|
||||||
|
gearboxes["mono"+str(s)] = gearbox
|
||||||
|
self.submodules += gearbox
|
||||||
|
self.sync += gearbox.x_size.eq(header_reader.metadata.x_size),
|
||||||
|
|
||||||
|
# From Table 34 (CXP-001-2021)
|
||||||
|
pix_fmt = {
|
||||||
|
"mono8": 0x0101,
|
||||||
|
"mono10": 0x0102,
|
||||||
|
"mono12": 0x0103,
|
||||||
|
"mono14": 0x0104,
|
||||||
|
"mono16": 0x0105,
|
||||||
|
}
|
||||||
|
|
||||||
|
self.submodules.tracker = tracker = Pixel_Coordinate_Tracker(res_width)
|
||||||
|
self.sync += tracker.y_size.eq(header_reader.metadata.y_size)
|
||||||
|
self.pixel4x = tracker.pixel4x
|
||||||
|
|
||||||
|
# discard unknown pixel format
|
||||||
|
mux_cases = {"default": [eol_inserter.source.ack.eq(1)]}
|
||||||
|
for fmt in pix_fmt:
|
||||||
|
mux_cases[pix_fmt[fmt]] = [
|
||||||
|
eol_inserter.source.connect(gearboxes[fmt].sink),
|
||||||
|
gearboxes[fmt].source.connect(tracker.sink),
|
||||||
|
]
|
||||||
|
|
||||||
|
self.comb += Case(header_reader.metadata.pixel_format, mux_cases)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user