mac/core: Allow using core_dw smaller than phy_dw
Especially for XGMII PHYs with 64 bit width, a 32 bit datapath uses much less resources
This commit is contained in:
parent
99d4073c6a
commit
d0608e6756
|
@ -12,6 +12,7 @@ from litex.gen import *
|
|||
|
||||
from liteeth.common import *
|
||||
from liteeth.mac import gap, preamble, crc, padding, last_be
|
||||
from liteeth.mac.common import *
|
||||
|
||||
from migen.genlib.cdc import PulseSynchronizer
|
||||
|
||||
|
@ -37,8 +38,7 @@ class LiteEthMACCore(LiteXModule):
|
|||
# Parameters.
|
||||
core_dw = dw
|
||||
phy_dw = phy.dw
|
||||
if core_dw < phy_dw:
|
||||
raise ValueError("Core data width({}) must be larger than PHY data width({})".format(core_dw, phy_dw))
|
||||
|
||||
if with_sys_datapath:
|
||||
cd_tx = "sys"
|
||||
cd_rx = "sys"
|
||||
|
@ -64,8 +64,8 @@ class LiteEthMACCore(LiteXModule):
|
|||
def __init__(self):
|
||||
self.pipeline = []
|
||||
|
||||
def add_cdc(self):
|
||||
tx_cdc = stream.ClockDomainCrossing(eth_phy_description(core_dw),
|
||||
def add_cdc(self, dw):
|
||||
tx_cdc = stream.ClockDomainCrossing(eth_phy_description(dw),
|
||||
cd_from = "sys",
|
||||
cd_to = "eth_tx",
|
||||
depth = tx_cdc_depth,
|
||||
|
@ -74,11 +74,11 @@ class LiteEthMACCore(LiteXModule):
|
|||
self.submodules += tx_cdc
|
||||
self.pipeline.append(tx_cdc)
|
||||
|
||||
def add_converter(self):
|
||||
def add_converter(self, cd):
|
||||
tx_converter = stream.StrideConverter(
|
||||
description_from = eth_phy_description(core_dw),
|
||||
description_to = eth_phy_description(phy_dw))
|
||||
tx_converter = ClockDomainsRenamer("eth_tx")(tx_converter)
|
||||
tx_converter = ClockDomainsRenamer(cd)(tx_converter)
|
||||
self.submodules += tx_converter
|
||||
self.pipeline.append(tx_converter)
|
||||
|
||||
|
@ -113,30 +113,30 @@ class LiteEthMACCore(LiteXModule):
|
|||
self.submodules += tx_gap
|
||||
self.pipeline.append(tx_gap)
|
||||
|
||||
def add_domain_switch(self):
|
||||
dw = core_dw
|
||||
if core_dw < phy_dw:
|
||||
dw = phy_dw
|
||||
self.add_converter("sys")
|
||||
self.add_cdc(dw)
|
||||
if core_dw > phy_dw:
|
||||
self.add_converter("eth_tx")
|
||||
self.add_last_be()
|
||||
|
||||
def do_finalize(self):
|
||||
self.submodules += stream.Pipeline(*self.pipeline)
|
||||
|
||||
self.tx_datapath = tx_datapath = TXDatapath()
|
||||
tx_datapath.pipeline.append(self.sink)
|
||||
if not with_sys_datapath:
|
||||
# CHECKME: Verify converter/cdc order for the different cases.
|
||||
tx_datapath.add_cdc()
|
||||
if core_dw != phy_dw:
|
||||
tx_datapath.add_converter()
|
||||
if core_dw != 8:
|
||||
tx_datapath.add_last_be()
|
||||
tx_datapath.add_domain_switch()
|
||||
if with_padding:
|
||||
tx_datapath.add_padding()
|
||||
if with_preamble_crc:
|
||||
tx_datapath.add_crc()
|
||||
tx_datapath.add_preamble()
|
||||
if with_sys_datapath:
|
||||
# CHECKME: Verify converter/cdc order for the different cases.
|
||||
tx_datapath.add_cdc()
|
||||
if core_dw != phy_dw:
|
||||
tx_datapath.add_converter()
|
||||
if core_dw != 8:
|
||||
tx_datapath.add_last_be()
|
||||
tx_datapath.add_domain_switch()
|
||||
# Gap insertion has to occurr in phy tx domain to ensure gap is correctly maintained.
|
||||
if not getattr(phy, "integrated_ifg_inserter", False):
|
||||
tx_datapath.add_gap()
|
||||
|
@ -186,16 +186,16 @@ class LiteEthMACCore(LiteXModule):
|
|||
self.submodules += rx_last_be
|
||||
self.pipeline.append(rx_last_be)
|
||||
|
||||
def add_converter(self):
|
||||
def add_converter(self, cd):
|
||||
rx_converter = stream.StrideConverter(
|
||||
description_from = eth_phy_description(phy_dw),
|
||||
description_to = eth_phy_description(core_dw))
|
||||
rx_converter = ClockDomainsRenamer("eth_rx")(rx_converter)
|
||||
rx_converter = ClockDomainsRenamer(cd)(rx_converter)
|
||||
self.submodules += rx_converter
|
||||
self.pipeline.append(rx_converter)
|
||||
|
||||
def add_cdc(self):
|
||||
rx_cdc = stream.ClockDomainCrossing(eth_phy_description(core_dw),
|
||||
def add_cdc(self, dw):
|
||||
rx_cdc = stream.ClockDomainCrossing(eth_phy_description(dw),
|
||||
cd_from = "eth_rx",
|
||||
cd_to = "sys",
|
||||
depth = rx_cdc_depth,
|
||||
|
@ -204,28 +204,31 @@ class LiteEthMACCore(LiteXModule):
|
|||
self.submodules += rx_cdc
|
||||
self.pipeline.append(rx_cdc)
|
||||
|
||||
def add_domain_switch(self):
|
||||
dw = phy_dw
|
||||
if phy_dw < core_dw:
|
||||
dw = core_dw
|
||||
self.add_last_be()
|
||||
self.add_converter("eth_rx")
|
||||
self.add_cdc(dw)
|
||||
if phy_dw > core_dw:
|
||||
self.add_converter("sys")
|
||||
last_handler = LiteEthLastHandler(eth_phy_description(core_dw))
|
||||
self.submodules += last_handler
|
||||
self.pipeline.append(last_handler)
|
||||
|
||||
def do_finalize(self):
|
||||
self.submodules += stream.Pipeline(*self.pipeline)
|
||||
|
||||
self.rx_datapath = rx_datapath = RXDatapath()
|
||||
rx_datapath.pipeline.append(phy)
|
||||
if with_sys_datapath:
|
||||
if core_dw != 8:
|
||||
rx_datapath.add_last_be()
|
||||
# CHECKME: Verify converter/cdc order for the different cases.
|
||||
if core_dw != phy_dw:
|
||||
rx_datapath.add_converter()
|
||||
rx_datapath.add_cdc()
|
||||
rx_datapath.add_domain_switch()
|
||||
if with_preamble_crc:
|
||||
rx_datapath.add_preamble()
|
||||
rx_datapath.add_crc()
|
||||
if with_padding:
|
||||
rx_datapath.add_padding()
|
||||
if not with_sys_datapath:
|
||||
if core_dw != 8:
|
||||
rx_datapath.add_last_be()
|
||||
# CHECKME: Verify converter/cdc order for the different cases.
|
||||
if core_dw != phy_dw:
|
||||
rx_datapath.add_converter()
|
||||
rx_datapath.add_cdc()
|
||||
rx_datapath.add_domain_switch()
|
||||
rx_datapath.pipeline.append(self.source)
|
||||
|
|
Loading…
Reference in New Issue