Add initial integration for OpenCores 10/100 Ethernet MAC
authorRaptor Engineering Development Team <support@raptorengineering.com>
Tue, 29 Mar 2022 01:11:43 +0000 (20:11 -0500)
committerRaptor Engineering Development Team <support@raptorengineering.com>
Tue, 29 Mar 2022 01:11:43 +0000 (20:11 -0500)
src/ls2.py

index 235caf89689d1a3f9d86bd085725a757685be9d8..f9f61cc3d5e94505435aafe1741bbe0fa3583680 100644 (file)
@@ -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,