diff --git a/src/gateware/cxp_frame_pipeline.py b/src/gateware/cxp_frame_pipeline.py index 74bce1c..02aa8ad 100644 --- a/src/gateware/cxp_frame_pipeline.py +++ b/src/gateware/cxp_frame_pipeline.py @@ -21,19 +21,17 @@ pixel4x_layout = [ ("data", pixel_width*4), ("valid", 4), ] +pixeldata_layout = [("data", word_width)] # pixel data don't need k code -# TODO: rename this to signalify eol marker & kcode/other data dropper -class End_Of_Line_Marker(Module): +class End_of_line_Marker(Module): """ Repurpose eop to indicate end of line - And drop the K codes and Duplicate char - """ def __init__(self): self.l_size = Signal(3*char_width) - self.sink = Endpoint(word_layout_dchar) - self.source = Endpoint([("data", word_width)]) # pixel data don't need k code + self.sink = Endpoint(pixeldata_layout) + self.source = Endpoint(pixeldata_layout) # # # @@ -46,7 +44,7 @@ class End_Of_Line_Marker(Module): cnt = Signal.like(self.l_size, reset=1) self.sync += [ If((~self.source.stb | self.source.ack), - self.sink.connect(self.source, omit={"ack", "eop", "k", "dchar", "dchar_k"}), + self.sink.connect(self.source, omit={"ack", "eop"}), If(self.sink.stb, If(cnt == 1, cnt.eq(self.l_size) @@ -127,9 +125,8 @@ class CXPCRC32(Module): ] class CXPCRC32_Checker(Module): - """Verify crc in stream data packet""" + """Verify crc in stream packet""" def __init__(self): - # TODO: handle the error into a counter self.error = Signal() self.sink = Endpoint(word_layout_dchar) @@ -267,7 +264,7 @@ class Stream_Broadcaster(Module): class Frame_Header_Reader(Module): """ - Extract the frame header information + Extract the frame header information and pass pixel data downstream """ def __init__(self): self.decode_err = Signal() @@ -291,11 +288,11 @@ class Frame_Header_Reader(Module): ] assert layout_len(img_header_layout) == n_metadata_chars*char_width + self.sink = Endpoint(word_layout_dchar) + self.source = Endpoint(pixeldata_layout) # # # - self.sink = Endpoint(word_layout_dchar) - self.source = Endpoint(word_layout_dchar) self.submodules.fsm = fsm = FSM(reset_state="IDLE") @@ -312,7 +309,7 @@ class Frame_Header_Reader(Module): self.sink.ack.eq(1), NextState("DECODE"), ).Else( - self.sink.connect(self.source), + self.sink.connect(self.source, omit={"k", "dchar", "dchar_k"}), ) ) @@ -370,7 +367,7 @@ class Frame_Header_Reader(Module): setattr(self.metadata, name, switch_endianness(packet_buffer[idx:idx+size])) idx += size -class Pixel_Gearbox(Module): +class Pixel_Unpacker(Module): """Convert 32 bits word into 4x pixel""" def __init__(self, size): assert size <= pixel_width @@ -378,12 +375,12 @@ class Pixel_Gearbox(Module): self.x_size = Signal(3*char_width) - sink_dw, source_dw = word_width, size*4 - self.sink = Endpoint([("data", sink_dw)]) + self.sink = Endpoint(pixeldata_layout) self.source = Endpoint(pixel4x_layout) # # # + sink_dw, source_dw = layout_len(pixeldata_layout), size*4 ring_buf_size = lcm(sink_dw, source_dw) # ensure the shift register is at least twice the size of sink/source dw if (ring_buf_size//sink_dw) < 2: @@ -831,14 +828,14 @@ class Pixel_Parser(Module): # inserter Tracker w/ coord # - self.submodules.eol_inserter = eol_inserter = End_Of_Line_Marker() + self.submodules.eol_inserter = eol_inserter = End_of_line_Marker() self.sync += eol_inserter.l_size.eq(self.l_size) self.sink = eol_inserter.sink gearboxes = {} for s in [8, 10, 12, 14, 16]: - gearbox = Pixel_Gearbox(s) + gearbox = Pixel_Unpacker(s) gearboxes["mono"+str(s)] = gearbox self.submodules += gearbox self.sync += gearbox.x_size.eq(self.x_size), @@ -921,36 +918,33 @@ class Stream2Pixel4x_Converter(Module): """ 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 - # + # + # 32+8(dchar) 32 4x pixel + # sink ────/────> crc checker ─────> frame header ───/───> eol inserter ─────> 8, 10, 12, 14, 16 bits ───/───> pixel coordinate ─────> 4x pixel with + # reader pixel unpacker tracker coordinate + # 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.submodules.formatter = formatter = End_of_line_Marker() + self.sync += formatter.l_size.eq(header_reader.metadata.l_size) + self.sink = formatter.sink - self.pipeline = [crc_checker, header_reader, eol_inserter] + self.pipeline = [crc_checker, header_reader, formatter] for s, d in zip(self.pipeline, self.pipeline[1:]): self.comb += s.source.connect(d.sink) self.sink = self.pipeline[0].sink - gearboxes = {} + unpackers = {} 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), + unpacker = Pixel_Unpacker(s) + unpackers["mono"+str(s)] = unpacker + self.submodules += unpacker + self.sync += unpacker.x_size.eq(header_reader.metadata.x_size), # From Table 34 (CXP-001-2021) pix_fmt = { @@ -966,11 +960,11 @@ class Stream2Pixel4x_Converter(Module): self.pixel4x = tracker.pixel4x # discard unknown pixel format - mux_cases = {"default": [eol_inserter.source.ack.eq(1)]} + mux_cases = {"default": [formatter.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), + formatter.source.connect(unpackers[fmt].sink), + unpackers[fmt].source.connect(tracker.sink), ] self.comb += Case(header_reader.metadata.pixel_format, mux_cases)