add new dram_clk_freq argument which does nothing for now
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Thu, 14 Apr 2022 10:45:43 +0000 (11:45 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Thu, 14 Apr 2022 10:45:43 +0000 (11:45 +0100)
leaves the dramsync/dramsync2x domains as "aliases" for sync/sync2x
but if set, it will create a *second* completely separate domain
at the requested frequency, along with a separate 2x that can then
be used on IOpads with "xdr=4" settings

src/ecp5_crg.py
src/ls2.py

index 239a5e624845881746cb563689aec174643fab0d..72c1af5685f196deab60e4fdb11ba7fdde916e74 100644 (file)
@@ -169,11 +169,15 @@ class PLL(Elaboratable):
 
 
 class ECP5CRG(Elaboratable):
-    def __init__(self, sys_clk_freq=100e6, pod_bits=25):
+    def __init__(self, sys_clk_freq=100e6, dram_clk_freq=None, pod_bits=25):
+        """when dram_clk_freq=None, a dramsync domain is still created
+        but it is an alias of sync domain.  likewise the 2x
+        """
         self.sys_clk_freq = sys_clk_freq
+        self.dram_clk_freq = dram_clk_freq
         self.pod_bits = pod_bits
 
-    def do_2x_phase_clock_create(self, m, pll, name, freq):
+    def phase2_domain(self, m, pll, name, freq):
         """creates a domain that can be used with xdr=4 platform resources.
 
         this requires creating a domain at *twice* the frequency,
@@ -263,27 +267,24 @@ class ECP5CRG(Elaboratable):
 
         # Generating sync2x and sync from extclk, which is *only* how
         # xdr=4 can be requested on the sync domain
-        self.do_2x_phase_clock_create(m, pll, "sync", self.sys_clk_freq)
+        self.phase2_domain(m, pll, "sync", self.sys_clk_freq)
         m.d.comb += ResetSignal("sync").eq(reset_ok)
 
-        # temporarily set dram sync clock exactly equal to main sync,
-        # which turns out to be a dog's dinner botch-job, because
-        # GRAM's ECP5PHY uses dramsync for the pads.o_clk but
-        # sync2x for the pads.o_fclk. sigh.
-        # TODO: this to be replaced with
-        # self.do_2x_phase_clock_create(m, pll, "dramsync", self.dram_clk_freq)
-        # and then a suitable DomainRenamer for *both* dramsync *and*
-        # dramsync2x applied
-        cd_dramsync = ClockDomain("dramsync", local=False)
-        m.domains += cd_dramsync
-        m.d.comb += ClockSignal("dramsync").eq(ClockSignal("sync"))
-        m.d.comb += ResetSignal("dramsync").eq(reset_ok)
-
-        # and a dram 2x sigh
-        cd_dramsync2x = ClockDomain("dramsync2x", local=False)
-        m.domains += cd_dramsync2x
-        m.d.comb += ClockSignal("dramsync2x").eq(ClockSignal("sync2x"))
+        if self.dram_clk_freq is not None:
+            self.phase2_domain(m, pll, "dramsync", self.dram_clk_freq)
+        else:
+            # alias dramsync and dramsync2x to sync and sync2x
+            cd_dramsync = ClockDomain("dramsync", local=False)
+            m.domains += cd_dramsync
+            m.d.comb += ClockSignal("dramsync").eq(ClockSignal("sync"))
+            # and a dram 2x sigh
+            cd_dramsync2x = ClockDomain("dramsync2x", local=False)
+            m.domains += cd_dramsync2x
+            m.d.comb += ClockSignal("dramsync2x").eq(ClockSignal("sync2x"))
+
+        # resets for the dram domains
         m.d.comb += ResetSignal("dramsync2x").eq(reset_ok)
+        m.d.comb += ResetSignal("dramsync").eq(reset_ok)
 
         return m
 
index 6bee6d6446f0836f2ef9699b0cbfa45b4d154018..045ea4bcb43bd2d8c9cc6b7e5b078381905d9645 100644 (file)
@@ -369,7 +369,6 @@ class DDR3SoC(SoC, Elaboratable):
         if ddr_pins is not None: # or fpga == 'sim':
             ddrmodule = dram_cls(clk_freq, "1:2") # match DDR3 ASIC P/N
 
-            #drs = lambda x: x
             # remap both the sync domain (wherever it occurs) and
             # the sync2x domain.  technically this should NOT be done.
             # it's a bit of a mess.  ok: this should be done only
@@ -377,6 +376,12 @@ class DDR3SoC(SoC, Elaboratable):
             drs = DomainRenamer({"sync": "dramsync",
                                  "sync2x": "dramsync2x"})
 
+            # HOWEVER, when the ASyncBridge is deployed, the two domains
+            # must NOT be renamed, instead this used:
+            #drs = lambda x: x
+            # and then the ASyncBridge takes care of it.
+            # but, back in ecp5_crg.py,
+
             if fpga == 'sim':
                 self.ddrphy = FakePHY(module=ddrmodule,
                                       settings=sim_ddr3_settings(clk_freq),