From 35eaede046b9d6a2c82eb6be45765f205245dd98 Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Fri, 18 Feb 2022 13:43:55 +0000 Subject: [PATCH] make cpu optional (test purposes), make bios optional, start on adding SDRAM --- Makefile | 2 +- src/ls2.py | 81 ++++++++++++++++++++++++++++++++++++------------------ 2 files changed, 56 insertions(+), 27 deletions(-) diff --git a/Makefile b/Makefile index fcb8127..b547e2e 100644 --- a/Makefile +++ b/Makefile @@ -60,7 +60,7 @@ microwatt-verilator: ls2.v \ --assert \ --top-module top \ --cc ls2.v \ - --cc ../soc/src/soc/external_core_top.v \ + --cc external_core_top.v \ --exe verilator/microwatt-verilator.cpp verilator/uart-verilator.c \ -o $@ -I../uart16550/rtl/verilog \ -Wno-fatal -Wno-CASEOVERLAP -Wno-UNOPTFLAT \ diff --git a/src/ls2.py b/src/ls2.py index a904ee7..576ec96 100644 --- a/src/ls2.py +++ b/src/ls2.py @@ -47,7 +47,8 @@ class DDR3SoC(SoC, Elaboratable): ddrphy_addr, dramcore_addr, ddr_addr, fw_addr=0x0000_0000, firmware=None, - clk_freq=50e6): + clk_freq=50e6, + add_cpu=True): # set up wishbone bus arbiter and decoder. arbiter routes, # decoder maps local-relative addressed satellites to global addresses @@ -66,28 +67,30 @@ class DDR3SoC(SoC, Elaboratable): self.crg = ECPIX5CRG(clk_freq) # set up CPU, with 64-to-32-bit downconverters - self.cpu = ExternalCore(name="ext_core") - cvtdbus = wishbone.Interface(addr_width=30, data_width=32, - granularity=8) - cvtibus = wishbone.Interface(addr_width=30, data_width=32, - granularity=8) - self.dbusdowncvt = WishboneDownConvert(self.cpu.dbus, cvtdbus) - self.ibusdowncvt = WishboneDownConvert(self.cpu.ibus, cvtibus) - self._arbiter.add(cvtibus) # I-Cache Master - self._arbiter.add(cvtdbus) # D-Cache Master. TODO JTAG master - - # CPU interrupt controller - self.intc = GenericInterruptController(width=len(self.cpu.irq)) + if add_cpu: + self.cpu = ExternalCore(name="ext_core") + cvtdbus = wishbone.Interface(addr_width=30, data_width=32, + granularity=8) + cvtibus = wishbone.Interface(addr_width=30, data_width=32, + granularity=8) + self.dbusdowncvt = WishboneDownConvert(self.cpu.dbus, cvtdbus) + self.ibusdowncvt = WishboneDownConvert(self.cpu.ibus, cvtibus) + self._arbiter.add(cvtibus) # I-Cache Master + self._arbiter.add(cvtdbus) # D-Cache Master. TODO JTAG master + + # CPU interrupt controller + self.intc = GenericInterruptController(width=len(self.cpu.irq)) # SRAM (but actually a ROM, for firmware), at address 0x0 if fw_addr is not None: sram_width = 32 self.bootmem = SRAMPeripheral(size=0x8000, data_width=sram_width, writable=True) - with open(firmware, "rb") as f: - words = iter(lambda: f.read(sram_width // 8), b'') - bios = [int.from_bytes(w, "little") for w in words] - self.bootmem.init = bios + if firmware is not None: + with open(firmware, "rb") as f: + words = iter(lambda: f.read(sram_width // 8), b'') + bios = [int.from_bytes(w, "little") for w in words] + self.bootmem.init = bios self._decoder.add(self.bootmem.bus, addr=fw_addr) # ROM at fw_addr # System Configuration info @@ -112,6 +115,26 @@ class DDR3SoC(SoC, Elaboratable): self._decoder.add(cvtuartbus, addr=0xc0002000) # 16550 UART addr self.cvtuartbus = cvtuartbus + # SDRAM module using opencores sdr_ctrl + """ + class MT48LC16M16(SDRModule): + # geometry + nbanks = 4 + nrows = 8192 + ncols = 512 + # timings + technology_timings = _TechnologyTimings(tREFI=64e6/8192, + tWTR=(2, None), + tCCD=(1, None), + tRRD=(None, 15)) + speedgrade_timings = {"default": _SpeedgradeTimings(tRP=20, + tRCD=20, + tWR=15, + tRFC=(None, 66), + tFAW=None, + tRAS=44)} + """ + # DRAM Module if ddr_pins is not None: self.ddrphy = DomainRenamer("dramsync")(ECP5DDRPHY(ddr_pins, @@ -220,6 +243,8 @@ class DDR3SoC(SoC, Elaboratable): # and at the moment that's just UART tx/rx. ports = [] ports += [self.uart.tx_o, self.uart.rx_i] + if hasattr(self, "ddrphy"): + ports += list(self.ddrphy.pads.fields.values()) return ports if __name__ == "__main__": @@ -251,27 +276,31 @@ if __name__ == "__main__": firmware = sys.argv[2] fw_addr = 0x0000_0000 - ddr_pins = None + # get UART resource pins if platform is not None: - # get DDR and UART resource pins - if False: - 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) else: uart_pins = Record([('tx', 1), ('rx', 1)], name="uart_0") + # get DDR resource pins + ddr_pins = None + if False and platform is not None and fpga in ['versa_ecp5', 'arty_a7']: + 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}) + # set up the SOC soc = DDR3SoC(ddrphy_addr=0xff000000, # DRAM firmware init base dramcore_addr=0x80000000, ddr_addr=0x10000000, - fw_addr=fw_addr, + #fw_addr=fw_addr, + fw_addr=None, ddr_pins=ddr_pins, uart_pins=uart_pins, firmware=firmware, - clk_freq=25e6) + clk_freq=50e6, + add_cpu=True) #if toolchain == 'Trellis': # add -abc9 option to yosys synth_ecp5 -- 2.30.2