1212
1313from liteeth .common import *
1414from liteeth .mac import gap , preamble , crc , padding , last_be
15+ from liteeth .mac .common import *
1516
1617from 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