forked from M-Labs/artiq-zynq
pipeline GW: add KCode Dict & add a decode example
This commit is contained in:
parent
67f25f500a
commit
9ffa83e797
|
@ -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),
|
||||
)
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue