1
0
Fork 0

pipeline GW: remove cxp

pipeline GW: fix data loss when downstream not ack
This commit is contained in:
morgan 2024-11-05 11:59:15 +08:00
parent 3fd7d3d905
commit fbb2089c34
1 changed files with 17 additions and 48 deletions

View File

@ -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)