107 lines
3.4 KiB
Python
107 lines
3.4 KiB
Python
|
from nmigen import *
|
||
|
|
||
|
|
||
|
__all__ = ["EthRGMIICoreCfg", "SPIFlashCoreCfg"]
|
||
|
|
||
|
|
||
|
class EthRGMIICoreCfg(Elaboratable):
|
||
|
def __init__(self, core, eth_pins, *, rx, tx, tx_clk=None):
|
||
|
self.core = core
|
||
|
self.eth_pins = eth_pins
|
||
|
if not isinstance(rx, bool):
|
||
|
raise TypeError("Must include either rx=True or False "
|
||
|
"to indicate whether RX is used or not, not rx={}"
|
||
|
.format(repr(rx)))
|
||
|
self.rx = rx
|
||
|
if not isinstance(tx, bool):
|
||
|
raise TypeError("Must include either tx=True or False "
|
||
|
"to indicate whether TX is used or not, not tx={}"
|
||
|
.format(repr(tx)))
|
||
|
self.tx = tx
|
||
|
|
||
|
if tx:
|
||
|
if tx_clk is None:
|
||
|
raise TypeError("Signal as TX clock must not be None")
|
||
|
self.tx_clk = tx_clk
|
||
|
|
||
|
def elaborate(self, platform):
|
||
|
m = Module()
|
||
|
|
||
|
if self.rx:
|
||
|
rx = self.core.rx_io
|
||
|
# DDRInput on rx_ctl
|
||
|
m.submodules += [
|
||
|
Instance("IDDRX1F",
|
||
|
i_D=self.eth_pins.rx_ctl,
|
||
|
i_SCLK=rx.rx_ctl_iddr.i_clk,
|
||
|
o_Q0=rx.rx_ctl_iddr.i0,
|
||
|
o_Q1=rx.rx_ctl_iddr.i1,
|
||
|
)
|
||
|
]
|
||
|
# DDRInput on rx_data
|
||
|
for i in range(4):
|
||
|
m.submodules += [
|
||
|
Instance("IDDRX1F",
|
||
|
i_D=self.eth_pins.rx_data[i],
|
||
|
i_SCLK=rx.rx_data_iddr.i_clk,
|
||
|
o_Q0=rx.rx_data_iddr.i0[i],
|
||
|
o_Q1=rx.rx_data_iddr.i1[i],
|
||
|
)
|
||
|
]
|
||
|
# RX Clock
|
||
|
cd_eth_rx = ClockDomain("eth_rx")
|
||
|
m.domains += cd_eth_rx
|
||
|
m.d.comb += cd_eth_rx.clk.eq(self.eth_pins.rx_clk)
|
||
|
|
||
|
if self.tx:
|
||
|
tx = self.core.tx_io
|
||
|
# DDROutput on tx_clk
|
||
|
m.submodules += [
|
||
|
Instance("ODDRX1F",
|
||
|
i_D0=tx.tx_clk_oddr.o0,
|
||
|
i_D1=tx.tx_clk_oddr.o1,
|
||
|
i_SCLK=tx.tx_clk_oddr.o_clk,
|
||
|
o_Q=self.eth_pins.tx_clk
|
||
|
)
|
||
|
]
|
||
|
# DDROutput on tx_ctl
|
||
|
m.submodules += [
|
||
|
Instance("ODDRX1F",
|
||
|
i_D0=tx.tx_ctl_oddr.o0,
|
||
|
i_D1=tx.tx_ctl_oddr.o1,
|
||
|
i_SCLK=tx.tx_ctl_oddr.o_clk,
|
||
|
o_Q=self.eth_pins.tx_ctl
|
||
|
)
|
||
|
]
|
||
|
# DDROutput on tx_data
|
||
|
for i in range(4):
|
||
|
m.submodules += [
|
||
|
Instance("ODDRX1F",
|
||
|
i_D0=tx.tx_data_oddr.o0[i],
|
||
|
i_D1=tx.tx_data_oddr.o1[i],
|
||
|
i_SCLK=tx.tx_data_oddr.o_clk,
|
||
|
o_Q=self.eth_pins.tx_data[i]
|
||
|
)
|
||
|
]
|
||
|
# TX Clock
|
||
|
cd_eth_tx = ClockDomain("eth_tx")
|
||
|
m.domains += cd_eth_tx
|
||
|
m.d.comb += cd_eth_tx.clk.eq(self.tx_clk)
|
||
|
|
||
|
return m
|
||
|
|
||
|
|
||
|
class SPIFlashCoreCfg(Elaboratable):
|
||
|
def __init__(self, core):
|
||
|
self.core = core
|
||
|
|
||
|
def elaborate(self, platform):
|
||
|
m = Module()
|
||
|
|
||
|
spi = self.core.spi_io
|
||
|
m.submodules += Instance("USRMCLK",
|
||
|
i_USRMCLKI=spi.clk,
|
||
|
i_USRMCLKTS=0)
|
||
|
|
||
|
return m
|