Rework LiteDRAM wishbone frontend (wip)
authorJean THOMAS <git0@pub.jeanthomas.me>
Tue, 9 Jun 2020 09:45:17 +0000 (11:45 +0200)
committerJean THOMAS <git0@pub.jeanthomas.me>
Tue, 9 Jun 2020 09:45:17 +0000 (11:45 +0200)
examples/ecpix5.py
gram/frontend/wishbone.py

index 3848436de26ef3e2a77c2d6439e348ed75199480..6fe9ae9cede76a7cb042da26025591d64846fe6a 100644 (file)
@@ -14,6 +14,7 @@ from lambdasoc.soc.cpu import CPUSoC
 from gram.core import gramCore
 from gram.phy.ecp5ddrphy import ECP5DDRPHY
 from gram.modules import MT41K256M16
+from gram.frontend.wishbone import gramWishbone
 
 from customecpix5 import ECPIX5Platform
 
@@ -113,7 +114,8 @@ class DDR3SoC(CPUSoC, Elaboratable):
                                 ram_addr, ram_size,
                                 uart_addr, uart_divisor, uart_pins,
                                 timer_addr, timer_width,
-                                ddrphy_addr, dramcore_addr):
+                                ddrphy_addr, dramcore_addr,
+                                ddr_addr):
                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,
@@ -154,7 +156,8 @@ class DDR3SoC(CPUSoC, Elaboratable):
                        clk_freq = clk_freq)
                self._decoder.add(self.dramcore.bus, addr=dramcore_addr)
 
-               self.dramport = self.dramcore.crossbar.get_port()
+               self.drambone = gramWishbone(self.dramcore)
+               self._decoder.add(self.drambone.bus, addr=ddr_addr)
 
                self.memory_map = self._decoder.bus.memory_map
 
@@ -174,6 +177,7 @@ class DDR3SoC(CPUSoC, Elaboratable):
                m.submodules.intc    = self.intc
                m.submodules.ddrphy  = self.ddrphy
                m.submodules.dramcore = self.dramcore
+               m.submodules.drambone = self.drambone
 
                m.submodules.sysclk = SysClocker()
 
@@ -198,7 +202,8 @@ if __name__ == "__main__":
                   ram_addr=0x00004000, ram_size=0x1000,
                  uart_addr=0x00005000, uart_divisor=uart_divisor, uart_pins=uart_pins,
                 timer_addr=0x00006000, timer_width=32,
-               ddrphy_addr=0x00008000, dramcore_addr=0x00009000
+               ddrphy_addr=0x00008000, dramcore_addr=0x00009000,
+                  ddr_addr=0x10000000
        )
 
        soc.build(do_build=True, do_init=True)
index f3e6ea3940edea6ac3cf6dd8dabd9462a7718547..25154b3196bfd17556b04e750a6dc56cb21f0060 100644 (file)
@@ -1,81 +1,49 @@
-# This file is Copyright (c) 2016-2020 Florent Kermarrec <florent@enjoy-digital.fr>
+# This file is Copyright (c) 2020 LambdaConcept <contact@lambdaconcept.com>
 # License: BSD
 
-"""Wishbone frontend for LiteDRAM"""
-
-from math import log2
-
 from nmigen import *
+from nmigen.utils import log2_int
 
-import gram.stream as stream
+from nmigen_soc import wishbone
+from nmigen_soc.memory import MemoryMap
+from lambdasoc.periph import Peripheral
 
+class gramWishbone(Peripheral, Elaboratable):
+    def __init__(self, core):
+        super().__init__()
 
-# LiteDRAMWishbone2Native --------------------------------------------------------------------------
+        self._port = core.crossbar.get_port()
 
-class LiteDRAMWishbone2Native(Module):
-    def __init__(self, wishbone, port, base_address=0x00000000):
-        wishbone_data_width = len(wishbone.dat_w)
-        port_data_width     = 2**int(log2(len(port.wdata.data))) # Round to lowest power 2
-        assert wishbone_data_width >= port_data_width
+        dram_size = core.size//4
+        dram_addr_width = log2_int(dram_size)
+        granularity = 8
 
-        # # #
+        self.bus = wishbone.Interface(addr_width=dram_addr_width,
+            data_width=32, granularity=granularity)
 
-        adr_offset = base_address >> log2_int(port.data_width//8)
+        map = MemoryMap(addr_width=dram_addr_width, data_width=granularity)
+        map.add_resource(self, size=dram_size)
+        self.bus.memory_map = map
 
-        # Write Datapath ---------------------------------------------------------------------------
-        wdata_converter = stream.StrideConverter(
-            [("data", wishbone_data_width), ("we", wishbone_data_width//8)],
-            [("data", port_data_width),     ("we", port_data_width//8)],
-        )
-        self.submodules += wdata_converter
-        self.comb += [
-            wdata_converter.sink.valid.eq(wishbone.cyc & wishbone.stb & wishbone.we),
-            wdata_converter.sink.data.eq(wishbone.dat_w),
-            wdata_converter.sink.we.eq(wishbone.sel),
-            wdata_converter.source.connect(port.wdata)
-        ]
+    def elaborate(self, platform):
+        m = Module()
 
-        # Read Datapath ----------------------------------------------------------------------------
-        rdata_converter = stream.StrideConverter(
-            [("data", port_data_width)],
-            [("data", wishbone_data_width)],
-        )
-        self.submodules += rdata_converter
-        self.comb += [
-            port.rdata.connect(rdata_converter.sink),
-            rdata_converter.source.ready.eq(1),
-            wishbone.dat_r.eq(rdata_converter.source.data),
-        ]
-
-        # Control ----------------------------------------------------------------------------------
         ratio = wishbone_data_width//port_data_width
         count = Signal(max=max(ratio, 2))
-        self.submodules.fsm = fsm = FSM(reset_state="CMD")
-        fsm.act("CMD",
-            port.cmd.valid.eq(wishbone.cyc & wishbone.stb),
-            port.cmd.we.eq(wishbone.we),
-            port.cmd.addr.eq(wishbone.adr*ratio + count - adr_offset),
-            If(port.cmd.valid & port.cmd.ready,
-                NextValue(count, count + 1),
-                If(count == (ratio - 1),
-                    NextValue(count, 0),
-                    If(wishbone.we,
-                        NextState("WAIT-WRITE")
-                    ).Else(
-                        NextState("WAIT-READ")
-                    )
-                )
-            )
-        )
-        fsm.act("WAIT-WRITE",
-            If(wdata_converter.sink.ready,
-                wishbone.ack.eq(1),
-                NextState("CMD")
-            )
-        )
-        fsm.act("WAIT-READ",
-            If(rdata_converter.source.valid,
-               wishbone.ack.eq(1),
-               NextState("CMD")
-            )
-        )
+        with m.FSM():
+            with m.State("Send-Cmd"):
+                m.d.comb += [
+                    port.cmd.valid.eq(self.bus.cyc & self.bus.stb),
+                    port.cmd.we.eq(self.bus.we),
+                    port.cmd.addr.eq(self.bus.adr*ratio + count - adr_offset),
+                ]
+                with m.If(port.cmd.valid & port.cmd.ready):
+
+
+        #   with m.State("Write"):
+        #       ...
+
+        #   with m.State("Read"):
+        #       ...
+
+        return m