Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

phy: titanium/trion rgmii: improvement #181

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 45 additions & 45 deletions liteeth/phy/titaniumrgmii.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
# LiteEth PHY RGMII TX -----------------------------------------------------------------------------

class LiteEthPHYRGMIITX(LiteXModule):
def __init__(self, platform, pads, n=0):
def __init__(self, pads, clk):
self.sink = sink = stream.Endpoint(eth_phy_description(8))

# # #
Expand All @@ -31,13 +31,12 @@ def __init__(self, platform, pads, n=0):
# ------------
tx_data_h = Signal(4)
tx_data_l = Signal(4)
for i in range(4):
self.specials += DDROutput(
i1 = tx_data_h[i],
i2 = tx_data_l[i],
o = pads.tx_data[i],
clk = ClockSignal("eth_tx"),
)
self.specials += DDROutput(
i1 = tx_data_h,
i2 = tx_data_l,
o = pads.tx_data,
clk = clk,
)

# TX Ctl IOs.
# -----------
Expand All @@ -47,7 +46,7 @@ def __init__(self, platform, pads, n=0):
i1 = tx_ctl_h,
i2 = tx_ctl_l,
o = pads.tx_ctl,
clk = ClockSignal("eth_tx"),
clk = clk,
)

# Logic.
Expand All @@ -56,17 +55,14 @@ def __init__(self, platform, pads, n=0):
self.sync += [
tx_ctl_h.eq(sink.valid),
tx_ctl_l.eq(sink.valid),
tx_data_h.eq(sink.data[:4]),
tx_data_l.eq(sink.data[4:]),
]
for i in range(4):
self.sync += [
tx_data_h[i].eq(sink.data[i + 0]),
tx_data_l[i].eq(sink.data[i + 4]),
]

# LiteEth PHY RGMII RX -----------------------------------------------------------------------------

class LiteEthPHYRGMIIRX(LiteXModule):
def __init__(self, platform, pads, n=0):
def __init__(self, pads, clk):
self.source = source = stream.Endpoint(eth_phy_description(8))

# # #
Expand All @@ -75,13 +71,12 @@ def __init__(self, platform, pads, n=0):
# ------------
rx_data_h = Signal(4)
rx_data_l = Signal(4)
for i in range(4):
self.specials += DDRInput(
i = pads.rx_data[i],
o1 = rx_data_h[i],
o2 = rx_data_l[i],
clk = ClockSignal("eth_rx"),
)
self.specials += DDRInput(
i = pads.rx_data,
o1 = rx_data_h,
o2 = rx_data_l,
clk = clk,
)

# RX Ctl IOs.
# -----------
Expand All @@ -91,7 +86,7 @@ def __init__(self, platform, pads, n=0):
i = pads.rx_ctl,
o1 = rx_ctl_h,
o2 = rx_ctl_l,
clk = ClockSignal("eth_rx"),
clk = clk,
)

rx_ctl = rx_ctl_h
Expand All @@ -103,9 +98,8 @@ def __init__(self, platform, pads, n=0):
last = Signal()
rx_data_lsb = Signal(4)
rx_data_msb = Signal(4)
for i in range(4):
self.comb += rx_data_msb[i + 0].eq(rx_data_l[i])
self.sync += rx_data_lsb[i + 0].eq(rx_data_h[i])
self.comb += rx_data_msb.eq(rx_data_l)
self.sync += rx_data_lsb.eq(rx_data_h)
self.sync += [
last.eq(~rx_ctl & rx_ctl_d),
source.valid.eq(rx_ctl_d),
Expand All @@ -123,32 +117,38 @@ def __init__(self, platform, clock_pads, with_hw_init_reset, hw_reset_cycles=256

# Clk Domains.
# ------------
self.cd_eth_rx = ClockDomain()
self.cd_eth_tx = ClockDomain()
self.cd_eth_tx_delayed = ClockDomain(reset_less=True)
self.cd_eth_rx = ClockDomain(name=f"eth{n}_rx")
self.cd_eth_tx = ClockDomain(name=f"eth{n}_tx")
self.cd_eth_tx_delayed = ClockDomain(name=f"eth{n}_tx_delayed", reset_less=True)

# Check if RX Clk is connected to a PLL. If it is, we have to use it directly.
pad_name = platform.get_pin_location(clock_pads.rx)[0]
if platform.parser.get_pll_inst_from_pin(pad_name) is not None:
clkin = clock_pads.rx
else:
# RX Clk.
# -------
self.specials += ClkInput(
i = clock_pads.rx,
o = self.cd_eth_rx.clk,
)
clkin = self.cd_eth_rx.clk

# RX Clk.
# TX PLL.
# -------
self.specials += ClkInput(
i = clock_pads.rx,
o = self.cd_eth_rx.clk,
)
self.pll = pll = TITANIUMPLL(platform)
pll.register_clkin(clkin, freq=125e6)
pll.create_clkout(self.cd_eth_rx, freq=125e6, phase=0, with_reset=False)
pll.create_clkout(self.cd_eth_tx, freq=125e6, phase=0, with_reset=False)
pll.create_clkout(self.cd_eth_tx_delayed, freq=125e6, phase=90)

# TX Clk.
# -------
self.specials += ClkOutput(
i = ClockSignal("eth_tx_delayed"),
i = self.cd_eth_tx_delayed.clk,
o = clock_pads.tx
)

# TX PLL.
# -------
self.pll = pll = TITANIUMPLL(platform)
pll.register_clkin(self.cd_eth_rx.clk, freq=125e6)
pll.create_clkout(self.cd_eth_rx, freq=125e6, phase=0, with_reset=False)
pll.create_clkout(self.cd_eth_tx, freq=125e6, phase=0, with_reset=False)
pll.create_clkout(self.cd_eth_tx_delayed, freq=125e6, phase=90)

# Reset.
# ------
self.reset = reset = Signal()
Expand All @@ -173,8 +173,8 @@ class LiteEthPHYRGMII(LiteXModule):
rx_clk_freq = 125e6
def __init__(self, platform, clock_pads, pads, with_hw_init_reset=True, hw_reset_cycles=256):
self.crg = LiteEthPHYRGMIICRG(platform, clock_pads, with_hw_init_reset, hw_reset_cycles, n=self.n)
self.tx = ClockDomainsRenamer("eth_tx")(LiteEthPHYRGMIITX(platform, pads, n=self.n))
self.rx = ClockDomainsRenamer("eth_rx")(LiteEthPHYRGMIIRX(platform, pads, n=self.n))
self.tx = ClockDomainsRenamer(f"eth{self.n}_tx")(LiteEthPHYRGMIITX(pads, self.crg.cd_eth_tx.clk))
self.rx = ClockDomainsRenamer(f"eth{self.n}_rx")(LiteEthPHYRGMIIRX(pads, self.crg.cd_eth_rx.clk))
self.sink, self.source = self.tx.sink, self.rx.source
LiteEthPHYRGMII.n += 1 # FIXME: Improve.

Expand Down
121 changes: 14 additions & 107 deletions liteeth/phy/trionrgmii.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,106 +12,13 @@

from litex.gen import *

from litex.build.io import ClkInput, ClkOutput, DDROutput, DDRInput
from litex.build.io import ClkInput, ClkOutput
from litex.build.generic_platform import *
from litex.soc.cores.clock import *

from liteeth.common import *
from liteeth.phy.common import *

# LiteEth PHY RGMII TX -----------------------------------------------------------------------------

class LiteEthPHYRGMIITX(LiteXModule):
def __init__(self, platform, pads, n=0):
self.sink = sink = stream.Endpoint(eth_phy_description(8))

# # #

# TX Data IOs.
# ------------
tx_data_h = Signal(4)
tx_data_l = Signal(4)
for i in range(4):
self.specials += DDROutput(
i1 = tx_data_h[i],
i2 = tx_data_l[i],
o = pads.tx_data[i],
clk = ClockSignal("eth_tx")
)

# TX Ctl IOs.
# -----------
tx_ctl_h = Signal()
tx_ctl_l = Signal()
self.specials += DDROutput(
i1 = tx_ctl_h,
i2 = tx_ctl_l,
o = pads.tx_ctl,
clk = ClockSignal("eth_tx")
)

# Logic.
# ------
self.comb += sink.ready.eq(1)
self.sync += [
tx_ctl_h.eq(sink.valid),
tx_ctl_l.eq(sink.valid),
]
for i in range(4):
self.sync += [
tx_data_h[i].eq(sink.data[i + 0]),
tx_data_l[i].eq(sink.data[i + 4]),
]

# LiteEth PHY RGMII RX -----------------------------------------------------------------------------

class LiteEthPHYRGMIIRX(LiteXModule):
def __init__(self, platform, pads, n=0):
self.source = source = stream.Endpoint(eth_phy_description(8))

# # #

# RX Data IOs.
# ------------
rx_data_h = Signal(4)
rx_data_l = Signal(4)
for i in range(4):
self.specials += DDRInput(
i = pads.rx_data[i],
o1 = rx_data_h[i],
o2 = rx_data_l[i],
clk = ClockSignal("eth_rx")
)

# RX Ctl IOs.
# -----------
rx_ctl_h = Signal()
rx_ctl_l = Signal()
self.specials += DDRInput(
i = pads.rx_ctl,
o1 = rx_ctl_h,
o2 = rx_ctl_l,
clk = ClockSignal("eth_rx")
)

rx_ctl = rx_ctl_h
rx_ctl_d = Signal()
self.sync += rx_ctl_d.eq(rx_ctl)

# Logic.
# ------
last = Signal()
rx_data_lsb = Signal(4)
rx_data_msb = Signal(4)
for i in range(4):
self.comb += rx_data_msb[i + 0].eq(rx_data_l[i])
self.sync += rx_data_lsb[i + 0].eq(rx_data_h[i])
self.sync += [
last.eq(~rx_ctl & rx_ctl_d),
source.valid.eq(rx_ctl_d),
source.data.eq(Cat(rx_data_lsb, rx_data_msb)),
]
self.comb += source.last.eq(last)
from liteeth.phy.titaniumrgmii import LiteEthPHYRGMIITX, LiteEthPHYRGMIIRX

# LiteEth PHY RGMII CRG ----------------------------------------------------------------------------

Expand All @@ -123,9 +30,9 @@ def __init__(self, platform, clock_pads, with_hw_init_reset, hw_reset_cycles=256

# Clk Domains.
# ------------
self.cd_eth_rx = ClockDomain()
self.cd_eth_tx = ClockDomain()
self.cd_eth_tx_delayed = ClockDomain(reset_less=True)
self.cd_eth_rx = ClockDomain(name=f"eth{n}_rx")
self.cd_eth_tx = ClockDomain(name=f"eth{n}_tx")
self.cd_eth_tx_delayed = ClockDomain(name=f"eth{n}_tx_delayed", reset_less=True)

# RX Clk.
# -------
Expand All @@ -134,13 +41,6 @@ def __init__(self, platform, clock_pads, with_hw_init_reset, hw_reset_cycles=256
o = self.cd_eth_rx.clk,
)

# TX Clk.
# -------
self.specials += ClkOutput(
i = ClockSignal("eth_tx_delayed"),
o = clock_pads.tx
)

# TX PLL.
# -------
self.pll = pll = TRIONPLL(platform)
Expand All @@ -149,6 +49,13 @@ def __init__(self, platform, clock_pads, with_hw_init_reset, hw_reset_cycles=256
pll.create_clkout(self.cd_eth_tx, freq=125e6, phase=0, with_reset=False)
pll.create_clkout(self.cd_eth_tx_delayed, freq=125e6, phase=45)

# TX Clk.
# -------
self.specials += ClkOutput(
i = self.cd_eth_tx_delayed.clk,
o = clock_pads.tx
)

# Reset.
# ------
self.reset = reset = Signal()
Expand All @@ -173,8 +80,8 @@ class LiteEthPHYRGMII(LiteXModule):
rx_clk_freq = 125e6
def __init__(self, platform, clock_pads, pads, with_hw_init_reset=True, hw_reset_cycles=256):
self.crg = LiteEthPHYRGMIICRG(platform, clock_pads, with_hw_init_reset, hw_reset_cycles, n=self.n)
self.tx = ClockDomainsRenamer("eth_tx")(LiteEthPHYRGMIITX(platform, pads, n=self.n))
self.rx = ClockDomainsRenamer("eth_rx")(LiteEthPHYRGMIIRX(platform, pads, n=self.n))
self.tx = ClockDomainsRenamer(f"eth{self.n}_tx")(LiteEthPHYRGMIITX(pads, self.crg.cd_eth_tx.clk))
self.rx = ClockDomainsRenamer(f"eth{self.n}_rx")(LiteEthPHYRGMIIRX(pads, self.crg.cd_eth_rx.clk))
self.sink, self.source = self.tx.sink, self.rx.source
LiteEthPHYRGMII.n += 1 # FIXME: Improve.

Expand Down