From a363f50357135499f13802c46173a118cebccc2f Mon Sep 17 00:00:00 2001 From: morgan Date: Thu, 23 Jan 2025 13:12:31 +0800 Subject: [PATCH] pipeline GW: refactor test seq pipeline GW: refactor test seq pipeline gw: reader clenaup pipeline GW: fix issue pipeline GW: cleanup --- src/gateware/cxp_pipeline.py | 108 +++++++++++++---------------------- 1 file changed, 40 insertions(+), 68 deletions(-) diff --git a/src/gateware/cxp_pipeline.py b/src/gateware/cxp_pipeline.py index e07dc06..31d12b1 100644 --- a/src/gateware/cxp_pipeline.py +++ b/src/gateware/cxp_pipeline.py @@ -364,14 +364,14 @@ class Duplicated_Char_Decoder(Module): @FullMemoryWE() class Control_Packet_Reader(Module): def __init__(self, buffer_depth, nslot): - self.packet_type = Signal(8) - self.decode_err = Signal() - self.buffer_err = Signal() + self.test_err = Signal() + self.test_pak = Signal() + + self.buffer_err = Signal() + self.write_ptr = Signal(log2_int(nslot)) + self.read_ptr = Signal.like(self.write_ptr) - self.test_err_cnt = Signal(16) - self.test_pak_cnt = Signal(16) - self.test_cnt_reset = Signal() # # # type = { @@ -387,37 +387,44 @@ class Control_Packet_Reader(Module): self.source = stream.Endpoint(word_layout_dchar) # N buffers for firmware to read packet from + self.specials.mem = mem = Memory(word_width, nslot*buffer_depth) self.specials.mem_port = mem_port = mem.get_port(write_capable=True) + buf_mem_we = Signal.like(mem_port.we) + buf_mem_dat_w = Signal.like(mem_port.dat_w) + buf_mem_adr = Signal.like(mem_port.adr) - - # Data packet parser - - self.submodules.fsm = fsm = FSM(reset_state="IDLE") + # buffered mem_port to improve timing + self.sync += [ + mem_port.we.eq(buf_mem_we), + mem_port.dat_w.eq(buf_mem_dat_w), + mem_port.adr.eq(buf_mem_adr) + ] addr_nbits = log2_int(buffer_depth) addr = Signal(addr_nbits) - cnt = Signal(max=0x100) + self.comb += [ + buf_mem_adr[:addr_nbits].eq(addr), + buf_mem_adr[addr_nbits:].eq(self.write_ptr), + ] + + # Data packet parser + self.submodules.fsm = fsm = FSM(reset_state="IDLE") + fsm.act("IDLE", - NextValue(addr, addr.reset), - NextValue(cnt, cnt.reset), self.sink.ack.eq(1), If((self.sink.stb & (self.sink.dchar == KCode["pak_start"]) & (self.sink.dchar_k == 1)), NextState("DECODE"), ) ) - test_pak = Signal() - buf_mem_we = Signal.like(mem_port.we) - buf_mem_dat_w = Signal.like(mem_port.dat_w) - buf_mem_adr = Signal.like(mem_port.adr) fsm.act("DECODE", self.sink.ack.eq(1), If(self.sink.stb, Case(self.sink.dchar, { type["data_stream"]: NextState("STREAMING"), type["test_packet"]: [ - test_pak.eq(1), + self.test_pak.eq(1), NextState("VERIFY_TEST_PATTERN"), ], type["control_ack_no_tag"]:[ @@ -463,64 +470,28 @@ class Control_Packet_Reader(Module): # Section 9.9.1 (CXP-001-2021) # the received test data packet (0x00, 0x01 ... 0xFF) # need to be compared against the local test sequence generator - # TODO: improve this to avoid tight setup/hold time - test_err = Signal() + cnt_bytes = [Signal(char_width, reset=i) for i in range(4)] fsm.act("VERIFY_TEST_PATTERN", self.sink.ack.eq(1), If(self.sink.stb, If(((self.sink.dchar == KCode["pak_end"]) & (self.sink.dchar_k == 1)), + [NextValue(cnt, cnt.reset) for cnt in cnt_bytes], NextState("IDLE"), ).Else( - If(self.sink.data[:8] != cnt, - test_err.eq(1), - ).Elif(self.sink.data[8:16] != cnt + 1, - test_err.eq(1), - ).Elif(self.sink.data[16:24] != cnt + 2, - test_err.eq(1), - ).Elif(self.sink.data[24:] != cnt + 3, - test_err.eq(1), - ), - - If(cnt == 0xFC, - NextValue(cnt, cnt.reset), - ).Else( - NextValue(cnt, cnt + 4) - ) + [ + If(self.sink.data[8 * i : 8 * (i + 1)] != cnt, + self.test_err.eq(1), + ), + If(cnt == 0xFC + i, + NextValue(cnt, cnt.reset), + ).Else(NextValue(cnt, cnt + 4)), + ] + for i, cnt in enumerate(cnt_bytes) ) ) ) - # TODO: move this out of this module - self.sync += [ - If(self.test_cnt_reset, - self.test_err_cnt.eq(self.test_err_cnt.reset), - ).Elif(test_err, - self.test_err_cnt.eq(self.test_err_cnt + 1), - ), - If(self.test_cnt_reset, - self.test_pak_cnt.eq(self.test_pak_cnt.reset), - ).Elif(test_pak, - self.test_pak_cnt.eq(self.test_pak_cnt + 1), - ) - ] - - # buffered mem_port to improve timing - self.sync += [ - mem_port.we.eq(buf_mem_we), - mem_port.dat_w.eq(buf_mem_dat_w), - mem_port.adr.eq(buf_mem_adr) - ] - - # TODO: move write_ptr_sys out of this module - write_ptr = Signal(log2_int(nslot)) - self.write_ptr_sys = Signal.like(write_ptr) - self.specials += MultiReg(write_ptr, self.write_ptr_sys), - - self.comb += [ - buf_mem_adr[:addr_nbits].eq(addr), - buf_mem_adr[addr_nbits:].eq(write_ptr), - ] fsm.act("LOAD_BUFFER", buf_mem_we.eq(0), @@ -535,21 +506,22 @@ class Control_Packet_Reader(Module): If(addr == buffer_depth - 1, # discard the packet self.buffer_err.eq(1), + NextValue(addr, addr.reset), NextState("IDLE"), ) ) ) ) - self.read_ptr_rx = Signal.like(write_ptr) fsm.act("MOVE_BUFFER_PTR", self.sink.ack.eq(0), - If(write_ptr + 1 == self.read_ptr_rx, + If(self.write_ptr + 1 == self.read_ptr, # if next one hasn't been read, overwrite the current buffer when new packet comes in self.buffer_err.eq(1), ).Else( - NextValue(write_ptr, write_ptr + 1), + NextValue(self.write_ptr, self.write_ptr + 1), ), + NextValue(addr, addr.reset), NextState("IDLE"), )