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),
|
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()
|
@FullMemoryWE()
|
||||||
class CXP_Data_Packet_Decode(Module):
|
class CXP_Data_Packet_Decode(Module):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
@ -313,7 +332,6 @@ class CXP_Data_Packet_Decode(Module):
|
||||||
|
|
||||||
# DEBUG: remove debug
|
# DEBUG: remove debug
|
||||||
# TODO: decode all packet type here
|
# TODO: decode all packet type here
|
||||||
# TODO: data&event -> memory
|
|
||||||
# TODO: heartbeat
|
# TODO: heartbeat
|
||||||
type = {
|
type = {
|
||||||
"data_stream": 0x01,
|
"data_stream": 0x01,
|
||||||
|
@ -331,10 +349,23 @@ class CXP_Data_Packet_Decode(Module):
|
||||||
|
|
||||||
self.submodules.fsm = fsm = FSM(reset_state="IDLE")
|
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",
|
fsm.act("IDLE",
|
||||||
self.sink.ack.eq(1),
|
self.sink.ack.eq(1),
|
||||||
# TODO: add error correction?
|
If((self.sink.stb & (voter.char == KCode["pak_start"]) & (voter.k == 1)),
|
||||||
If((self.sink.stb & (self.sink.data == Replicate(KCode["pak_start"], 4)) & (self.sink.k == 0b1111)),
|
|
||||||
NextState("DECODE"),
|
NextState("DECODE"),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -345,9 +376,9 @@ class CXP_Data_Packet_Decode(Module):
|
||||||
fsm.act("DECODE",
|
fsm.act("DECODE",
|
||||||
self.sink.ack.eq(1),
|
self.sink.ack.eq(1),
|
||||||
If(self.sink.stb,
|
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["data_stream"]: NextState("STREAMING"),
|
||||||
type["control_ack_no_tag"]:[
|
type["control_ack_no_tag"]:[
|
||||||
NextValue(addr, addr.reset),
|
NextValue(addr, addr.reset),
|
||||||
|
@ -384,7 +415,7 @@ class CXP_Data_Packet_Decode(Module):
|
||||||
fsm.act("VERIFY_TEST_PATTERN",
|
fsm.act("VERIFY_TEST_PATTERN",
|
||||||
self.sink.ack.eq(1),
|
self.sink.ack.eq(1),
|
||||||
If(self.sink.stb,
|
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"),
|
NextState("IDLE"),
|
||||||
).Else(
|
).Else(
|
||||||
If(((self.sink.data != Cat(cnt, cnt+1, cnt+2, cnt+3))),
|
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
|
# For stream data packet
|
||||||
fsm.act("STREAMING",
|
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
|
# discard K29,7
|
||||||
self.sink.ack.eq(1),
|
self.sink.ack.eq(1),
|
||||||
NextState("IDLE")
|
NextState("IDLE")
|
||||||
|
@ -429,7 +460,7 @@ class CXP_Data_Packet_Decode(Module):
|
||||||
mem_port.we.eq(0),
|
mem_port.we.eq(0),
|
||||||
self.sink.ack.eq(1),
|
self.sink.ack.eq(1),
|
||||||
If(self.sink.stb,
|
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"),
|
NextState("MOVE_BUFFER_PTR"),
|
||||||
).Else(
|
).Else(
|
||||||
mem_port.we.eq(1),
|
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.fsm = fsm = FSM(reset_state="COPY")
|
||||||
|
|
||||||
|
self.submodules.voter = voter = Duplicate_Majority_Voter(self.sink.data, self.sink.k)
|
||||||
|
|
||||||
fsm.act("COPY",
|
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
|
# discard K28,6
|
||||||
self.sink.ack.eq(1),
|
self.sink.ack.eq(1),
|
||||||
NextState("CHECK_ACK")
|
NextState("CHECK_ACK")
|
||||||
|
@ -483,7 +516,7 @@ class CXP_Trig_Ack_Checker(Module, AutoCSR):
|
||||||
NextState("COPY"),
|
NextState("COPY"),
|
||||||
# discard the word after K28,6
|
# discard the word after K28,6
|
||||||
self.sink.ack.eq(1),
|
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),
|
self.ack.eq(1),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in New Issue