liteth/phy/rmii: add support for ref_clk as input.

In some hardware, ref_clk can be input for both the MAC and the PHY. In this
case, setting refclk_cd to None will make the CRG use ref_clk as the RMII
input reference clock:

Pads:
# RMII Ethernet
("eth_clocks", 0,
    Subsignal("ref_clk", Pins("D17")),
    IOStandard("LVCMOS33"),
),
("eth", 0,
    Subsignal("rst_n",   Pins("F16")),
    Subsignal("rx_data", Pins("A20 B18")),
    Subsignal("crs_dv",  Pins("C20")),
    Subsignal("tx_en",   Pins("A19")),
    Subsignal("tx_data", Pins("C18 C19")),
    Subsignal("mdc",     Pins("F14")),
    Subsignal("mdio",    Pins("F13")),
    Subsignal("rx_er",   Pins("B20")),
    Subsignal("int_n",   Pins("D21")),
    IOStandard("LVCMOS33")
),


PHY:

self.submodules.ethphy = LiteEthPHYRMII(
    clock_pads = self.platform.request("eth_clocks"),
    pads       = self.platform.request("eth"),
    refclk_cd  = None)

Thanks @mwick83 for reporting the use case and for the initial implementation.
This commit is contained in:
Florent Kermarrec 2020-12-28 11:29:00 +01:00
parent dea35908c9
commit 7448170390
1 changed files with 14 additions and 4 deletions

View File

@ -99,12 +99,22 @@ class LiteEthPHYRMIICRG(Module, AutoCSR):
# # #
# RX/TX clocks
self.clock_domains.cd_eth_rx = ClockDomain()
self.clock_domains.cd_eth_tx = ClockDomain()
self.comb += self.cd_eth_rx.clk.eq(ClockSignal(refclk_cd))
self.comb += self.cd_eth_tx.clk.eq(ClockSignal(refclk_cd))
if clock_pads is not None:
self.specials += DDROutput(0, 1, clock_pads.ref_clk, ClockSignal("eth_tx"))
# When no refclk_cd, use clock_pads.ref_clk as RMII reference clock.
if refclk_cd is None:
self.comb += self.cd_eth_rx.clk.eq(clock_pads.ref_clk)
self.comb += self.cd_eth_tx.clk.eq(clock_pads.ref_clk)
# Else use refclk_cd as RMII reference clock (provided by user design).
else:
self.comb += self.cd_eth_rx.clk.eq(ClockSignal(refclk_cd))
self.comb += self.cd_eth_tx.clk.eq(ClockSignal(refclk_cd))
# Drive clock_pads if provided.
if clock_pads is not None:
self.specials += DDROutput(0, 1, clock_pads.ref_clk, ClockSignal("eth_tx"))
# Reset
self.reset = reset = Signal()