add MemoryMap to UART16550 (TODO, put that into UART16550 class)
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sun, 13 Feb 2022 14:13:51 +0000 (14:13 +0000)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sun, 13 Feb 2022 14:13:51 +0000 (14:13 +0000)
examples/ls2.py [new file with mode: 0644]
examples/soc.py [deleted file]

diff --git a/examples/ls2.py b/examples/ls2.py
new file mode 100644 (file)
index 0000000..09d4043
--- /dev/null
@@ -0,0 +1,195 @@
+# Copyright (c) 2020 LambdaConcept <contact@lambdaconcept.com>
+# Copyright (c) 2021 Luke Kenneth Casson Leighton <lkcl@lkcl.net>
+#
+# Based on code from LambaConcept, from the gram example which is BSD-2-License
+# https://github.com/jeanthom/gram/tree/master/examples
+#
+# Modifications for the Libre-SOC Project funded by NLnet and NGI POINTER
+# under EU Grants 871528 and 957073, under the LGPLv3+ License
+
+from nmigen import (Module, Elaboratable, DomainRenamer)
+from nmigen.lib.cdc import ResetSynchronizer
+from nmigen_soc import wishbone, memory
+from nmigen_soc.memory import MemoryMap
+from nmigen_stdio.serial import AsyncSerial
+
+from lambdasoc.cpu.minerva import MinervaCPU
+from lambdasoc.periph.intc import GenericInterruptController
+from lambdasoc.periph.sram import SRAMPeripheral
+from lambdasoc.periph.timer import TimerPeripheral
+from lambdasoc.periph import Peripheral
+from lambdasoc.soc.base import SoC
+from soc.bus.uart_16550 import UART16550 # opencores 16550 uart
+
+from gram.core import gramCore
+from gram.phy.ecp5ddrphy import ECP5DDRPHY
+from gram.modules import MT41K256M16
+from gram.frontend.wishbone import gramWishbone
+
+from nmigen_boards.versa_ecp5 import VersaECP5Platform
+from nmigen_boards.ulx3s import ULX3S_85F_Platform
+from nmigen_boards.arty_a7 import ArtyA7_100Platform
+from nmigen_boards.test.blinky import Blinky
+
+from crg import ECPIX5CRG
+
+import sys
+import os
+
+
+class DDR3SoC(SoC, Elaboratable):
+    def __init__(self, *,
+                 uart_pins, ddr_pins,
+                 ddrphy_addr, dramcore_addr,
+                 ddr_addr, fw_addr=0x0000_0000,
+                 firmware=None,
+                 clk_freq=40e6):
+
+        # set up wishbone bus arbiter and decoder. arbiter routes,
+        # decoder maps local-relative addressed satellites to global addresses
+        self._arbiter = wishbone.Arbiter(addr_width=30, data_width=32,
+                                         granularity=8,
+                                         features={"cti", "bte"})
+        self._decoder = wishbone.Decoder(addr_width=30, data_width=32,
+                                         granularity=8,
+                                         features={"cti", "bte"})
+
+        # default firmware name
+        if firmware is None:
+            firmware = "firmware/main.bin"
+
+        # set up clock request generator
+        self.crg = ECPIX5CRG()
+
+        # set up CPU, and interrupt interface
+        if False:
+            self.cpu = MinervaCPU(reset_address=0)
+            self._arbiter.add(self.cpu.ibus) # I-Cache Master
+            self._arbiter.add(self.cpu.dbus) # D-Cache Master. TODO JTAG master
+            self.intc = GenericInterruptController(width=len(self.cpu.ip))
+
+        # SRAM (but actually a ROM, for firmware), at address 0x0
+        if fw_addr is not None:
+            self.rom = SRAMPeripheral(size=4096, writable=False)
+            with open(firmware, "rb") as f:
+                words = iter(lambda: f.read(self.cpu.data_width // 8), b'')
+                bios  = [int.from_bytes(w, self.cpu.byteorder) for w in words]
+            self.rom.init = bios
+            self._decoder.add(self.rom.bus, addr=fw_addr) # ROM at fw_addr
+
+        # SRAM (read-writeable BRAM)
+        self.ram = SRAMPeripheral(size=4096)
+        self._decoder.add(self.ram.bus, addr=0x8000000) # SRAM at 0x8000_000
+
+        # UART
+        opencores_16550 = "../../uart16550/rtl/verilog"
+        pth = os.path.split(__file__)[0]
+        pth = os.path.join(pth, opencores_16550)
+        fname = os.path.abspath(pth)
+        print (fname)
+        self.uart = UART16550(verilog_src_dir=fname)
+        umap = MemoryMap(addr_width=7, data_width=8, name="uart_map")
+        #umap.add_resource(self._mem, name="mem", size=1<<5)
+        self.uart.bus.memory_map = umap
+
+        self._decoder.add(self.uart.bus, addr=0xc0002000) # 16550 UART address
+
+        # DRAM Module
+        self.ddrphy = DomainRenamer("dramsync")(ECP5DDRPHY(ddr_pins,
+                                                sys_clk_freq=100e6))
+        self._decoder.add(self.ddrphy.bus, addr=ddrphy_addr)
+
+        ddrmodule = MT41K256M16(clk_freq, "1:2") # match DDR3 ASIC P/N
+
+        drs = DomainRenamer("dramsync")
+        dramcore = gramCore(phy=self.ddrphy,
+                            geom_settings=ddrmodule.geom_settings,
+                            timing_settings=ddrmodule.timing_settings,
+                            clk_freq=clk_freq)
+        self.dramcore = drs(dramcore)
+        self._decoder.add(self.dramcore.bus, addr=dramcore_addr)
+
+        # map the DRAM onto Wishbone
+        self.drambone = drs(gramWishbone(self.dramcore))
+        self._decoder.add(self.drambone.bus, addr=ddr_addr)
+
+        self.memory_map = self._decoder.bus.memory_map
+
+        self.clk_freq = clk_freq
+
+    def elaborate(self, platform):
+        m = Module()
+        comb = m.d.comb
+
+        # add the peripherals and clock-reset-generator
+        m.submodules.sysclk = self.crg
+
+        if hasattr(self, "rom"):
+            m.submodules.rom = self.rom
+        m.submodules.ram = self.ram
+        m.submodules.uart = self.uart
+        if False:
+            m.submodules.intc = self.intc
+            m.submodules.cpu = self.cpu
+        m.submodules.arbiter = self._arbiter
+        m.submodules.decoder = self._decoder
+        m.submodules.ddrphy = self.ddrphy
+        m.submodules.dramcore = self.dramcore
+        m.submodules.drambone = self.drambone
+
+        # add blinky lights so we know FPGA is alive
+        m.submodules.blinky = Blinky()
+
+        # connect the arbiter (of wishbone masters)
+        # to the decoder (addressing wishbone slaves)
+        comb += self._arbiter.bus.connect(self._decoder.bus)
+
+        if False:
+            # wire up the CPU interrupts
+            comb += self.cpu.ip.eq(self.intc.ip)
+
+        return m
+
+
+if __name__ == "__main__":
+
+    # create a platform selected from the toolchain. defaults to VERSA_ECP5
+    # only VERSA_ECP5 will work for now because of the DDR3 module
+    fpga = "versa_ecp5"
+    if len(sys.argv) >= 2:
+        fpga = sys.argv[1]
+    platform_kls =  {'versa_ecp5': VersaECP5Platform,
+                     'ulx3s': ULX3S_85F_Platform,
+                     'arty_a7': ArtyA7_100Platform,
+                    }[fpga]
+    toolchain = {'arty_a7': "yosys_nextpnr",
+                 'versa_ecp5': 'Trellis',
+                 'ulx3s': 'Trellis'
+                }.get(fpga, None)
+    platform = platform_kls(toolchain=toolchain)
+
+    # select a firmware file
+    firmware = None
+    fw_addr = None
+    if len(sys.argv) >= 3:
+        firmware = sys.argv[2]
+        fw_addr = 0x0000_0000
+
+    # get DDR and UART resource pins
+    ddr_pins = platform.request("ddr3", 0,
+                                dir={"dq":"-", "dqs":"-"},
+                                xdr={"clk":4, "a":4, "ba":4, "clk_en":4,
+                                     "odt":4, "ras":4, "cas":4, "we":4})
+    uart_pins = platform.request("uart", 0)
+
+    # set up the SOC
+    soc = DDR3SoC(ddrphy_addr=0xff000000, # DRAM firmware init base
+                  dramcore_addr=0x80000000,
+                  ddr_addr=0x10000000,
+                  fw_addr=fw_addr,
+                  ddr_pins=ddr_pins,
+                  uart_pins=uart_pins,
+                  firmware=firmware)
+
+    # build and upload it
+    platform.build(soc, do_program=True)
diff --git a/examples/soc.py b/examples/soc.py
deleted file mode 100644 (file)
index 54ffdd3..0000000
+++ /dev/null
@@ -1,188 +0,0 @@
-# Copyright (c) 2020 LambdaConcept <contact@lambdaconcept.com>
-# Copyright (c) 2021 Luke Kenneth Casson Leighton <lkcl@lkcl.net>
-#
-# Based on code from LambaConcept, from the gram example which is BSD-2-License
-# https://github.com/jeanthom/gram/tree/master/examples
-#
-# Modifications for the Libre-SOC Project funded by NLnet and NGI POINTER
-# under EU Grants 871528 and 957073, under the LGPLv3+ License
-
-from soc.bus.uart_16550 import UART16550 # opencores 16550 uart
-from nmigen import (Module, Elaboratable, DomainRenamer)
-from nmigen.lib.cdc import ResetSynchronizer
-from nmigen_soc import wishbone, memory
-from nmigen_stdio.serial import AsyncSerial
-
-from lambdasoc.cpu.minerva import MinervaCPU
-from lambdasoc.periph.intc import GenericInterruptController
-from lambdasoc.periph.sram import SRAMPeripheral
-from lambdasoc.periph.timer import TimerPeripheral
-from lambdasoc.periph import Peripheral
-from lambdasoc.soc.base import SoC
-
-from gram.core import gramCore
-from gram.phy.ecp5ddrphy import ECP5DDRPHY
-from gram.modules import MT41K256M16
-from gram.frontend.wishbone import gramWishbone
-
-from nmigen_boards.versa_ecp5 import VersaECP5Platform
-from nmigen_boards.ulx3s import ULX3S_85F_Platform
-from nmigen_boards.arty_a7 import ArtyA7_100Platform
-from nmigen_boards.test.blinky import Blinky
-
-from crg import ECPIX5CRG
-
-import sys
-import os
-
-
-class DDR3SoC(SoC, Elaboratable):
-    def __init__(self, *,
-                 uart_pins, ddr_pins,
-                 ddrphy_addr, dramcore_addr,
-                 ddr_addr, fw_addr=0x0000_0000,
-                 firmware=None,
-                 clk_freq=40e6):
-
-        # set up wishbone bus arbiter and decoder. arbiter routes,
-        # decoder maps local-relative addressed satellites to global addresses
-        self._arbiter = wishbone.Arbiter(addr_width=30, data_width=32,
-                                         granularity=8,
-                                         features={"cti", "bte"})
-        self._decoder = wishbone.Decoder(addr_width=30, data_width=32,
-                                         granularity=8,
-                                         features={"cti", "bte"})
-
-        # default firmware name
-        if firmware is None:
-            firmware = "firmware/main.bin"
-
-        # set up clock request generator
-        self.crg = ECPIX5CRG()
-
-        if False:
-            # set up CPU, and interrupt interface
-            self.cpu = MinervaCPU(reset_address=0)
-            self._arbiter.add(self.cpu.ibus) # I-Cache Master
-            self._arbiter.add(self.cpu.dbus) # D-Cache Master. TODO JTAG master
-            self.intc = GenericInterruptController(width=len(self.cpu.ip))
-
-        # SRAM (but actually a ROM, for firmware), at address 0x0
-        if fw_addr is not None:
-            self.rom = SRAMPeripheral(size=4096, writable=False)
-            with open(firmware, "rb") as f:
-                words = iter(lambda: f.read(self.cpu.data_width // 8), b'')
-                bios  = [int.from_bytes(w, self.cpu.byteorder) for w in words]
-            self.rom.init = bios
-            self._decoder.add(self.rom.bus, addr=fw_addr) # ROM at fw_addr
-
-        # SRAM (read-writeable BRAM)
-        self.ram = SRAMPeripheral(size=4096)
-        self._decoder.add(self.ram.bus, addr=0x8000000) # SRAM at 0x8000_000
-
-        # UART
-        opencores_16550 = "../../uart16550/rtl/verilog"
-        pth = __file__
-        print (pth)
-        self.uart = UART16550(verilog_src_dir=opencores_16550)
-        self._decoder.add(self.uart.bus, addr=0xc0002000) # 16550 UART address
-
-        # DRAM Module
-        self.ddrphy = DomainRenamer("dramsync")(ECP5DDRPHY(ddr_pins,
-                                                sys_clk_freq=100e6))
-        self._decoder.add(self.ddrphy.bus, addr=ddrphy_addr)
-
-        ddrmodule = MT41K256M16(clk_freq, "1:2") # match DDR3 ASIC P/N
-
-        drs = DomainRenamer("dramsync")
-        dramcore = gramCore(phy=self.ddrphy,
-                            geom_settings=ddrmodule.geom_settings,
-                            timing_settings=ddrmodule.timing_settings,
-                            clk_freq=clk_freq)
-        self.dramcore = drs(dramcore)
-        self._decoder.add(self.dramcore.bus, addr=dramcore_addr)
-
-        # map the DRAM onto Wishbone
-        self.drambone = drs(gramWishbone(self.dramcore))
-        self._decoder.add(self.drambone.bus, addr=ddr_addr)
-
-        self.memory_map = self._decoder.bus.memory_map
-
-        self.clk_freq = clk_freq
-
-    def elaborate(self, platform):
-        m = Module()
-        comb = m.d.comb
-
-        # add the peripherals and clock-reset-generator
-        m.submodules.sysclk = self.crg
-
-        if hasattr(self, "rom"):
-            m.submodules.rom = self.rom
-        m.submodules.ram = self.ram
-        m.submodules.uart = self.uart
-        if False:
-            m.submodules.intc = self.intc
-            m.submodules.cpu = self.cpu
-        m.submodules.arbiter = self._arbiter
-        m.submodules.decoder = self._decoder
-        m.submodules.ddrphy = self.ddrphy
-        m.submodules.dramcore = self.dramcore
-        m.submodules.drambone = self.drambone
-
-        # add blinky lights so we know FPGA is alive
-        m.submodules.blinky = Blinky()
-
-        # connect the arbiter (of wishbone masters)
-        # to the decoder (addressing wishbone slaves)
-        comb += self._arbiter.bus.connect(self._decoder.bus)
-
-        if False:
-            # wire up the CPU interrupts
-            comb += self.cpu.ip.eq(self.intc.ip)
-
-        return m
-
-
-if __name__ == "__main__":
-
-    # create a platform selected from the toolchain. defaults to VERSA_ECP5
-    # only VERSA_ECP5 will work for now because of the DDR3 module
-    fpga = "versa_ecp5"
-    if len(sys.argv) >= 2:
-        fpga = sys.argv[1]
-    platform_kls =  {'versa_ecp5': VersaECP5Platform,
-                     'ulx3s': ULX3S_85F_Platform,
-                     'arty_a7': ArtyA7_100Platform,
-                    }[fpga]
-    toolchain = {'arty_a7': "yosys_nextpnr",
-                 'versa_ecp5': 'Trellis',
-                 'ulx3s': 'Trellis'
-                }.get(fpga, None)
-    platform = platform_kls(toolchain=toolchain)
-
-    # select a firmware file
-    firmware = None
-    fw_addr = None
-    if len(sys.argv) >= 3:
-        firmware = sys.argv[2]
-        fw_addr = 0x0000_0000
-
-    # get DDR and UART resource pins
-    ddr_pins = platform.request("ddr3", 0,
-                                dir={"dq":"-", "dqs":"-"},
-                                xdr={"clk":4, "a":4, "ba":4, "clk_en":4,
-                                     "odt":4, "ras":4, "cas":4, "we":4})
-    uart_pins = platform.request("uart", 0)
-
-    # set up the SOC
-    soc = DDR3SoC(ddrphy_addr=0xff000000, # DRAM firmware init base
-                  dramcore_addr=0x80000000,
-                  ddr_addr=0x10000000,
-                  fw_addr=fw_addr,
-                  ddr_pins=ddr_pins,
-                  uart_pins=uart_pins,
-                  firmware=firmware)
-
-    # build and upload it
-    platform.build(soc, do_program=True)