From 9ffa83e7977c3664b63660e5126c61a3588f472d Mon Sep 17 00:00:00 2001 From: morgan Date: Fri, 20 Sep 2024 12:43:16 +0800 Subject: [PATCH] pipeline GW: add KCode Dict & add a decode example --- src/gateware/cxp_pipeline.py | 63 +++++++++++++++++++++++++++++++++--- 1 file changed, 58 insertions(+), 5 deletions(-) diff --git a/src/gateware/cxp_pipeline.py b/src/gateware/cxp_pipeline.py index bd9e36c..e153ed2 100644 --- a/src/gateware/cxp_pipeline.py +++ b/src/gateware/cxp_pipeline.py @@ -13,7 +13,16 @@ downconn_layout = [("data", downconn_dw), ("k", downconn_dw//8)] def K(x, y): return ((y << 5) | x) -def bytes2word(arr): +KCode = { + "pak_start" : K(27, 7), + "io_ack" : K(28, 6), + "trig_indic_28_2" : K(28, 2), + "trig_indic_28_4" : K(28, 4), + "pak_end" : K(29, 7), +} + + +def _bytes2word(arr): assert len(arr) == 4 sum = 0 for i, val in enumerate(arr): @@ -386,7 +395,7 @@ class Receiver_Path(Module, AutoCSR): self.submodules.trig_ack_checker = trig_ack_checker = CXP_Trig_Ack_Checker() - self.submodules.packet_decoder= packet_decoder = CXP_Data_Packet_Decode() + self.submodules.packet_decoder = packet_decoder = CXP_Data_Packet_Decode() self.sync += [ If(trig_ack_checker.ack, self.trig_ack.eq(1), @@ -412,11 +421,55 @@ class CXP_Data_Packet_Decode(Module): # This is where data stream comes out self.source = stream.Endpoint(downconn_layout) + self.packet_type = Signal(8) + self.decode_err = Signal() + # # # - self.comb += self.sink.connect(self.source) + # decoder -> priorities mux(normal packet vs trigger ack) -> data packet mux (control ack, data stream, heartbeat, testmode, (optional Genlcam event)) + type = { + "data_stream": 0x01, + "control_ack_no_tag": 0x03, + "test_packet": 0x04, + "control_ack_with_tag": 0x06, + "event_ack": 0x08, + "heartbeat": 0x09, + "debug" : 0x02, + } + self.submodules.fsm = fsm = FSM(reset_state="IDLE") + + fsm.act("IDLE", + self.sink.ack.eq(1), + # TODO: add error correction? + If((self.sink.stb & (self.sink.data == _bytes2word([KCode["pak_start"]]*4)) & (self.sink.k == 0b1111)), + NextState("DECODE_PAK"), + ) + ) + + # TODO: decode packet type here + fsm.act("DECODE_PAK", + self.sink.ack.eq(1), + If(self.sink.stb, + NextValue(self.packet_type, self.sink.data[:8]), + NextState("STREAMING"), + ) + ) + + fsm.act("STREAMING", + If((self.sink.stb & (self.sink.data == _bytes2word([KCode["pak_end"]]*4)) & (self.sink.k == 0b1111)), + # discard K29,7 + self.sink.ack.eq(1), + NextState("IDLE") + ).Elif(self.packet_type == type["debug"], + self.sink.connect(self.source), + ).Else( + # discard K29,7 + self.sink.ack.eq(1), + NextValue(self.decode_err, 1), + ) + ) class CXP_Trig_Ack_Checker(Module, AutoCSR): def __init__(self): self.sink = stream.Endpoint(downconn_layout) @@ -437,7 +490,7 @@ class CXP_Trig_Ack_Checker(Module, AutoCSR): ) fsm.act("COPY", - If((self.sink.stb & (self.sink.data == bytes2word([K(28, 6)]*4)) & (self.sink.k == 0b1111)), + If((self.sink.stb & (self.sink.data == _bytes2word([KCode["io_ack"]]*4)) & (self.sink.k == 0b1111)), # discard K28,6 self.sink.ack.eq(1), NextState("CHECK_ACK") @@ -451,7 +504,7 @@ class CXP_Trig_Ack_Checker(Module, AutoCSR): NextState("IDLE"), # discard the word after K28,6 self.sink.ack.eq(1), - If(self.sink.data == bytes2word([0x01]*4), + If(self.sink.data == _bytes2word([0x01]*4), self.ack.eq(1), ) )