forked from M-Labs/artiq-zynq
pipeline GW: add voter for duplicate char
This commit is contained in:
parent
61df5113a2
commit
24a16a3a5b
|
@ -301,6 +301,25 @@ class RX_Debug_Buffer(Module,AutoCSR):
|
|||
self.dout_valid.status.eq(buf_out.source.stb),
|
||||
]
|
||||
|
||||
class Duplicate_Majority_Voter(Module):
|
||||
def __init__(self, data, k):
|
||||
assert data.nbits == 32
|
||||
assert k.nbits == 4
|
||||
|
||||
# Section 9.2.2.1 (CXP-001-2021)
|
||||
# decoder should immune to single bit errors when handling duplicated characters
|
||||
self.char = Signal(char_width)
|
||||
self.k = Signal()
|
||||
|
||||
a, a_k = data[:8], k[0]
|
||||
b, b_k = data[8:16], k[1]
|
||||
c, c_k = data[16:24], k[2]
|
||||
d, d_k = data[24:], k[3]
|
||||
self.comb += [
|
||||
self.char.eq(a&b&c | a&b&d | a&c&d | b&c&d),
|
||||
self.k.eq(a_k&b_k&c_k | a_k&b_k&d_k | a_k&c_k&d_k | b_k&c_k&d_k),
|
||||
]
|
||||
|
||||
@FullMemoryWE()
|
||||
class CXP_Data_Packet_Decode(Module):
|
||||
def __init__(self):
|
||||
|
@ -313,7 +332,6 @@ class CXP_Data_Packet_Decode(Module):
|
|||
|
||||
# DEBUG: remove debug
|
||||
# TODO: decode all packet type here
|
||||
# TODO: data&event -> memory
|
||||
# TODO: heartbeat
|
||||
type = {
|
||||
"data_stream": 0x01,
|
||||
|
@ -331,10 +349,23 @@ class CXP_Data_Packet_Decode(Module):
|
|||
|
||||
self.submodules.fsm = fsm = FSM(reset_state="IDLE")
|
||||
|
||||
self.submodules.voter = voter = Duplicate_Majority_Voter(self.sink.data, self.sink.k)
|
||||
|
||||
# # Section 9.2.2.1 (CXP-001-2021)
|
||||
# # decoder should immune to single bit errors when handling duplicated characters
|
||||
# char_majority = Signal(char_width)
|
||||
# k_majority = Signal()
|
||||
# a, b, c, d = self.sink.data[:8], self.sink.data[8:16], self.sink.data[16:24], self.sink.data[24:]
|
||||
# a_k, b_k, c_k, d_k = self.sink.k[0], self.sink.k[1], self.sink.k[2], self.sink.k[3]
|
||||
# self.comb += [
|
||||
# char_majority.eq(a&b&c | a&b&d | a&c&d | b&c&d),
|
||||
# k_majority.eq(a_k&b_k&c_k | a_k&b_k&d_k | a_k&c_k&d_k | b_k&c_k&d_k),
|
||||
# ]
|
||||
|
||||
|
||||
fsm.act("IDLE",
|
||||
self.sink.ack.eq(1),
|
||||
# TODO: add error correction?
|
||||
If((self.sink.stb & (self.sink.data == Replicate(KCode["pak_start"], 4)) & (self.sink.k == 0b1111)),
|
||||
If((self.sink.stb & (voter.char == KCode["pak_start"]) & (voter.k == 1)),
|
||||
NextState("DECODE"),
|
||||
)
|
||||
)
|
||||
|
@ -345,9 +376,9 @@ class CXP_Data_Packet_Decode(Module):
|
|||
fsm.act("DECODE",
|
||||
self.sink.ack.eq(1),
|
||||
If(self.sink.stb,
|
||||
NextValue(self.packet_type, self.sink.data[:8]),
|
||||
NextValue(self.packet_type, voter.char),
|
||||
|
||||
Case(self.sink.data[:8],{
|
||||
Case(voter.char, {
|
||||
type["data_stream"]: NextState("STREAMING"),
|
||||
type["control_ack_no_tag"]:[
|
||||
NextValue(addr, addr.reset),
|
||||
|
@ -384,7 +415,7 @@ class CXP_Data_Packet_Decode(Module):
|
|||
fsm.act("VERIFY_TEST_PATTERN",
|
||||
self.sink.ack.eq(1),
|
||||
If(self.sink.stb,
|
||||
If(((self.sink.data == Replicate(KCode["pak_end"], 4)) & (self.sink.k == 0b1111)),
|
||||
If(((voter.char == KCode["pak_end"]) & (voter.k == 1)),
|
||||
NextState("IDLE"),
|
||||
).Else(
|
||||
If(((self.sink.data != Cat(cnt, cnt+1, cnt+2, cnt+3))),
|
||||
|
@ -402,7 +433,7 @@ class CXP_Data_Packet_Decode(Module):
|
|||
|
||||
# For stream data packet
|
||||
fsm.act("STREAMING",
|
||||
If((self.sink.stb & (self.sink.data == Replicate(KCode["pak_end"], 4)) & (self.sink.k == 0b1111)),
|
||||
If((self.sink.stb & (voter.char == KCode["pak_end"]) & (voter.k == 1)),
|
||||
# discard K29,7
|
||||
self.sink.ack.eq(1),
|
||||
NextState("IDLE")
|
||||
|
@ -429,7 +460,7 @@ class CXP_Data_Packet_Decode(Module):
|
|||
mem_port.we.eq(0),
|
||||
self.sink.ack.eq(1),
|
||||
If(self.sink.stb,
|
||||
If(((self.sink.data == Replicate(KCode["pak_end"], 4)) & (self.sink.k == 0b1111)),
|
||||
If(((voter.char == KCode["pak_end"]) & (voter.k == 1)),
|
||||
NextState("MOVE_BUFFER_PTR"),
|
||||
).Else(
|
||||
mem_port.we.eq(1),
|
||||
|
@ -468,8 +499,10 @@ class CXP_Trig_Ack_Checker(Module, AutoCSR):
|
|||
|
||||
self.submodules.fsm = fsm = FSM(reset_state="COPY")
|
||||
|
||||
self.submodules.voter = voter = Duplicate_Majority_Voter(self.sink.data, self.sink.k)
|
||||
|
||||
fsm.act("COPY",
|
||||
If((self.sink.stb & (self.sink.data == Replicate(KCode["io_ack"], 4)) & (self.sink.k == 0b1111)),
|
||||
If((self.sink.stb & (voter.char == KCode["io_ack"]) & (voter.k == 1)),
|
||||
# discard K28,6
|
||||
self.sink.ack.eq(1),
|
||||
NextState("CHECK_ACK")
|
||||
|
@ -483,7 +516,7 @@ class CXP_Trig_Ack_Checker(Module, AutoCSR):
|
|||
NextState("COPY"),
|
||||
# discard the word after K28,6
|
||||
self.sink.ack.eq(1),
|
||||
If(self.sink.data == Replicate(C(0x01, char_width), 4),
|
||||
If((voter.char == 0x01) & (voter.k == 0),
|
||||
self.ack.eq(1),
|
||||
)
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue