From: Luke Kenneth Casson Leighton Date: Mon, 14 Feb 2022 10:34:48 +0000 (+0000) Subject: add verilog build option, make DDR3 PHY optional, add UART pins X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=2c35e5716c5239d0bce4bee08733029e451c1d08;p=ls2.git add verilog build option, make DDR3 PHY optional, add UART pins --- diff --git a/src/ls2.py b/src/ls2.py index 362dfa5..c39ca5d 100644 --- a/src/ls2.py +++ b/src/ls2.py @@ -7,7 +7,8 @@ # 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 import (Module, Elaboratable, DomainRenamer, Record) +from nmigen.cli import verilog from nmigen.lib.cdc import ResetSynchronizer from nmigen_soc import wishbone, memory from nmigen_soc.memory import MemoryMap @@ -82,31 +83,32 @@ class DDR3SoC(SoC, Elaboratable): 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 + if uart_pins is not None: + 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 addr # DRAM Module - self.ddrphy = DomainRenamer("dramsync")(ECP5DDRPHY(ddr_pins, - sys_clk_freq=100e6)) - self._decoder.add(self.ddrphy.bus, addr=ddrphy_addr) + if ddr_pins is not None: + 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 + 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) + 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) + # 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 @@ -117,7 +119,8 @@ class DDR3SoC(SoC, Elaboratable): comb = m.d.comb # add the peripherals and clock-reset-generator - m.submodules.sysclk = self.crg + if platform is not None: + m.submodules.sysclk = self.crg if hasattr(self, "rom"): m.submodules.rom = self.rom @@ -128,12 +131,14 @@ class DDR3SoC(SoC, Elaboratable): 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 + if hasattr(self, "ddrphy"): + 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() + if platform is not None: + m.submodules.blinky = Blinky() # connect the arbiter (of wishbone masters) # to the decoder (addressing wishbone slaves) @@ -146,15 +151,22 @@ class DDR3SoC(SoC, Elaboratable): # 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) + if platform is not None: + 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 + def ports(self): + # puzzlingly the only IO ports needed are peripheral pins, + # and at the moment that's just UART tx/rx. + ports = [] + ports += [self.uart.tx_o, self.uart.rx_i] + return ports if __name__ == "__main__": @@ -175,6 +187,8 @@ if __name__ == "__main__": }.get(fpga, None) if platform_kls is not None: platform = platform_kls(toolchain=toolchain) + else: + platform = None # select a firmware file firmware = None @@ -190,6 +204,9 @@ if __name__ == "__main__": xdr={"clk":4, "a":4, "ba":4, "clk_en":4, "odt":4, "ras":4, "cas":4, "we":4}) uart_pins = platform.request("uart", 0) + else: + ddr_pins = None + uart_pins = Record([('tx', 1), ('rx', 1)], name="uart_0") # set up the SOC soc = DDR3SoC(ddrphy_addr=0xff000000, # DRAM firmware init base @@ -200,5 +217,12 @@ if __name__ == "__main__": uart_pins=uart_pins, firmware=firmware) - # build and upload it - platform.build(soc, do_program=True) + if platform is not None: + # build and upload it + platform.build(soc, do_program=True) + else: + # for now, generate verilog + vl = verilog.convert(soc, ports=soc.ports()) + with open("test_ls2.v", "w") as f: + f.write(vl) +