1
0
Fork 0

cxp: use CXPCRC32inserter in pipeline

This commit is contained in:
morgan 2024-08-30 12:38:21 +08:00
parent 6ebd3d4315
commit 4458c28736
1 changed files with 21 additions and 73 deletions

View File

@ -1,16 +1,13 @@
from migen import * from migen import *
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, LiteEthMACCRC32Inserter
from cxp_downconn import CXP_DownConn from cxp_downconn import CXP_DownConn
from cxp_upconn import CXP_UpConn from cxp_upconn import CXP_UpConn
from cxp_pipeline import Code_Inserter from cxp_pipeline import Code_Inserter, CXPCRC32Inserter
class CXP(Module, AutoCSR): class CXP(Module, AutoCSR):
def __init__(self, refclk, downconn_pads, upconn_pads, sys_clk_freq, debug_sma, pmod_pads): 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.txcore = CXP_TX_Core(pmod_pads)
self.submodules.upconn = UpConn_Packets(upconn_pads, sys_clk_freq, debug_sma, 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): class CXP_TX_Core(Module, AutoCSR):
def __init__(self, pmod_pads): def __init__(self, pmod_pads):
self.din_len = CSRStorage(6)
self.din_pak = CSR(8) self.din_pak = CSR(8)
self.din_k = CSRStorage() self.din_k = CSRStorage()
self.din_ready = CSRStatus() self.din_ready = CSRStatus()
@ -100,21 +98,34 @@ class CXP_TX_Core(Module, AutoCSR):
self.kout_pak = CSRStatus() self.kout_pak = CSRStatus()
self.dout_valid =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 # 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_in = buf_in = stream.SyncFIFO(cxp_phy_layout(), 2)
self.submodules.buf_out = buf_out = stream.SyncFIFO(cxp_phy_layout(), 64) 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.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 += [ self.sync += [
# input # input
self.din_ready.status.eq(buf_in.sink.ack), self.din_ready.status.eq(buf_in.sink.ack),
buf_in.sink.stb.eq(self.din_pak.re), buf_in.sink.stb.eq(0),
buf_in.sink.data.eq(self.din_pak.r), If(self.din_pak.re,
buf_in.sink.k.eq(self.din_k.storage), 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 # output
buf_out.source.ack.eq(self.inc.re), 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:]): for s, d in zip(tx_pipeline, tx_pipeline[1:]):
self.comb += s.source.connect(d.sink) 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.stb, o_O=pmod_pads[6]),
Instance("OBUF", i_I=buf_out.source.ack, o_O=pmod_pads[7]), 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)),
]