From: Luke Kenneth Casson Leighton Date: Sun, 13 Feb 2022 14:26:07 +0000 (+0000) Subject: rename examples to src X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=07a02428b2e8a38256e8bc0b988645e2676d89f0;p=ls2.git rename examples to src --- diff --git a/examples/crg.py b/examples/crg.py deleted file mode 100644 index eb3c651..0000000 --- a/examples/crg.py +++ /dev/null @@ -1,146 +0,0 @@ -# Copyright (c) 2020 LambdaConcept -# Copyright (c) 2021 Luke Kenneth Casson Leighton - -from nmigen import (Module, Elaboratable, Instance, Signal, ClockDomain, - ClockSignal, ResetSignal) - -__ALL__ = ["ECPIX5CRG"] - - -class PLL(Elaboratable): - def __init__(self, clkin, clksel=Signal(shape=2, reset=2), - clkout1=Signal(), clkout2=Signal(), - clkout3=Signal(), clkout4=Signal(), lock=Signal(), - CLKI_DIV=1, CLKFB_DIV=2, CLK1_DIV=3, CLK2_DIV=24): - self.clkin = clkin - self.clkout1 = clkout1 - self.clkout2 = clkout2 - self.clkout3 = clkout3 - self.clkout4 = clkout4 - self.clksel = clksel - self.lock = lock - self.CLKI_DIV = CLKI_DIV - self.CLKFB_DIV = CLKFB_DIV - self.CLKOP_DIV = CLK1_DIV - self.CLKOS_DIV = CLK2_DIV - self.ports = [ - self.clkin, - self.clkout1, - self.clkout2, - self.clkout3, - self.clkout4, - self.clksel, - self.lock, - ] - - def elaborate(self, platform): - clkfb = Signal() - pll = Instance("EHXPLLL", - p_OUTDIVIDER_MUXA='DIVA', - p_OUTDIVIDER_MUXB='DIVB', - p_CLKOP_ENABLE='ENABLED', - p_CLKOS_ENABLE='ENABLED', - p_CLKOS2_ENABLE='DISABLED', - p_CLKOS3_ENABLE='DISABLED', - p_CLKOP_DIV=self.CLKOP_DIV, - p_CLKOS_DIV=self.CLKOS_DIV, - p_CLKFB_DIV=self.CLKFB_DIV, - p_CLKI_DIV=self.CLKI_DIV, - p_FEEDBK_PATH='INT_OP', - p_CLKOP_TRIM_POL="FALLING", - p_CLKOP_TRIM_DELAY=0, - p_CLKOS_TRIM_POL="FALLING", - p_CLKOS_TRIM_DELAY=0, - i_CLKI=self.clkin, - i_RST=0, - i_STDBY=0, - i_PHASESEL0=0, - i_PHASESEL1=0, - i_PHASEDIR=0, - i_PHASESTEP=0, - i_PHASELOADREG=0, - i_PLLWAKESYNC=0, - i_ENCLKOP=1, - i_ENCLKOS=1, - i_ENCLKOS2=0, - i_ENCLKOS3=0, - o_CLKOP=self.clkout1, - o_CLKOS=self.clkout2, - o_CLKOS2=self.clkout3, - o_CLKOS3=self.clkout4, - o_LOCK=self.lock, - ) - m = Module() - m.submodules += pll - return m - - -class ECPIX5CRG(Elaboratable): - def __init__(self): - ... - - def elaborate(self, platform): - m = Module() - - # Get 100Mhz from oscillator - clk100 = platform.request("clk100") - cd_rawclk = ClockDomain("rawclk", local=True, reset_less=True) - m.d.comb += cd_rawclk.clk.eq(clk100) - m.domains += cd_rawclk - - # Reset - reset = platform.request(platform.default_rst).i - gsr0 = Signal() - gsr1 = Signal() - - m.submodules += [ - Instance("FD1S3AX", p_GSR="DISABLED", i_CK=ClockSignal("rawclk"), - i_D=~reset, o_Q=gsr0), - Instance("FD1S3AX", p_GSR="DISABLED", i_CK=ClockSignal("rawclk"), - i_D=gsr0, o_Q=gsr1), - Instance("SGSR", i_CLK=ClockSignal("rawclk"), i_GSR=gsr1), - ] - - # Power-on delay (655us) - podcnt = Signal(16, reset=2**16-1) - pod_done = Signal() - with m.If(podcnt != 0): - m.d.rawclk += podcnt.eq(podcnt-1) - m.d.rawclk += pod_done.eq(podcnt == 0) - - # Generating sync2x (200Mhz) and init (25Mhz) from clk100 - cd_sync2x = ClockDomain("sync2x", local=False) - cd_sync2x_unbuf = ClockDomain("sync2x_unbuf", local=False, - reset_less=True) - cd_init = ClockDomain("init", local=False) - cd_sync = ClockDomain("sync", local=False) - cd_dramsync = ClockDomain("dramsync", local=False) - m.submodules.pll = pll = PLL(ClockSignal("rawclk"), - CLKI_DIV=1, CLKFB_DIV=2, - CLK1_DIV=3, CLK2_DIV=24, - clkout1=ClockSignal("sync2x_unbuf"), - clkout2=ClockSignal("init")) - m.submodules += Instance("ECLKSYNCB", - i_ECLKI = ClockSignal("sync2x_unbuf"), - i_STOP = 0, - o_ECLKO = ClockSignal("sync2x")) - m.domains += cd_sync2x_unbuf - m.domains += cd_sync2x - m.domains += cd_init - m.domains += cd_sync - m.domains += cd_dramsync - m.d.comb += ResetSignal("init").eq(~pll.lock|~pod_done) - m.d.comb += ResetSignal("sync").eq(~pll.lock|~pod_done) - m.d.comb += ResetSignal("dramsync").eq(~pll.lock|~pod_done) - - # # Generating sync (100Mhz) from sync2x - - m.submodules += Instance("CLKDIVF", - p_DIV="2.0", - i_ALIGNWD=0, - i_CLKI=ClockSignal("sync2x"), - i_RST=0, - o_CDIVX=ClockSignal("sync")) - m.d.comb += ClockSignal("dramsync").eq(ClockSignal("sync")) - - return m diff --git a/examples/ls2.py b/examples/ls2.py deleted file mode 100644 index 711299e..0000000 --- a/examples/ls2.py +++ /dev/null @@ -1,200 +0,0 @@ -# Copyright (c) 2020 LambdaConcept -# Copyright (c) 2021 Luke Kenneth Casson Leighton -# -# 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 - self.uart = UART16550() - 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) - - # add uart16550 verilog source. assumes a directory - # structure where ls2 has been checked out in a common - # subdirectory as https://github.com/freecores/uart16550 - 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.add_verilog_source(fname, platform) - - 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/src/crg.py b/src/crg.py new file mode 100644 index 0000000..eb3c651 --- /dev/null +++ b/src/crg.py @@ -0,0 +1,146 @@ +# Copyright (c) 2020 LambdaConcept +# Copyright (c) 2021 Luke Kenneth Casson Leighton + +from nmigen import (Module, Elaboratable, Instance, Signal, ClockDomain, + ClockSignal, ResetSignal) + +__ALL__ = ["ECPIX5CRG"] + + +class PLL(Elaboratable): + def __init__(self, clkin, clksel=Signal(shape=2, reset=2), + clkout1=Signal(), clkout2=Signal(), + clkout3=Signal(), clkout4=Signal(), lock=Signal(), + CLKI_DIV=1, CLKFB_DIV=2, CLK1_DIV=3, CLK2_DIV=24): + self.clkin = clkin + self.clkout1 = clkout1 + self.clkout2 = clkout2 + self.clkout3 = clkout3 + self.clkout4 = clkout4 + self.clksel = clksel + self.lock = lock + self.CLKI_DIV = CLKI_DIV + self.CLKFB_DIV = CLKFB_DIV + self.CLKOP_DIV = CLK1_DIV + self.CLKOS_DIV = CLK2_DIV + self.ports = [ + self.clkin, + self.clkout1, + self.clkout2, + self.clkout3, + self.clkout4, + self.clksel, + self.lock, + ] + + def elaborate(self, platform): + clkfb = Signal() + pll = Instance("EHXPLLL", + p_OUTDIVIDER_MUXA='DIVA', + p_OUTDIVIDER_MUXB='DIVB', + p_CLKOP_ENABLE='ENABLED', + p_CLKOS_ENABLE='ENABLED', + p_CLKOS2_ENABLE='DISABLED', + p_CLKOS3_ENABLE='DISABLED', + p_CLKOP_DIV=self.CLKOP_DIV, + p_CLKOS_DIV=self.CLKOS_DIV, + p_CLKFB_DIV=self.CLKFB_DIV, + p_CLKI_DIV=self.CLKI_DIV, + p_FEEDBK_PATH='INT_OP', + p_CLKOP_TRIM_POL="FALLING", + p_CLKOP_TRIM_DELAY=0, + p_CLKOS_TRIM_POL="FALLING", + p_CLKOS_TRIM_DELAY=0, + i_CLKI=self.clkin, + i_RST=0, + i_STDBY=0, + i_PHASESEL0=0, + i_PHASESEL1=0, + i_PHASEDIR=0, + i_PHASESTEP=0, + i_PHASELOADREG=0, + i_PLLWAKESYNC=0, + i_ENCLKOP=1, + i_ENCLKOS=1, + i_ENCLKOS2=0, + i_ENCLKOS3=0, + o_CLKOP=self.clkout1, + o_CLKOS=self.clkout2, + o_CLKOS2=self.clkout3, + o_CLKOS3=self.clkout4, + o_LOCK=self.lock, + ) + m = Module() + m.submodules += pll + return m + + +class ECPIX5CRG(Elaboratable): + def __init__(self): + ... + + def elaborate(self, platform): + m = Module() + + # Get 100Mhz from oscillator + clk100 = platform.request("clk100") + cd_rawclk = ClockDomain("rawclk", local=True, reset_less=True) + m.d.comb += cd_rawclk.clk.eq(clk100) + m.domains += cd_rawclk + + # Reset + reset = platform.request(platform.default_rst).i + gsr0 = Signal() + gsr1 = Signal() + + m.submodules += [ + Instance("FD1S3AX", p_GSR="DISABLED", i_CK=ClockSignal("rawclk"), + i_D=~reset, o_Q=gsr0), + Instance("FD1S3AX", p_GSR="DISABLED", i_CK=ClockSignal("rawclk"), + i_D=gsr0, o_Q=gsr1), + Instance("SGSR", i_CLK=ClockSignal("rawclk"), i_GSR=gsr1), + ] + + # Power-on delay (655us) + podcnt = Signal(16, reset=2**16-1) + pod_done = Signal() + with m.If(podcnt != 0): + m.d.rawclk += podcnt.eq(podcnt-1) + m.d.rawclk += pod_done.eq(podcnt == 0) + + # Generating sync2x (200Mhz) and init (25Mhz) from clk100 + cd_sync2x = ClockDomain("sync2x", local=False) + cd_sync2x_unbuf = ClockDomain("sync2x_unbuf", local=False, + reset_less=True) + cd_init = ClockDomain("init", local=False) + cd_sync = ClockDomain("sync", local=False) + cd_dramsync = ClockDomain("dramsync", local=False) + m.submodules.pll = pll = PLL(ClockSignal("rawclk"), + CLKI_DIV=1, CLKFB_DIV=2, + CLK1_DIV=3, CLK2_DIV=24, + clkout1=ClockSignal("sync2x_unbuf"), + clkout2=ClockSignal("init")) + m.submodules += Instance("ECLKSYNCB", + i_ECLKI = ClockSignal("sync2x_unbuf"), + i_STOP = 0, + o_ECLKO = ClockSignal("sync2x")) + m.domains += cd_sync2x_unbuf + m.domains += cd_sync2x + m.domains += cd_init + m.domains += cd_sync + m.domains += cd_dramsync + m.d.comb += ResetSignal("init").eq(~pll.lock|~pod_done) + m.d.comb += ResetSignal("sync").eq(~pll.lock|~pod_done) + m.d.comb += ResetSignal("dramsync").eq(~pll.lock|~pod_done) + + # # Generating sync (100Mhz) from sync2x + + m.submodules += Instance("CLKDIVF", + p_DIV="2.0", + i_ALIGNWD=0, + i_CLKI=ClockSignal("sync2x"), + i_RST=0, + o_CDIVX=ClockSignal("sync")) + m.d.comb += ClockSignal("dramsync").eq(ClockSignal("sync")) + + return m diff --git a/src/ls2.py b/src/ls2.py new file mode 100644 index 0000000..711299e --- /dev/null +++ b/src/ls2.py @@ -0,0 +1,200 @@ +# Copyright (c) 2020 LambdaConcept +# Copyright (c) 2021 Luke Kenneth Casson Leighton +# +# 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 + self.uart = UART16550() + 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) + + # add uart16550 verilog source. assumes a directory + # structure where ls2 has been checked out in a common + # subdirectory as https://github.com/freecores/uart16550 + 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.add_verilog_source(fname, platform) + + 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)