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")), ]