s6ddrphy: cleanup
authorSebastien Bourdeauducq <sebastien@milkymist.org>
Wed, 17 Jul 2013 11:58:58 +0000 (13:58 +0200)
committerSebastien Bourdeauducq <sebastien@milkymist.org>
Wed, 17 Jul 2013 11:58:58 +0000 (13:58 +0200)
milkymist/cif.py
milkymist/lasmicon/__init__.py
milkymist/lasmicon/multiplexer.py
milkymist/s6ddrphy/__init__.py
top.py

index d040ccdd58ccf918f86cf252b18fe873d8b5797a..bc5eb13da66102393a6f3ecb25ad7c6a0985be3e 100644 (file)
@@ -67,7 +67,7 @@ def get_csr_header(csr_base, bank_array, interrupt_map):
        return r
 
 def get_sdram_phy_header(sdram_phy):
-       if sdram_phy.phy_settings.type not in ["SDR", "DDR", "LPDDR", "DDR2"]:
+       if sdram_phy.phy_settings.memtype not in ["SDR", "DDR", "LPDDR", "DDR2"]:
                raise NotImplementedError("The SDRAM PHY header generator only supports SDR, DDR, LPDDR and DDR2")
 
        r = "#ifndef __HW_SDRAM_PHY_H\n#define __HW_SDRAM_PHY_H\n"
@@ -129,7 +129,7 @@ static void command_p{n}(int cmd)
 
        cl = sdram_phy.phy_settings.cl
        
-       if sdram_phy.phy_settings.type == "SDR":
+       if sdram_phy.phy_settings.memtype == "SDR":
                bl = 1*sdram_phy.phy_settings.nphases
                mr  = log2_int(bl) + (cl << 4)
                reset_dll = 1 << 8
@@ -144,7 +144,7 @@ static void command_p{n}(int cmd)
                        ("Load Mode Register / CL={0:d}, BL={1:d}".format(cl, bl), mr, 0, cmds["MODE_REGISTER"], 200)
                ]
 
-       elif sdram_phy.phy_settings.type == "DDR":
+       elif sdram_phy.phy_settings.memtype == "DDR":
                bl = 2*sdram_phy.phy_settings.nphases
                mr  = log2_int(bl) + (cl << 4)
                emr = 0
@@ -161,7 +161,7 @@ static void command_p{n}(int cmd)
                        ("Load Mode Register / CL={0:d}, BL={1:d}".format(cl, bl), mr, 0, cmds["MODE_REGISTER"], 200)
                ]
 
-       elif sdram_phy.phy_settings.type == "LPDDR":
+       elif sdram_phy.phy_settings.memtype == "LPDDR":
                bl = 2*sdram_phy.phy_settings.nphases
                mr  = log2_int(bl) + (cl << 4)
                emr = 0
@@ -178,7 +178,7 @@ static void command_p{n}(int cmd)
                        ("Load Mode Register / CL={0:d}, BL={1:d}".format(cl, bl), mr, 0, cmds["MODE_REGISTER"], 200)
                ]
 
-       elif sdram_phy.phy_settings.type == "DDR2":
+       elif sdram_phy.phy_settings.memtype == "DDR2":
                bl = 2*sdram_phy.phy_settings.nphases
                mr  = log2_int(bl) + (cl << 4)
                emr = 0
index f0a38999472a7643271c303aa81c31ffc5542a73..ffcb8e3a1447320839e0be659899c6072b4dae50 100644 (file)
@@ -7,14 +7,13 @@ from milkymist.lasmicon.refresher import *
 from milkymist.lasmicon.bankmachine import *
 from milkymist.lasmicon.multiplexer import *
 
-PhySettings = namedtuple("PhySettings", "type dfi_d nphases rdphase wrphase cl")
+PhySettings = namedtuple("PhySettings", "memtype dfi_d nphases rdphase wrphase cl read_latency write_latency")
 
 class GeomSettings(namedtuple("_GeomSettings", "bank_a row_a col_a")):
        def __init__(self, *args, **kwargs):
                self.mux_a = max(self.row_a, self.col_a)
 
 TimingSettings = namedtuple("TimingSettings", "tRP tRCD tWR tWTR tREFI tRFC" \
-       " read_latency write_latency" \
        " req_queue_size read_time write_time")
 
 class LASMIcon(Module):
@@ -31,8 +30,8 @@ class LASMIcon(Module):
                        dw=phy_settings.dfi_d*phy_settings.nphases,
                        nbanks=2**geom_settings.bank_a,
                        req_queue_size=timing_settings.req_queue_size,
-                       read_latency=timing_settings.read_latency+1,
-                       write_latency=timing_settings.write_latency+1)
+                       read_latency=phy_settings.read_latency+1,
+                       write_latency=phy_settings.write_latency+1)
                self.nrowbits = geom_settings.col_a - address_align
        
                ###
index 27978f941cd6d6dc3729fda2d239e5649dc3c4ed..d0cfa48b12cfc1907aa8bd75ca244d535482412d 100644 (file)
@@ -178,7 +178,7 @@ class Multiplexer(Module, AutoCSR):
                        steerer.sel[0].eq(STEER_REFRESH),
                        If(~refresher.req, NextState("READ"))
                )
-               fsm.delayed_enter("RTW", "WRITE", timing_settings.read_latency-1)
+               fsm.delayed_enter("RTW", "WRITE", phy_settings.read_latency-1) # FIXME: reduce this, actual limit is around (cl+1)/nphases
                fsm.delayed_enter("WTR", "READ", timing_settings.tWTR-1)
                # FIXME: workaround for zero-delay loop simulation problem with Icarus Verilog
                fsm.finalize()
index aa88c2ac623aac0fcde4267055209516197d602e..e137b543a34ef02fc46d77a8f7bd4b73c57a66f2 100644 (file)
@@ -1,4 +1,3 @@
-#
 # 1:2 frequency-ratio DDR / LPDDR / DDR2 PHY for 
 # Spartan-6
 # 
 # of dfi_rddata_valid.
 #
 # This PHY only supports CAS Latency 3.
-# Read commands must be sent on phase RDPHASE.
-# Write commands must be sent on phase WRPHASE.
-#/
+# Read commands must be sent on phase 0.
+# Write commands must be sent on phase 1.
+#
 
 # Todo:
 #      - use CSR for bitslip?
 #      - add configurable CAS Latency
-#      - automatically determines wrphase / rdphase / latencies according to phy_settings
+#      - automatically determines wrphase / rdphase / latencies
 
 from migen.fhdl.std import *
 from migen.bus.dfi import *
 from migen.genlib.record import *
 
-def get_latencies(phy_settings):
-       read_latency=5
-       write_latency=0
-       return read_latency, write_latency
-       
+from milkymist import lasmicon
+
 class S6DDRPHY(Module):
-       def __init__(self, pads, phy_settings, bitslip):
-               if phy_settings.type not in ["DDR", "LPDDR", "DDR2"]:
+       def __init__(self, pads, memtype, nphases, cl, bitslip):
+               if memtype not in ["DDR", "LPDDR", "DDR2"]:
                        raise NotImplementedError("S6DDRPHY only supports DDR, LPDDR and DDR2")
-               if phy_settings.cl != 3:
-                       raise NotImplementedError("S6DDRPHY only supports CAS LATENCY 3 for now")
+               if cl != 3:
+                       raise NotImplementedError("S6DDRPHY only supports CAS LATENCY 3")
 
                a = flen(pads.a)
                ba = flen(pads.ba)
                d = flen(pads.dq)
-               nphases = phy_settings.nphases
-               self.phy_settings = phy_settings
-               read_latency, write_latency = get_latencies(phy_settings)
+
+               self.phy_settings = lasmicon.PhySettings(
+                       memtype=memtype,
+                       dfi_d=2*d,
+                       nphases=nphases,
+                       rdphase=0,
+                       wrphase=1,
+                       cl=cl,
+                       read_latency=5,
+                       write_latency=0
+               )
 
                self.dfi = Interface(a, ba, nphases*d, nphases)
                self.clk4x_wr_strb = Signal()
@@ -112,7 +116,7 @@ class S6DDRPHY(Module):
                bitslip_inc = Signal()
 
                sd_sys += [
-                       If(bitslip_cnt==bitslip, 
+                       If(bitslip_cnt == bitslip, 
                                bitslip_inc.eq(0)
                        ).Else(
                                bitslip_cnt.eq(bitslip_cnt+1),
@@ -156,7 +160,7 @@ class S6DDRPHY(Module):
                                Instance.Input("S", 0),
 
                                Instance.Output("Q", dqs_o[i])
-                               )
+                       )
 
                        # DQS tristate cmd
                        self.specials += Instance("ODDR2",
@@ -174,7 +178,7 @@ class S6DDRPHY(Module):
                                Instance.Input("S", 0),
 
                                Instance.Output("Q", dqs_t[i])
-                               )
+                       )
 
                        # DQS tristate buffer
                        self.specials += Instance("OBUFT",
@@ -182,7 +186,7 @@ class S6DDRPHY(Module):
                                Instance.Input("T", dqs_t[i]),
 
                                Instance.Output("O", pads.dqs[i])
-                               )
+                       )
 
                sd_sdram_half += postamble.eq(drive_dqs)
 
@@ -333,26 +337,26 @@ class S6DDRPHY(Module):
                                Instance.Output("SHIFTOUT4"),
                        )
 
-
                # 
                # DQ/DQS/DM control
                #
-               self.comb += drive_dq.eq(d_dfi[phy_settings.wrphase].wrdata_en)
+               self.comb += drive_dq.eq(d_dfi[self.phy_settings.wrphase].wrdata_en)
                sd_sys += d_drive_dq.eq(drive_dq)
 
                d_dfi_wrdata_en = Signal()
-               sd_sys += d_dfi_wrdata_en.eq(d_dfi[phy_settings.wrphase].wrdata_en)
+               sd_sys += d_dfi_wrdata_en.eq(d_dfi[self.phy_settings.wrphase].wrdata_en)
                
                r_dfi_wrdata_en = Signal(2)
                sd_sdram_half += r_dfi_wrdata_en.eq(Cat(d_dfi_wrdata_en, r_dfi_wrdata_en[0])) 
 
                self.comb += drive_dqs.eq(r_dfi_wrdata_en[1])
 
-               rddata_sr = Signal(read_latency)
-               sd_sys += rddata_sr.eq(Cat(rddata_sr[1:read_latency], d_dfi[phy_settings.rdphase].rddata_en))
+               rddata_sr = Signal(self.phy_settings.read_latency)
+               sd_sys += rddata_sr.eq(Cat(rddata_sr[1:self.phy_settings.read_latency],
+                       d_dfi[self.phy_settings.rdphase].rddata_en))
                
                for n, phase in enumerate(self.dfi.phases):
                        self.comb += [
                                phase.rddata.eq(d_dfi[n].rddata),
                                phase.rddata_valid.eq(rddata_sr[0]),
-                       ]
\ No newline at end of file
+                       ]
diff --git a/top.py b/top.py
index a4d687f3bcf5dc6c54e6bc71d9b7e07cce979879..2d894f200eeb0a892b812073ed2ccd5d93a35351 100644 (file)
--- a/top.py
+++ b/top.py
@@ -25,20 +25,11 @@ def ns(t, margin=True):
                t += clk_period_ns/2
        return ceil(t/clk_period_ns)
 
-sdram_phy = lasmicon.PhySettings(
-       type="DDR",
-       dfi_d=64, 
-       nphases=2,
-       rdphase=0,
-       wrphase=1,
-       cl=3
-)
 sdram_geom = lasmicon.GeomSettings(
        bank_a=2,
        row_a=13,
        col_a=10
 )
-sdram_phy_read_latency, sdram_phy_write_latency = s6ddrphy.get_latencies(sdram_phy)
 sdram_timing = lasmicon.TimingSettings(
        tRP=ns(15),
        tRCD=ns(15),
@@ -46,9 +37,6 @@ sdram_timing = lasmicon.TimingSettings(
        tWTR=2,
        tREFI=ns(7800, False),
        tRFC=ns(70),
-       
-       read_latency=sdram_phy_read_latency+0,
-       write_latency=sdram_phy_write_latency+0,
 
        req_queue_size=8,
        read_time=32,
@@ -104,10 +92,20 @@ class SoC(Module):
        }
 
        def __init__(self, platform, platform_name, with_memtest):
+               #
+               # DFI
+               #
+               self.submodules.ddrphy = s6ddrphy.S6DDRPHY(platform.request("ddram"), memtype="DDR", nphases=2, cl=3, bitslip=0)
+               self.submodules.dfii = dfii.DFIInjector(sdram_geom.mux_a, sdram_geom.bank_a,
+                       self.ddrphy.phy_settings.dfi_d, self.ddrphy.phy_settings.nphases)
+               self.submodules.dficon0 = dfi.Interconnect(self.dfii.master, self.ddrphy.dfi)
+
                #
                # LASMI
                #
-               self.submodules.lasmicon = lasmicon.LASMIcon(sdram_phy, sdram_geom, sdram_timing)
+               self.submodules.lasmicon = lasmicon.LASMIcon(self.ddrphy.phy_settings, sdram_geom, sdram_timing)
+               self.submodules.dficon1 = dfi.Interconnect(self.lasmicon.dfi, self.dfii.slave)
+
                n_lasmims = 7 if with_memtest else 5
                self.submodules.lasmixbar = lasmibus.Crossbar([self.lasmicon.lasmic], n_lasmims, self.lasmicon.nrowbits)
                lasmims = list(self.lasmixbar.masters)
@@ -115,15 +113,6 @@ class SoC(Module):
                if with_memtest:
                        lasmim_mtw, lasmim_mtr = lasmims.pop(), lasmims.pop()
                assert(not lasmims)
-               
-               #
-               # DFI
-               #
-               self.submodules.ddrphy = s6ddrphy.S6DDRPHY(platform.request("ddram"), sdram_phy, 0)
-               self.submodules.dfii = dfii.DFIInjector(sdram_geom.mux_a, sdram_geom.bank_a, sdram_phy.dfi_d,
-                       sdram_phy.nphases)
-               self.submodules.dficon0 = dfi.Interconnect(self.dfii.master, self.ddrphy.dfi)
-               self.submodules.dficon1 = dfi.Interconnect(self.lasmicon.dfi, self.dfii.slave)
 
                #
                # WISHBONE