diff --git a/src/gateware/cxp.py b/src/gateware/cxp.py index f5fb47c..b48a033 100644 --- a/src/gateware/cxp.py +++ b/src/gateware/cxp.py @@ -1,14 +1,17 @@ from migen import * from misoc.interconnect.csr import * from misoc.interconnect import stream -from misoc.cores.liteeth_mini.mac.crc import LiteEthMACCRCEngine +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 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.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) @@ -33,7 +36,7 @@ class UpConn_Packets(Module, AutoCSR): # # # - self.submodules.upconn = upconn = CXP_UpConn(upconn_pads, sys_clk_freq, debug_sma, pmod_pads, fifos_depth) + self.submodules.upconn = upconn = CXP_UpConn(upconn_pads, sys_clk_freq, debug_sma, pmod_pads, cxp_phy_layout(), fifos_depth) self.comb += [ upconn.bitrate2x_enable.eq(self.bitrate2x_enable.storage), @@ -75,9 +78,72 @@ class UpConn_Packets(Module, AutoCSR): upconn.tx_fifos.sink_k[2].eq(self.symbol2.r[8]), ] -class CXP_Packet(Module): - def __init__(self, max_packet_length): - pass +# TODO: put these stuff properly instead of declaring everytime +def K(x, y): + return [((y << 5) | x), 1] + +def D(x, y): + return [((y << 5) | x), 0] + +def cxp_phy_layout(): + return [("data", 8), ("k", 1)] + +class CXP_TX_Core(Module, AutoCSR): + def __init__(self, pmod_pads): + + self.din_pak = CSR(8) + self.din_k = CSRStorage() + self.din_ready = CSRStatus() + + self.inc = CSR() + self.dout_pak = CSRStatus(8) + self.kout_pak = CSRStatus() + self.dout_valid =CSRStatus() + + + # 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 + 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.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), + + # output + buf_out.source.ack.eq(self.inc.re), + self.dout_pak.status.eq(buf_out.source.data), + self.kout_pak.status.eq(buf_out.source.k), + self.dout_valid.status.eq(buf_out.source.stb), + ] + + + tx_pipeline = [ buf_in, pak_start, buf_out] + + for s, d in zip(tx_pipeline, tx_pipeline[1:]): + self.comb += s.source.connect(d.sink) + + + # DEBUG + self.specials += [ + + # # pmod 0-7 pin + Instance("OBUF", i_I=pak_start.sink.stb, o_O=pmod_pads[0]), + Instance("OBUF", i_I=pak_start.sink.ack, o_O=pmod_pads[1]), + Instance("OBUF", i_I=pak_start.source.stb, o_O=pmod_pads[2]), + Instance("OBUF", i_I=pak_start.source.ack, o_O=pmod_pads[3]), + Instance("OBUF", i_I=buf_out.sink.stb, o_O=pmod_pads[4]), + Instance("OBUF", i_I=buf_out.sink.ack, o_O=pmod_pads[5]), + 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):