new-sonar/gateware/eth.py
David Lenfesty 8b19464608 gateware: propogate MDIO signal correctly w/o IOBUF
This was causing my nextpnr crash. I really do need to figure out how to
do this in a less hacky way. Or even just make it more explicit that I
am doing this for a reason.
2023-03-04 12:41:16 -07:00

89 lines
2.9 KiB
Python

from amaranth import *
from amaranth.lib.io import pin_layout
from amaranth_soc.wishbone.bus import Interface
from amaranth_soc.memory import MemoryMap
__all__ = ["LiteEth", "rgmii_layout"]
# TODO maybe this should just call liteeth_gen to close the loop?
class LiteEth(Elaboratable, Interface):
def __init__(self, eth_interface):
self.eth_interface = eth_interface
# Addr width is 13 bits to accomodate 0x1FFF, which is well p
Interface.__init__(self, addr_width=13, data_width=32, granularity=8, features=["cti", "bte", "err"])
# TODO I need to understand the semantics here better
memory_map = MemoryMap(addr_width=15, data_width=8)
#memory_map.add_resource(self, name="LiteETH", size=0x2000)
self.memory_map = memory_map
self.interrupt = Signal()
# TODO this really shouldn't technically happen here, because we can elaborate one module multiple times,
# but since I use it once it isn't actually a problem.
def elaborate(self, platform):
platform.add_file("liteeth_core.v", open("liteeth/gateware/liteeth_core.v", 'r').read())
m = Module()
# TODO I have to provide TX/RX clocks myself
core = Instance(
"liteeth_core",
i_sys_clock=ClockSignal(),
# RGMII signals
o_rgmii_eth_clocks_tx=self.eth_interface.tx_clk,
i_rgmii_eth_clocks_rx=self.eth_interface.rx_clk,
o_rgmii_eth_rst_n=self.eth_interface.rst,
i_rgmii_eth_int_n=Const(1),
# TODO actually fix the platform to support this problem.
#i_rgmii_eth_mdio=self.eth_interface.mdio,
o_rgmii_eth_mdc=self.eth_interface.mdc,
i_rgmii_eth_rx_ctl=self.eth_interface.rx_ctl,
i_rgmii_eth_rx_data=self.eth_interface.rx_data,
o_rgmii_eth_tx_ctl=self.eth_interface.tx_ctl,
o_rgmii_eth_tx_data=self.eth_interface.tx_data,
# Wishbone all the things
i_wishbone_adr=self.adr,
i_wishbone_dat_w=self.dat_w,
o_wishbone_dat_r=self.dat_r,
i_wishbone_sel=self.sel,
i_wishbone_cyc=self.cyc,
o_wishbone_ack=self.ack,
i_wishbone_we=self.we,
i_wishbone_cti=self.cti,
i_wishbone_bte=self.bte,
o_wishbone_err=self.err,
o_interrupt=self.interrupt,
)
# TODO connect ethernet interface
m.submodules.core = core
return m
rgmii_layout = [
("tx_clk", pin_layout(1, "o")),
("rx_clk", pin_layout(1, "i")),
("rst", pin_layout(1, "o")),
("int_n", pin_layout(1, "i")),
# TODO is this not IO? why does LiteEth say input?
# I think the answer is it uses a primitive, not 100% right now
("mdio", pin_layout(1, "i")),
("mdc", pin_layout(1, "o")),
("rx_ctl", pin_layout(1, "i")),
("rx_data", pin_layout(4, "i")),
("tx_ctl", pin_layout(1, "o")),
("tx_data", pin_layout(4, "o")),
]