Skip to content

Commit ec68688

Browse files
Merge pull request #177 from david-sawatzke/mac_path_flexibility
mac/core: Allow using core_dw smaller than phy_dw
2 parents 6bc8a23 + d0608e6 commit ec68688

File tree

1 file changed

+37
-34
lines changed

1 file changed

+37
-34
lines changed

liteeth/mac/core.py

Lines changed: 37 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
from liteeth.common import *
1414
from liteeth.mac import gap, preamble, crc, padding, last_be
15+
from liteeth.mac.common import *
1516

1617
from migen.genlib.cdc import PulseSynchronizer
1718

@@ -37,8 +38,7 @@ def __init__(self, phy, dw,
3738
# Parameters.
3839
core_dw = dw
3940
phy_dw = phy.dw
40-
if core_dw < phy_dw:
41-
raise ValueError("Core data width({}) must be larger than PHY data width({})".format(core_dw, phy_dw))
41+
4242
if with_sys_datapath:
4343
cd_tx = "sys"
4444
cd_rx = "sys"
@@ -64,8 +64,8 @@ class TXDatapath(LiteXModule):
6464
def __init__(self):
6565
self.pipeline = []
6666

67-
def add_cdc(self):
68-
tx_cdc = stream.ClockDomainCrossing(eth_phy_description(core_dw),
67+
def add_cdc(self, dw):
68+
tx_cdc = stream.ClockDomainCrossing(eth_phy_description(dw),
6969
cd_from = "sys",
7070
cd_to = "eth_tx",
7171
depth = tx_cdc_depth,
@@ -74,11 +74,11 @@ def add_cdc(self):
7474
self.submodules += tx_cdc
7575
self.pipeline.append(tx_cdc)
7676

77-
def add_converter(self):
77+
def add_converter(self, cd):
7878
tx_converter = stream.StrideConverter(
7979
description_from = eth_phy_description(core_dw),
8080
description_to = eth_phy_description(phy_dw))
81-
tx_converter = ClockDomainsRenamer("eth_tx")(tx_converter)
81+
tx_converter = ClockDomainsRenamer(cd)(tx_converter)
8282
self.submodules += tx_converter
8383
self.pipeline.append(tx_converter)
8484

@@ -113,30 +113,30 @@ def add_gap(self):
113113
self.submodules += tx_gap
114114
self.pipeline.append(tx_gap)
115115

116+
def add_domain_switch(self):
117+
dw = core_dw
118+
if core_dw < phy_dw:
119+
dw = phy_dw
120+
self.add_converter("sys")
121+
self.add_cdc(dw)
122+
if core_dw > phy_dw:
123+
self.add_converter("eth_tx")
124+
self.add_last_be()
125+
116126
def do_finalize(self):
117127
self.submodules += stream.Pipeline(*self.pipeline)
118128

119129
self.tx_datapath = tx_datapath = TXDatapath()
120130
tx_datapath.pipeline.append(self.sink)
121131
if not with_sys_datapath:
122-
# CHECKME: Verify converter/cdc order for the different cases.
123-
tx_datapath.add_cdc()
124-
if core_dw != phy_dw:
125-
tx_datapath.add_converter()
126-
if core_dw != 8:
127-
tx_datapath.add_last_be()
132+
tx_datapath.add_domain_switch()
128133
if with_padding:
129134
tx_datapath.add_padding()
130135
if with_preamble_crc:
131136
tx_datapath.add_crc()
132137
tx_datapath.add_preamble()
133138
if with_sys_datapath:
134-
# CHECKME: Verify converter/cdc order for the different cases.
135-
tx_datapath.add_cdc()
136-
if core_dw != phy_dw:
137-
tx_datapath.add_converter()
138-
if core_dw != 8:
139-
tx_datapath.add_last_be()
139+
tx_datapath.add_domain_switch()
140140
# Gap insertion has to occurr in phy tx domain to ensure gap is correctly maintained.
141141
if not getattr(phy, "integrated_ifg_inserter", False):
142142
tx_datapath.add_gap()
@@ -186,16 +186,16 @@ def add_last_be(self):
186186
self.submodules += rx_last_be
187187
self.pipeline.append(rx_last_be)
188188

189-
def add_converter(self):
189+
def add_converter(self, cd):
190190
rx_converter = stream.StrideConverter(
191191
description_from = eth_phy_description(phy_dw),
192192
description_to = eth_phy_description(core_dw))
193-
rx_converter = ClockDomainsRenamer("eth_rx")(rx_converter)
193+
rx_converter = ClockDomainsRenamer(cd)(rx_converter)
194194
self.submodules += rx_converter
195195
self.pipeline.append(rx_converter)
196196

197-
def add_cdc(self):
198-
rx_cdc = stream.ClockDomainCrossing(eth_phy_description(core_dw),
197+
def add_cdc(self, dw):
198+
rx_cdc = stream.ClockDomainCrossing(eth_phy_description(dw),
199199
cd_from = "eth_rx",
200200
cd_to = "sys",
201201
depth = rx_cdc_depth,
@@ -204,28 +204,31 @@ def add_cdc(self):
204204
self.submodules += rx_cdc
205205
self.pipeline.append(rx_cdc)
206206

207+
def add_domain_switch(self):
208+
dw = phy_dw
209+
if phy_dw < core_dw:
210+
dw = core_dw
211+
self.add_last_be()
212+
self.add_converter("eth_rx")
213+
self.add_cdc(dw)
214+
if phy_dw > core_dw:
215+
self.add_converter("sys")
216+
last_handler = LiteEthLastHandler(eth_phy_description(core_dw))
217+
self.submodules += last_handler
218+
self.pipeline.append(last_handler)
219+
207220
def do_finalize(self):
208221
self.submodules += stream.Pipeline(*self.pipeline)
209222

210223
self.rx_datapath = rx_datapath = RXDatapath()
211224
rx_datapath.pipeline.append(phy)
212225
if with_sys_datapath:
213-
if core_dw != 8:
214-
rx_datapath.add_last_be()
215-
# CHECKME: Verify converter/cdc order for the different cases.
216-
if core_dw != phy_dw:
217-
rx_datapath.add_converter()
218-
rx_datapath.add_cdc()
226+
rx_datapath.add_domain_switch()
219227
if with_preamble_crc:
220228
rx_datapath.add_preamble()
221229
rx_datapath.add_crc()
222230
if with_padding:
223231
rx_datapath.add_padding()
224232
if not with_sys_datapath:
225-
if core_dw != 8:
226-
rx_datapath.add_last_be()
227-
# CHECKME: Verify converter/cdc order for the different cases.
228-
if core_dw != phy_dw:
229-
rx_datapath.add_converter()
230-
rx_datapath.add_cdc()
233+
rx_datapath.add_domain_switch()
231234
rx_datapath.pipeline.append(self.source)

0 commit comments

Comments
 (0)