93 lines
3.0 KiB
Python
93 lines
3.0 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
|
|
from math import log2, ceil
|
|
|
|
|
|
__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
|
|
|
|
# Highest address to support is 0x0002_1FFF, so need 18 bits of full address
|
|
highest_addr = 0x0002_1FFF
|
|
bit_width = ceil(log2(highest_addr))
|
|
Interface.__init__(self, addr_width=bit_width - 2, data_width=32, granularity=8, features=["cti", "bte", "err"])
|
|
memory_map = MemoryMap(addr_width=bit_width, 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):
|
|
if platform is not None:
|
|
platform.add_file("liteeth_core.v", open("liteeth/gateware/liteeth_core.v", 'r').read())
|
|
|
|
m = Module()
|
|
|
|
|
|
core = Instance(
|
|
"liteeth_core",
|
|
i_sys_clock=ClockSignal(),
|
|
i_sys_reset=Const(0),
|
|
|
|
# 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),
|
|
|
|
# Bad hacks
|
|
o_rgmii_eth_mdio_o=self.eth_interface.mdio.o,
|
|
o_rgmii_eth_mdio_oe=self.eth_interface.mdio.oe,
|
|
i_rgmii_eth_mdio_i=self.eth_interface.mdio.i,
|
|
|
|
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,
|
|
i_wishbone_stb=self.stb,
|
|
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,
|
|
)
|
|
|
|
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")),
|
|
|
|
("mdio", pin_layout(1, "io")),
|
|
("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")),
|
|
]
|
|
|