From 2df6c0b88e864aeea11c9d0b38538b8f8b42aeca Mon Sep 17 00:00:00 2001 From: Raptor Engineering Development Team Date: Mon, 28 Mar 2022 20:11:43 -0500 Subject: [PATCH] Add initial integration for OpenCores 10/100 Ethernet MAC --- src/ls2.py | 55 ++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 49 insertions(+), 6 deletions(-) diff --git a/src/ls2.py b/src/ls2.py index 235caf8..f9f61cc 100644 --- a/src/ls2.py +++ b/src/ls2.py @@ -30,6 +30,7 @@ from lambdasoc.periph import Peripheral from lambdasoc.soc.base import SoC from soc.bus.uart_16550 import UART16550 # opencores 16550 uart from soc.bus.tercel import Tercel # SPI XIP master +from soc.bus.opencores_ethmac import EthMAC # OpenCores 10/100 Ethernet MAC from soc.bus.external_core import ExternalCore # external libresoc/microwatt from soc.bus.wb_downconvert import WishboneDownConvert from soc.bus.syscon import MicrowattSYSCON @@ -230,11 +231,12 @@ class DDR3SoC(SoC, Elaboratable): def __init__(self, *, fpga, dram_cls, - uart_pins, spi_0_pins, + uart_pins, spi_0_pins, ethmac_0_pins, ddr_pins, ddrphy_addr, dramcore_addr, ddr_addr, fw_addr=0x0000_0000, firmware=None, spi0_addr, spi0_cfg_addr, + eth0_cfg_addr, eth0_irqno, hyperram_addr=None, hyperram_pins=None, clk_freq=50e6, @@ -251,11 +253,11 @@ class DDR3SoC(SoC, Elaboratable): # | # 64to32DownCvt # | - # arbiter - # | - # +---decoder----+--------+---------+-------+ - # | | | | | | - # uart XICS CSRs DRAM XIP SPI HyperRAM + # arbiter------------------------------------------+ + # | | + # +---decoder----+--------+---------+-------+--------+ | + # | | | | | | | | + # uart XICS CSRs DRAM XIP SPI HyperRAM EthMAC # set up wishbone bus arbiter and decoder. arbiter routes, # decoder maps local-relative addressed satellites to global addresses @@ -394,6 +396,7 @@ class DDR3SoC(SoC, Elaboratable): # SPI controller used for FPGA bitstream loading. spi0_is_lattice_ecp5_clk = False if platform is not None and fpga in ['versa_ecp5', + 'versa_ecp5_85', 'rcs_arctic_tern_bmc_card', 'isim']: spi0_is_lattice_ecp5_clk = True @@ -411,6 +414,19 @@ class DDR3SoC(SoC, Elaboratable): self._decoder.add(self.spi0.bus, addr=spi0_addr) self._decoder.add(self.spi0.cfg_bus, addr=spi0_cfg_addr) + + # Ethernet MAC + if ethmac_0_pins is not None and fpga in ['versa_ecp5', + 'versa_ecp5_85', + 'isim']: + # The OpenCores Ethernet MAC contains two independent Wishbone + # interfaces, a slave (configuration) interface and a master (DMA) + # interface. + self.eth0 = EthMAC(pins=ethmac_0_pins) + self._arbiter.add(self.eth0.master_bus) + self._decoder.add(self.eth0.slave_bus, addr=eth0_cfg_addr) + self.intc.add_irq(self.eth0.irq, index=eth0_irqno) + # HyperRAM modules *plural*. Assumes using a Quad PMOD by Piotr # Esden, sold by 1bitsquared, only doing one CS_N enable at the # moment @@ -522,6 +538,17 @@ class DDR3SoC(SoC, Elaboratable): print (fname) self.spi0.add_verilog_source(fname, platform) + if hasattr(self, "eth0"): + # add EthMAC verilog source. assumes a directory + # structure where the opencores ethmac has been checked out + # in a common subdirectory as https://github.com/freecores/ethmac + opencores_ethmac = "../../ethmac/rtl/verilog" + pth = os.path.split(__file__)[0] + pth = os.path.join(pth, opencores_ethmac) + fname = os.path.abspath(pth) + print (fname) + self.eth0.add_verilog_source(fname, platform) + # add the main core pth = os.path.split(__file__)[0] pth = os.path.join(pth, '../external_core_top.v') @@ -641,6 +668,19 @@ def build_platform(fpga, firmware): dir={"dq":"io", "cs_n":"o", "clk":"o"}, xdr={"dq": 1, "cs_n": 1, "clk": 0}) + # Get Ethernet RMII resource pins + ethmac_0_pins = None + if platform is not None and fpga in ['versa_ecp5', 'versa_ecp5_85', 'isim']: + ethmac_0_pins = platform.request("ethmac_0", 0, + dir={"mtx_clk":"i", "mtxd":"o", "mtxen":"o", + "mtxerr":"o", "mrx_clk":"i", "mrxd":"i", + "mrxdv":"i", "mrxerr":"i", "mcoll":"i", + "mcrs":"i", "mdc":"o", "md":"io"}, + xdr={"mtx_clk": 0, "mtxd": 0, "mtxen": 0, + "mtxerr": 0, "mrx_clk": 0, "mrxd": 0, + "mrxdv": 0, "mrxerr": 0, "mcoll": 0, + "mcrs": 0, "mdc": 0, "md": 0}) + # Get HyperRAM pins hyperram_pins = None if platform is None: @@ -683,12 +723,15 @@ def build_platform(fpga, firmware): ddr_addr=0x40000000, # DRAM_BASE spi0_addr=0x10000000, # SPI0_BASE spi0_cfg_addr=0xc0003000, # SPI0_CTRL_BASE + eth0_cfg_addr=0xc0004000, # ETH0_CTRL_BASE (4k) + eth0_irqno=0, # ETH0_IRQ number hyperram_addr=0xa0000000, # HYPERRAM_BASE fw_addr=fw_addr, #fw_addr=None, ddr_pins=ddr_pins, uart_pins=uart_pins, spi_0_pins=spi_0_pins, + ethmac_0_pins=ethmac_0_pins, hyperram_pins=hyperram_pins, firmware=firmware, clk_freq=clk_freq, -- 2.30.2