diff --git a/src/gateware/cxp.py b/src/gateware/cxp.py index b48a033..1891ea6 100644 --- a/src/gateware/cxp.py +++ b/src/gateware/cxp.py @@ -1,16 +1,13 @@ from migen import * from misoc.interconnect.csr import * from misoc.interconnect import stream -from misoc.cores.liteeth_mini.mac.crc import LiteEthMACCRCEngine, LiteEthMACCRC32Inserter from cxp_downconn import CXP_DownConn from cxp_upconn import CXP_UpConn -from cxp_pipeline import Code_Inserter +from cxp_pipeline import Code_Inserter, CXPCRC32Inserter class CXP(Module, AutoCSR): def __init__(self, refclk, downconn_pads, upconn_pads, sys_clk_freq, debug_sma, pmod_pads): - # self.submodules.crc = CXP_CRC(8) - self.submodules.txcore = CXP_TX_Core(pmod_pads) self.submodules.upconn = UpConn_Packets(upconn_pads, sys_clk_freq, debug_sma, pmod_pads) @@ -91,6 +88,7 @@ def cxp_phy_layout(): class CXP_TX_Core(Module, AutoCSR): def __init__(self, pmod_pads): + self.din_len = CSRStorage(6) self.din_pak = CSR(8) self.din_k = CSRStorage() self.din_ready = CSRStatus() @@ -100,21 +98,34 @@ class CXP_TX_Core(Module, AutoCSR): self.kout_pak = CSRStatus() self.dout_valid =CSRStatus() + len = Signal(6, reset=1) + + # TODO: add end of packet (eop) interface for firmware and try out crc_inserters # a buf is used to simulated a proper endpoint which hold source.stb high as long as data is available - # otherwise, CSR.re only hold when CSR is written too and it cannot act as a proper source + # otherwise, CSR.re only hold when CSR is written to and it cannot act as a proper source self.submodules.buf_in = buf_in = stream.SyncFIFO(cxp_phy_layout(), 2) self.submodules.buf_out = buf_out = stream.SyncFIFO(cxp_phy_layout(), 64) self.submodules.pak_start = pak_start = Code_Inserter(*K(27, 7), cxp_phy_layout()) - # self.submodules.crc_inserter = crc_inserters = LiteEthMACCRC32Inserter(CXP_LAYOUT) + self.submodules.crc_inserter = crc_inserters = CXPCRC32Inserter(cxp_phy_layout()) self.sync += [ # input self.din_ready.status.eq(buf_in.sink.ack), - buf_in.sink.stb.eq(self.din_pak.re), - buf_in.sink.data.eq(self.din_pak.r), - buf_in.sink.k.eq(self.din_k.storage), + buf_in.sink.stb.eq(0), + If(self.din_pak.re, + If(len == self.din_len.storage, + len.eq(len.reset), + buf_in.sink.eop.eq(1), + ).Else( + len.eq(len + 1), + buf_in.sink.eop.eq(0), + ), + buf_in.sink.stb.eq(1), + buf_in.sink.data.eq(self.din_pak.r), + buf_in.sink.k.eq(self.din_k.storage), + ), # output buf_out.source.ack.eq(self.inc.re), @@ -124,7 +135,7 @@ class CXP_TX_Core(Module, AutoCSR): ] - tx_pipeline = [ buf_in, pak_start, buf_out] + tx_pipeline = [ buf_in, crc_inserters, buf_out] for s, d in zip(tx_pipeline, tx_pipeline[1:]): self.comb += s.source.connect(d.sink) @@ -143,66 +154,3 @@ class CXP_TX_Core(Module, AutoCSR): Instance("OBUF", i_I=buf_out.source.stb, o_O=pmod_pads[6]), Instance("OBUF", i_I=buf_out.source.ack, o_O=pmod_pads[7]), ] - - - -class CXP_CRC(Module, AutoCSR): - def __init__(self, data_width): - # Section 9.2.2.2 (CXP-001-2021) - crc_width = 32 - polynom = 0x04C11DB7 - seed = 2**crc_width-1 - - self.d = Signal(data_width) - self.stb = Signal() - self.reset = Signal() - self.val = Signal(crc_width, reset=seed) - - - # # # - - self.submodules.engine = LiteEthMACCRCEngine(data_width, crc_width, polynom) - - self.sync += [ - self.val.eq(self.engine.next), - If(self.stb, - self.engine.data.eq(self.d), - - If(self.reset, - # because the seed is non zero, even if the data is 0x00, the engine output will be change :< - self.engine.last.eq(seed), - # clear reset bit - self.reset.eq(0), - ).Else( - self.engine.last.eq(self.val), - ) - ), - ] - - # DEBUG: remove those csr - # TODO: do char bit reverse outside of this submodule - - p0 = Signal(8) - p1 = Signal(8) - p2 = Signal(8) - p3 = Signal(8) - self.comb += [ - p3.eq(self.engine.next[:8][::-1]), - p2.eq(self.engine.next[8:16][::-1]), - p1.eq(self.engine.next[16:24][::-1]), - p0.eq(self.engine.next[24:32][::-1]), - ] - - self.data = CSR(data_width) - self.en = CSR() - self.value = CSRStatus(crc_width) - self.processed = CSRStatus(crc_width) - - self.sync += [ - self.d.eq(self.data.r), - self.stb.eq(self.data.re), - If(self.en.re, self.reset.eq(1)), - - self.value.status.eq(self.engine.next), - self.processed.status.eq(Cat(p3, p2, p1, p0)), - ]