diff --git a/src/gateware/cxp_pipeline.py b/src/gateware/cxp_pipeline.py index b0f7adc..42dc05b 100644 --- a/src/gateware/cxp_pipeline.py +++ b/src/gateware/cxp_pipeline.py @@ -2,7 +2,6 @@ from migen import * from migen.genlib.cdc import MultiReg from misoc.interconnect.csr import * from misoc.interconnect import stream -from misoc.cores.liteeth_mini.mac.crc import LiteEthMACCRCEngine, LiteEthMACCRCChecker from functools import reduce from itertools import combinations @@ -291,7 +290,6 @@ class RX_Debug_Buffer(Module,AutoCSR): class Duplicated_Char_Decoder(Module): def __init__(self): self.sink = stream.Endpoint(word_layout) - self.buffer = stream.Endpoint(word_layout) 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. # 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.sink.ack.eq(self.buffer.ack), - self.buffer.stb.eq(self.sink.stb), - If(self.sink.stb, - self.buffer.data.eq(self.sink.data), - self.buffer.k.eq(self.sink.k), - ), + If((~buffer.stb | buffer.ack), + buffer.stb.eq(self.sink.stb), + buffer.payload.eq(self.sink.payload), + ) ] - - # cycle 1 - calculate ABC, ABD, ACD & BCD + self.comb += self.sink.ack.eq(~buffer.stb | buffer.ack) + + # calculate ABC, ABD, ACD, BCD 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)] for i, comb in enumerate(combinations(char, 3)): 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].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 self.sync += [ - self.buffer.ack.eq(self.source.ack), - self.source.stb.eq(self.buffer.stb), - If(self.buffer.stb, - self.source.data.eq(self.buffer.data), - self.source.k.eq(self.buffer.k), + If((~self.source.stb | self.source.ack), + self.source.stb.eq(buffer.stb), + self.source.data.eq(buffer.data), + self.source.k.eq(buffer.k), 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.comb += buffer.ack.eq(~self.source.stb | self.source.ack) + @FullMemoryWE() 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)