make cpu optional (test purposes), make bios optional,
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Fri, 18 Feb 2022 13:43:55 +0000 (13:43 +0000)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Fri, 18 Feb 2022 13:43:55 +0000 (13:43 +0000)
start on adding SDRAM

Makefile
src/ls2.py

index fcb8127ee8c8755e9e30b3eb841b6a2a33512b4d..b547e2e05d56de4f83ec3468c5efba366d70b16a 100644 (file)
--- 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 \
index a904ee7d8e02cc0835ae5fba8eacc1abb9803f97..576ec96ea4a2bba3a9b3d529f089c38a0339d95c 100644 (file)
@@ -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