forked from M-Labs/artiq-zynq
pipeline GW: remove cxp
pipeline GW: fix data loss when downstream not ack
This commit is contained in:
parent
3fd7d3d905
commit
fbb2089c34
|
@ -2,7 +2,6 @@ from migen import *
|
||||||
from migen.genlib.cdc import MultiReg
|
from migen.genlib.cdc import MultiReg
|
||||||
from misoc.interconnect.csr import *
|
from misoc.interconnect.csr import *
|
||||||
from misoc.interconnect import stream
|
from misoc.interconnect import stream
|
||||||
from misoc.cores.liteeth_mini.mac.crc import LiteEthMACCRCEngine, LiteEthMACCRCChecker
|
|
||||||
|
|
||||||
from functools import reduce
|
from functools import reduce
|
||||||
from itertools import combinations
|
from itertools import combinations
|
||||||
|
@ -291,7 +290,6 @@ class RX_Debug_Buffer(Module,AutoCSR):
|
||||||
class Duplicated_Char_Decoder(Module):
|
class Duplicated_Char_Decoder(Module):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.sink = stream.Endpoint(word_layout)
|
self.sink = stream.Endpoint(word_layout)
|
||||||
self.buffer = stream.Endpoint(word_layout)
|
|
||||||
self.source = stream.Endpoint(word_layout_dchar)
|
self.source = stream.Endpoint(word_layout_dchar)
|
||||||
|
|
||||||
# # #
|
# # #
|
||||||
|
@ -314,22 +312,23 @@ class Duplicated_Char_Decoder(Module):
|
||||||
# Hence, a pipeline approach is needed to avoid any s/h violation, where the majority voting result are pre-calculate and injected into the bus immediate after the PHY.
|
# Hence, a pipeline approach is needed to avoid any s/h violation, where the majority voting result are pre-calculate and injected into the bus immediate after the PHY.
|
||||||
# And any downstream modules can access the voting result without implementing the voting logic inside the decoder
|
# And any downstream modules can access the voting result without implementing the voting logic inside the decoder
|
||||||
|
|
||||||
|
# cycle 1 - buffer data & calculate intermediate result
|
||||||
|
buffer = stream.Endpoint(word_layout)
|
||||||
self.sync += [
|
self.sync += [
|
||||||
self.sink.ack.eq(self.buffer.ack),
|
If((~buffer.stb | buffer.ack),
|
||||||
self.buffer.stb.eq(self.sink.stb),
|
buffer.stb.eq(self.sink.stb),
|
||||||
If(self.sink.stb,
|
buffer.payload.eq(self.sink.payload),
|
||||||
self.buffer.data.eq(self.sink.data),
|
)
|
||||||
self.buffer.k.eq(self.sink.k),
|
|
||||||
),
|
|
||||||
]
|
]
|
||||||
|
self.comb += self.sink.ack.eq(~buffer.stb | buffer.ack)
|
||||||
|
|
||||||
# cycle 1 - calculate ABC, ABD, ACD & BCD
|
# calculate ABC, ABD, ACD, BCD
|
||||||
char = [[self.sink.data[i*8:(i+1)*8], self.sink.k[i]] for i in range(4)]
|
char = [[self.sink.data[i*8:(i+1)*8], self.sink.k[i]] for i in range(4)]
|
||||||
voters = [Record([("data", 8), ("k", 1)]) for _ in range(4)]
|
voters = [Record([("data", 8), ("k", 1)]) for _ in range(4)]
|
||||||
|
|
||||||
for i, comb in enumerate(combinations(char, 3)):
|
for i, comb in enumerate(combinations(char, 3)):
|
||||||
self.sync += [
|
self.sync += [
|
||||||
If(self.sink.stb,
|
If((~buffer.stb | buffer.ack),
|
||||||
voters[i].data.eq(reduce(and_, [code[0] for code in comb])),
|
voters[i].data.eq(reduce(and_, [code[0] for code in comb])),
|
||||||
voters[i].k.eq(reduce(and_, [code[1] for code in comb])),
|
voters[i].k.eq(reduce(and_, [code[1] for code in comb])),
|
||||||
)
|
)
|
||||||
|
@ -338,15 +337,16 @@ class Duplicated_Char_Decoder(Module):
|
||||||
|
|
||||||
# cycle 2 - inject the voting result
|
# cycle 2 - inject the voting result
|
||||||
self.sync += [
|
self.sync += [
|
||||||
self.buffer.ack.eq(self.source.ack),
|
If((~self.source.stb | self.source.ack),
|
||||||
self.source.stb.eq(self.buffer.stb),
|
self.source.stb.eq(buffer.stb),
|
||||||
If(self.buffer.stb,
|
self.source.data.eq(buffer.data),
|
||||||
self.source.data.eq(self.buffer.data),
|
self.source.k.eq(buffer.k),
|
||||||
self.source.k.eq(self.buffer.k),
|
|
||||||
self.source.dchar.eq(Replicate(reduce(or_, [v.data for v in voters]), 4)),
|
self.source.dchar.eq(Replicate(reduce(or_, [v.data for v in voters]), 4)),
|
||||||
self.source.dchar_k.eq(Replicate(reduce(or_, [v.k for v in voters]), 4)),
|
self.source.dchar_k.eq(Replicate(reduce(or_, [v.k for v in voters]), 4)),
|
||||||
),
|
)
|
||||||
]
|
]
|
||||||
|
self.comb += buffer.ack.eq(~self.source.stb | self.source.ack)
|
||||||
|
|
||||||
|
|
||||||
@FullMemoryWE()
|
@FullMemoryWE()
|
||||||
class RX_Bootstrap(Module):
|
class RX_Bootstrap(Module):
|
||||||
|
@ -523,34 +523,3 @@ class Trigger_Ack_Checker(Module, AutoCSR):
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@ResetInserter()
|
|
||||||
@CEInserter()
|
|
||||||
class CXPCRC32(Module):
|
|
||||||
# Section 9.2.2.2 (CXP-001-2021)
|
|
||||||
width = 32
|
|
||||||
polynom = 0x04C11DB7
|
|
||||||
seed = 2**width-1
|
|
||||||
check = 0x00000000
|
|
||||||
def __init__(self, data_width):
|
|
||||||
self.data = Signal(data_width)
|
|
||||||
self.value = Signal(self.width)
|
|
||||||
self.error = Signal()
|
|
||||||
|
|
||||||
# # #
|
|
||||||
|
|
||||||
self.submodules.engine = LiteEthMACCRCEngine(data_width, self.width, self.polynom)
|
|
||||||
reg = Signal(self.width, reset=self.seed)
|
|
||||||
self.sync += reg.eq(self.engine.next)
|
|
||||||
self.comb += [
|
|
||||||
self.engine.data.eq(self.data),
|
|
||||||
self.engine.last.eq(reg),
|
|
||||||
|
|
||||||
self.value.eq(reg[::-1]),
|
|
||||||
self.error.eq(self.engine.next != self.check)
|
|
||||||
]
|
|
||||||
|
|
||||||
# For verifying crc in stream data packet
|
|
||||||
class CXPCRC32Checker(LiteEthMACCRCChecker):
|
|
||||||
def __init__(self, layout):
|
|
||||||
LiteEthMACCRCChecker.__init__(self, CXPCRC32, layout)
|
|
||||||
|
|
Loading…
Reference in New Issue