Prepare for new DDR PHY
authorSebastien Bourdeauducq <sebastien@milkymist.org>
Sun, 19 Feb 2012 17:43:42 +0000 (18:43 +0100)
committerSebastien Bourdeauducq <sebastien@milkymist.org>
Sun, 19 Feb 2012 17:43:42 +0000 (18:43 +0100)
15 files changed:
.gitignore
Makefile
README
constraints.py
milkymist/m1crg/__init__.py
milkymist/s6ddrphy/__init__.py
software/bios/ddrinit.c
software/include/hw/dfii.h
software/include/hw/s6ddrphy.h [deleted file]
top.py
verilog/m1crg/m1crg.v
verilog/s6ddrphy/README [deleted file]
verilog/s6ddrphy/patches/s6ddrphy.diff [deleted file]
verilog/s6ddrphy/patches/series [deleted file]
verilog/s6ddrphy/s6ddrphy.v [new file with mode: 0644]

index 15832e3347a781ac651d3a08d87fbb0a8904b02a..9d2acfa3a66f1aa83de9f6f95d38c5cca8fb1ac7 100644 (file)
@@ -6,5 +6,3 @@ build/*
 tools/bin2hex
 tools/flterm
 tools/mkmmimg
 tools/bin2hex
 tools/flterm
 tools/mkmmimg
-verilog/s6ddrphy/*.v
-verilog/s6ddrphy/.pc
index 9ebc7067563ff5bb960b60eb9221ca6e9c397729..f1696a3bc1e4bd0faf310ef8c8a980efeb023966 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -21,7 +21,7 @@ build/soc-routed.ncd: build/soc.ncd
        cd build && par -ol high -w soc.ncd soc-routed.ncd
 
 build/soc.bit build/soc.bin: build/soc-routed.ncd
        cd build && par -ol high -w soc.ncd soc-routed.ncd
 
 build/soc.bit build/soc.bin: build/soc-routed.ncd
-       cd build && bitgen -g Binary:Yes -g INIT_9K:Yes -w soc-routed.ncd soc.bit
+       cd build && bitgen -g LCK_cycle:6 -g Binary:Yes -g INIT_9K:Yes -w soc-routed.ncd soc.bit
 
 load: build/soc.bit
        jtag -n load.jtag
 
 load: build/soc.bit
        jtag -n load.jtag
diff --git a/README b/README
index 5dc6b64241bb9e569a3c9d3895397b055d2ceef0..1cc3abf5b5588d3e1e3e7647f84a022367037ac6 100644 (file)
--- a/README
+++ b/README
@@ -19,22 +19,6 @@ production version of Milkymist SoC, visit:
 First, download and install Migen from:
   https://github.com/milkymist/migen
 
 First, download and install Migen from:
   https://github.com/milkymist/migen
 
-Then, you will need to fetch the "Spartan-6 FPGA DDR/DDR2 SDRAM PHY core"
-(PHY only solution, we do not need the NWL memory controller) from:
-  http://www.xilinx.com/products/intellectual-property/1-1MFEDB.htm
-Downloading it is free of charge, but it cannot be redistributed in
-source form due to copyright restrictions.
-
-Place the Verilog source code of the PHY (contents of
-phy_rtl/spartan6_soft_phy) into the verilog/s6ddrphy folder.
-Then run (from verilog/s6ddrphy):
-  quilt push -a
-in order to apply patches that make the PHY more compliant with the DFI
-specification in general, and in particular with the capability to send
-multiple SDRAM commands in one system clock cycle, which our new SDRAM
-controller is capable of doing.
-The patches are against version 1.04 of the PHY.
-
 Once this is done, build the bitstream with:
   python3 build.py
 This will generate the build/soc.bit programming file.
 Once this is done, build the bitstream with:
   python3 build.py
 This will generate the build/soc.bit programming file.
@@ -67,8 +51,7 @@ without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
 PARTICULAR PURPOSE. See the GNU General Public License for more details.
 
 The authors grant the additional permissions that the code can be used in
 PARTICULAR PURPOSE. See the GNU General Public License for more details.
 
 The authors grant the additional permissions that the code can be used in
-conjunction with the LatticeMico32 CPU core from Lattice and the
-Spartan-6 FPGA DDR/DDR2 SDRAM PHY core from Xilinx and Northwest Logic.
+conjunction with the LatticeMico32 CPU core from Lattice.
 
 Unless otherwise noted, Milkymist-NG's source code is copyright (C)
 2011-2012 Sebastien Bourdeauducq. Other authors retain ownership of their
 
 Unless otherwise noted, Milkymist-NG's source code is copyright (C)
 2011-2012 Sebastien Bourdeauducq. Other authors retain ownership of their
index 4867ae5bb65e256a057f78eecadad18951e1c2f8..f68e5bb3de80843ec7c6ab13098a806bd1aa371c 100644 (file)
@@ -13,7 +13,6 @@ def get(ns, crg0, norflash0, uart0, ddrphy0):
        add(crg0.ac97_rst_n, "D6")
        add(crg0.videoin_rst_n, "W17")
        add(crg0.flash_rst_n, "P22", extra="SLEW = FAST | DRIVE = 8")
        add(crg0.ac97_rst_n, "D6")
        add(crg0.videoin_rst_n, "W17")
        add(crg0.flash_rst_n, "P22", extra="SLEW = FAST | DRIVE = 8")
-       add(crg0.rd_clk_lb, "K5", extra="IOSTANDARD = SSTL2_I")
        add(crg0.trigger_reset, "AA4")
        
        add_vec(norflash0.adr, ["L22", "L20", "K22", "K21", "J19", "H20", "F22",
        add(crg0.trigger_reset, "AA4")
        
        add_vec(norflash0.adr, ["L22", "L20", "K22", "K21", "J19", "H20", "F22",
@@ -61,15 +60,8 @@ def get(ns, crg0, norflash0, uart0, ddrphy0):
        
        r += """
 TIMESPEC "TSclk50" = PERIOD "GRPclk50" 20 ns HIGH 50%;
        
        r += """
 TIMESPEC "TSclk50" = PERIOD "GRPclk50" 20 ns HIGH 50%;
-INST "spartan6_soft_phy/datapath_s6_inst/dq_idelay_cal_inst/max_tap_drp" LOC = "IODELAY_X0Y79"; # use sd_dm[0] at E1
-INST "m1crg/wr_bufpll_left" LOC = "BUFPLL_X0Y2";
-INST "m1crg/wr_bufpll_right" LOC = "BUFPLL_X2Y2";
-INST "m1crg/rd_bufpll_left" LOC = "BUFPLL_X0Y3";
-INST "m1crg/rd_bufpll_right" LOC = "BUFPLL_X2Y3";
-
-# MAP (13.4) hallucinates that this placement is unroutable. Tell it to STFU.
-PIN "m1crg/rd_bufpll_left.IOCLK" CLOCK_DEDICATED_ROUTE = FALSE;
-PIN "spartan6_soft_phy/datapath_s6_inst/dq_idelay_cal_inst/max_tap_drp.IOCLK0" CLOCK_DEDICATED_ROUTE = FALSE;
+INST "m1crg/wr_bufpll" LOC = "BUFPLL_X0Y2";
+INST "m1crg/rd_bufpll" LOC = "BUFPLL_X0Y3";
 """
        
        return r
 """
        
        return r
index 37b19e5a01a4e8fc7a806324b11c87f510d3015a..a0b49b61ac3d9f3d9a2317c3a8ca39aaedb583bf 100644 (file)
@@ -15,21 +15,15 @@ class M1CRG:
                        "videoin_rst_n",
                        "flash_rst_n",
                        "clk2x_90",
                        "videoin_rst_n",
                        "flash_rst_n",
                        "clk2x_90",
-                       "clk4x_wr_left",
-                       "clk4x_wr_strb_left",
-                       "clk4x_wr_right",
-                       "clk4x_wr_strb_right",
-                       "clk4x_rd_left",
-                       "clk4x_rd_strb_left",
-                       "clk4x_rd_right",
-                       "clk4x_rd_strb_right"
+                       "clk4x_wr",
+                       "clk4x_wr_strb",
+                       "clk4x_rd",
+                       "clk4x_rd_strb"
                ]:
                        s = Signal(name=name)
                        setattr(self, name, s)
                        generated.append((name, s))  
                
                ]:
                        s = Signal(name=name)
                        setattr(self, name, s)
                        generated.append((name, s))  
                
-               self.rd_clk_lb = Signal()
-               
                ratio = Fraction(outfreq1x)/Fraction(infreq)
                in_period = float(Fraction(1000000000)/Fraction(infreq))
                
                ratio = Fraction(outfreq1x)/Fraction(infreq)
                in_period = float(Fraction(1000000000)/Fraction(infreq))
                
@@ -38,9 +32,8 @@ class M1CRG:
                        [
                                ("clkin", self.clkin),
                                ("trigger_reset", self.trigger_reset)
                        [
                                ("clkin", self.clkin),
                                ("trigger_reset", self.trigger_reset)
-                       ], [
-                               ("rd_clk_lb", self.rd_clk_lb)
-                       ], [
+                       ],
+                       parameters=[
                                ("in_period", in_period),
                                ("f_mult", ratio.numerator),
                                ("f_div", ratio.denominator)
                                ("in_period", in_period),
                                ("f_mult", ratio.numerator),
                                ("f_div", ratio.denominator)
@@ -49,4 +42,4 @@ class M1CRG:
 
        def get_fragment(self):
                return Fragment(instances=[self._inst],
 
        def get_fragment(self):
                return Fragment(instances=[self._inst],
-                       pads={self.clkin, self.ac97_rst_n, self.videoin_rst_n, self.flash_rst_n, self.rd_clk_lb})
+                       pads={self.clkin, self.ac97_rst_n, self.videoin_rst_n, self.flash_rst_n})
index 6b2697031e766bf4ce8689a3d542dc50389a46a6..4129f089390fc99e884ada4b309a8d551755cba8 100644 (file)
@@ -1,31 +1,24 @@
 from migen.fhdl.structure import *
 from migen.bus import dfi
 from migen.fhdl.structure import *
 from migen.bus import dfi
-from migen.bank.description import *
-from migen.bank import csrgen
 
 class S6DDRPHY:
 
 class S6DDRPHY:
-       def __init__(self, csr_address, a, ba, d):
+       def __init__(self, a, ba, d):
                ins = []
                outs = []
                inouts = []
                
                for name in [
                        "clk2x_90",
                ins = []
                outs = []
                inouts = []
                
                for name in [
                        "clk2x_90",
-                       "clk4x_wr_left",
-                       "clk4x_wr_strb_left",
-                       "clk4x_wr_right",
-                       "clk4x_wr_strb_right",
-                       "clk4x_rd_left",
-                       "clk4x_rd_strb_left",
-                       "clk4x_rd_right",
-                       "clk4x_rd_strb_right"
+                       "clk4x_wr",
+                       "clk4x_wr_strb",
+                       "clk4x_rd",
+                       "clk4x_rd_strb"
                ]:
                        s = Signal(name=name)
                        setattr(self, name, s)
                        ins.append((name, s))
                
                self._sd_pins = []
                ]:
                        s = Signal(name=name)
                        setattr(self, name, s)
                        ins.append((name, s))
                
                self._sd_pins = []
-               sd_d = d//4
                for name, width, l in [
                        ("sd_clk_out_p", 1, outs),
                        ("sd_clk_out_n", 1, outs),
                for name, width, l in [
                        ("sd_clk_out_p", 1, outs),
                        ("sd_clk_out_n", 1, outs),
@@ -36,9 +29,9 @@ class S6DDRPHY:
                        ("sd_ras_n", 1, outs),
                        ("sd_cas_n", 1, outs),
                        ("sd_we_n", 1, outs),
                        ("sd_ras_n", 1, outs),
                        ("sd_cas_n", 1, outs),
                        ("sd_we_n", 1, outs),
-                       ("sd_dq", sd_d, inouts),
-                       ("sd_dm", sd_d//8, outs),
-                       ("sd_dqs", sd_d//8, inouts)
+                       ("sd_dq", d//2, inouts),
+                       ("sd_dm", d//16, outs),
+                       ("sd_dqs", d//16, inouts)
                        
                ]:
                        s = Signal(BV(width), name=name)
                        
                ]:
                        s = Signal(BV(width), name=name)
@@ -46,93 +39,20 @@ class S6DDRPHY:
                        l.append((name, s))
                        self._sd_pins.append(s)
                
                        l.append((name, s))
                        self._sd_pins.append(s)
                
-               self.dfi = dfi.Interface(a, ba, d)
+               self.dfi = dfi.Interface(a, ba, d, 2)
                ins += self.dfi.get_standard_names(True, False)
                outs += self.dfi.get_standard_names(False, True)
                
                ins += self.dfi.get_standard_names(True, False)
                outs += self.dfi.get_standard_names(False, True)
                
-               ins += [
-                       ("reset_n", BV(1)),
-                       
-                       ("cfg_al", BV(3)),
-                       ("cfg_cl", BV(3)),
-                       ("cfg_bl", BV(2)),
-                       ("cfg_regdimm", BV(1)),
-                       
-                       ("init_done", BV(1)),
-                       
-                       ("cpg_busy", BV(1)),
-                       
-                       ("diag_dq_recal", BV(1)),
-                       ("diag_io_sel", BV(9)),
-                       ("diag_disable_cal_on_startup", BV(1)),
-                       ("diag_cal_bits", BV(2)),
-                       ("diag_short_cal", BV(1))
-               ]
-               outs += [
-                       ("phy_cal_done", BV(1)),
-                       
-                       ("cpg_r_req", BV(1)),
-                       ("cpg_w_req", BV(1)),
-                       ("cpg_addr", BV(a)),
-                       ("cpg_b_size", BV(4))
-               ]
-               
-               self._inst = Instance("spartan6_soft_phy",
+               self._inst = Instance("s6ddrphy",
                        outs,
                        ins,
                        inouts,
                        [
                        outs,
                        ins,
                        inouts,
                        [
-                               ("DSIZE", d),
                                ("NUM_AD", a),
                                ("NUM_BA", ba),
                                ("NUM_AD", a),
                                ("NUM_BA", ba),
-                               ("ADDR_WIDTH", 31),
-                               ("DQ_IO_LOC", Constant(2**32-1, BV(32))),
-                               ("DM_IO_LOC", Constant(2**4-1, BV(4)))
+                               ("NUM_D", d)
                        ],
                        ],
-                       clkport="clk")
-               
-               self._reset_n = Field("reset_n")
-               self._init_done = Field("init_done")
-               self._phy_cal_done = Field("phy_cal_done", 1, READ_ONLY, WRITE_ONLY)
-               self._status = RegisterFields("status",
-                       [self._reset_n, self._init_done, self._phy_cal_done])
-               self._req = RegisterRaw("req", 2)
-               self._req_addr = RegisterField("req_addr", 8, READ_ONLY, WRITE_ONLY)
-               
-               self.bank = csrgen.Bank([self._status, self._req, self._req_addr],
-                       address=csr_address)
+                       clkport="sys_clk")
 
        def get_fragment(self):
 
        def get_fragment(self):
-               pending_r = Signal()
-               pending_w = Signal()
-               cpg_busy = Signal()
-               
-               comb = [
-                       self._inst.ins["cfg_al"].eq(0),
-                       self._inst.ins["cfg_cl"].eq(3),
-                       self._inst.ins["cfg_bl"].eq(1),
-                       self._inst.ins["cfg_regdimm"].eq(0),
-                       
-                       self._inst.ins["diag_dq_recal"].eq(0),
-                       self._inst.ins["diag_io_sel"].eq(0),
-                       self._inst.ins["diag_disable_cal_on_startup"].eq(0),
-                       self._inst.ins["diag_cal_bits"].eq(0),
-                       self._inst.ins["diag_short_cal"].eq(0),
-                       
-                       self._inst.ins["reset_n"].eq(self._reset_n.r),
-                       self._inst.ins["init_done"].eq(self._init_done.r),
-                       self._phy_cal_done.w.eq(self._inst.outs["phy_cal_done"]),
-                       self._req_addr.field.w.eq(self._inst.outs["cpg_addr"][2:10]),
-                       
-                       self._req.w.eq(Cat(pending_r, pending_w)),
-                       cpg_busy.eq(pending_r | pending_w),
-                       self._inst.ins["cpg_busy"].eq(cpg_busy)
-               ]
-               sync = [
-                       If(self._inst.outs["cpg_r_req"], pending_r.eq(1)),
-                       If(self._inst.outs["cpg_w_req"], pending_w.eq(1)),
-                       If(self._req.re & self._req.r[0], pending_r.eq(0)),
-                       If(self._req.re & self._req.r[1], pending_w.eq(0))
-               ]
-               return Fragment(comb, sync, instances=[self._inst], pads=set(self._sd_pins)) \
-                       + self.bank.get_fragment()
+               return Fragment(instances=[self._inst], pads=set(self._sd_pins))
index 5edce2347809f1048c3b33f632c8ae9b00502158..6e18e16bae6108cc75db991702d6d673b32b98d1 100644 (file)
@@ -17,7 +17,6 @@
 
 #include <stdio.h>
 
 
 #include <stdio.h>
 
-#include <hw/s6ddrphy.h>
 #include <hw/dfii.h>
 
 #include "ddrinit.h"
 #include <hw/dfii.h>
 
 #include "ddrinit.h"
@@ -79,54 +78,11 @@ static void init_sequence(void)
        cdelay(200);
 }
 
        cdelay(200);
 }
 
-static void calibrate_phy(void)
-{
-       int requests;
-       int addr;
-       
-       printf("Calibrating PHY...\n");
-       
-       CSR_DFII_WRDELAY = 4;
-       CSR_DFII_WRDURATION = 1;
-       CSR_DFII_RDDELAY = 7;
-       CSR_DFII_RDDURATION = 1;
-       
-       /* Use bank 0, activate row 0 */
-       CSR_DFII_BA = 0;
-       setaddr(0x0000);
-       CSR_DFII_COMMAND = DFII_COMMAND_RAS|DFII_COMMAND_CS;
-       
-       while(!(CSR_DDRPHY_STATUS & DDRPHY_STATUS_PHY_CAL_DONE)) {
-               cdelay(20);
-               requests = CSR_DDRPHY_REQUESTS;
-               addr = CSR_DDRPHY_REQADDR;
-               
-               setaddr(addr << 2);
-               if(requests & DDRPHY_REQUEST_READ) {
-                       printf("R %d\n", addr);
-                       CSR_DFII_COMMAND = DFII_COMMAND_RDDATA|DFII_COMMAND_CAS|DFII_COMMAND_CS;
-               }
-               if(requests & DDRPHY_REQUEST_WRITE) {
-                       printf("W %d\n", addr);
-                       CSR_DFII_COMMAND = DFII_COMMAND_WRDATA|DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS;
-               }
-               
-               CSR_DDRPHY_REQUESTS = requests;
-       }
-       
-       /* Precharge All */
-       setaddr(0x0400);
-       CSR_DFII_COMMAND = DFII_COMMAND_RAS|DFII_COMMAND_WE|DFII_COMMAND_CS;
-}
-
 int ddrinit(void)
 {
        printf("Initializing DDR SDRAM...\n");
        
 int ddrinit(void)
 {
        printf("Initializing DDR SDRAM...\n");
        
-       CSR_DDRPHY_STATUS = DDRPHY_STATUS_RESETN;
        init_sequence();
        init_sequence();
-       CSR_DDRPHY_STATUS = DDRPHY_STATUS_RESETN|DDRPHY_STATUS_INIT_DONE;
-       calibrate_phy();
        
        return 1;
 }
        
        return 1;
 }
index 9a58faac9f2e466f9140e791939a531fcace6383..045e25aede4f70d6d2d260968000fc709e9085a8 100644 (file)
@@ -20,7 +20,7 @@
 
 #include <hw/common.h>
 
 
 #include <hw/common.h>
 
-#define CSR_DFII_CONTROL               MMPTR(0xe0001000)
+#define CSR_DFII_CONTROL               MMPTR(0xe0000800)
 
 #define DFII_CONTROL_SEL               (0x01)
 #define DFII_CONTROL_CKE               (0x02)
 
 #define DFII_CONTROL_SEL               (0x01)
 #define DFII_CONTROL_CKE               (0x02)
 #define DFII_COMMAND_RDDATA            (0x10)
 #define DFII_COMMAND_WRDATA            (0x20)
 
 #define DFII_COMMAND_RDDATA            (0x10)
 #define DFII_COMMAND_WRDATA            (0x20)
 
-#define CSR_DFII_AH                    MMPTR(0xe0001008)
-#define CSR_DFII_AL                    MMPTR(0xe000100C)
-#define CSR_DFII_BA                    MMPTR(0xe0001010)
+#define CSR_DFII_AH                    MMPTR(0xe0000808)
+#define CSR_DFII_AL                    MMPTR(0xe000080C)
+#define CSR_DFII_BA                    MMPTR(0xe0000810)
 
 
-#define CSR_DFII_RDDELAY               MMPTR(0xe0001014)
-#define CSR_DFII_RDDURATION            MMPTR(0xe0001018)
-#define CSR_DFII_WRDELAY               MMPTR(0xe000101C)
-#define CSR_DFII_WRDURATION            MMPTR(0xe0001020)
+#define CSR_DFII_RDDELAY               MMPTR(0xe0000814)
+#define CSR_DFII_RDDURATION            MMPTR(0xe0000818)
+#define CSR_DFII_WRDELAY               MMPTR(0xe000081C)
+#define CSR_DFII_WRDURATION            MMPTR(0xe0000820)
 
 #endif /* __HW_DFII_H */
 
 #endif /* __HW_DFII_H */
diff --git a/software/include/hw/s6ddrphy.h b/software/include/hw/s6ddrphy.h
deleted file mode 100644 (file)
index a139c4c..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Milkymist SoC (Software)
- * Copyright (C) 2012 Sebastien Bourdeauducq
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, version 3 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef __HW_S6DDRPHY_H
-#define __HW_S6DDRPHY_H
-
-#include <hw/common.h>
-
-#define CSR_DDRPHY_STATUS              MMPTR(0xe0000800)
-
-#define DDRPHY_STATUS_RESETN           (0x1)
-#define DDRPHY_STATUS_INIT_DONE                (0x2)
-#define DDRPHY_STATUS_PHY_CAL_DONE     (0x4)
-
-#define CSR_DDRPHY_REQUESTS            MMPTR(0xe0000804)
-
-#define DDRPHY_REQUEST_READ            (0x1)
-#define DDRPHY_REQUEST_WRITE           (0x2)
-
-#define CSR_DDRPHY_REQADDR             MMPTR(0xe0000808)
-
-#endif /* __HW_S6DDRPHY_H */
diff --git a/top.py b/top.py
index 473674060639c8b94e4d77fb7df47511606af139..a4d898861803d5d3f9e9f496473e79324ee3ebb3 100644 (file)
--- a/top.py
+++ b/top.py
@@ -14,19 +14,15 @@ l2_size = 8192 # in bytes
 
 dfi_a = 13
 dfi_ba = 2
 
 dfi_a = 13
 dfi_ba = 2
-dfi_d = 128 # TODO -> 64
+dfi_d = 64
 
 def ddrphy_clocking(crg, phy):
        names = [
                "clk2x_90",
 
 def ddrphy_clocking(crg, phy):
        names = [
                "clk2x_90",
-               "clk4x_wr_left",
-               "clk4x_wr_strb_left",
-               "clk4x_wr_right",
-               "clk4x_wr_strb_right",
-               "clk4x_rd_left",
-               "clk4x_rd_strb_left",
-               "clk4x_rd_right",
-               "clk4x_rd_strb_right",
+               "clk4x_wr",
+               "clk4x_wr_strb",
+               "clk4x_rd",
+               "clk4x_rd_strb"
        ]
        comb = [getattr(phy, name).eq(getattr(crg, name)) for name in names]
        return Fragment(comb)
        ]
        comb = [getattr(phy, name).eq(getattr(crg, name)) for name in names]
        return Fragment(comb)
@@ -42,8 +38,8 @@ def get():
        #
        # DFI
        #
        #
        # DFI
        #
-       ddrphy0 = s6ddrphy.S6DDRPHY(1, dfi_a, dfi_ba, dfi_d)
-       dfii0 = dfii.DFIInjector(2, dfi_a, dfi_ba, dfi_d, 1)
+       ddrphy0 = s6ddrphy.S6DDRPHY(dfi_a, dfi_ba, dfi_d)
+       dfii0 = dfii.DFIInjector(1, dfi_a, dfi_ba, dfi_d, 2)
        dficon0 = dfi.Interconnect(dfii0.master, ddrphy0.dfi)
 
        #
        dficon0 = dfi.Interconnect(dfii0.master, ddrphy0.dfi)
 
        #
@@ -80,7 +76,6 @@ def get():
        uart0 = uart.UART(0, clk_freq, baud=115200)
        csrcon0 = csr.Interconnect(wishbone2csr0.csr, [
                uart0.bank.interface,
        uart0 = uart.UART(0, clk_freq, baud=115200)
        csrcon0 = csr.Interconnect(wishbone2csr0.csr, [
                uart0.bank.interface,
-               ddrphy0.bank.interface,
                dfii0.bank.interface
        ])
        
                dfii0.bank.interface
        ])
        
index e885a0c0cae7445642a19b22aa4a11880629d948..0ab04410560b5769c1583bf73a525a9ce3beb707 100644 (file)
@@ -32,37 +32,25 @@ module m1crg #(
        output videoin_rst_n,
        output flash_rst_n,
        
        output videoin_rst_n,
        output flash_rst_n,
        
-       /* DDR PHY clocks and reset */
+       /* DDR PHY clocks */
        output clk2x_90,
        output clk2x_90,
-       output clk4x_wr_left,
-       output clk4x_wr_strb_left,
-       output clk4x_wr_right,
-       output clk4x_wr_strb_right,
-       output clk4x_rd_left,
-       output clk4x_rd_strb_left,
-       output clk4x_rd_right,
-       output clk4x_rd_strb_right,
-       inout rd_clk_lb /* < unconnected clock pin for read clock PLL loopback */
+       output clk4x_wr,
+       output clk4x_wr_strb,
+       output clk4x_rd,
+       output clk4x_rd_strb
 );
 
 /*
  * Reset
  */
 
 );
 
 /*
  * Reset
  */
 
-wire reset_n;
-
 reg [19:0] rst_debounce;
 reg [19:0] rst_debounce;
-always @(posedge sys_clk, negedge reset_n) begin
-       if(~reset_n) begin
+always @(posedge sys_clk) begin
+       if(trigger_reset)
                rst_debounce <= 20'hFFFFF;
                rst_debounce <= 20'hFFFFF;
-               sys_rst <= 1'b1;
-       end else begin
-               if(trigger_reset)
-                       rst_debounce <= 20'hFFFFF;
-               else if(rst_debounce != 20'd0)
-                       rst_debounce <= rst_debounce - 20'd1;
-               sys_rst <= rst_debounce != 20'd0;
-       end
+       else if(rst_debounce != 20'd0)
+               rst_debounce <= rst_debounce - 20'd1;
+       sys_rst <= rst_debounce != 20'd0;
 end
 
 assign ac97_rst_n = ~sys_rst;
 end
 
 assign ac97_rst_n = ~sys_rst;
@@ -79,23 +67,19 @@ assign videoin_rst_n = ~sys_rst;
 
 reg [7:0] flash_rstcounter;
 
 
 reg [7:0] flash_rstcounter;
 
-always @(posedge sys_clk, negedge reset_n) begin
-       if(~reset_n) begin
+always @(posedge sys_clk) begin
+       if(trigger_reset)
                flash_rstcounter <= 8'd0;
                flash_rstcounter <= 8'd0;
-       end else begin
-               if(trigger_reset)
-                       flash_rstcounter <= 8'd0;
-               else if(~flash_rstcounter[7])
-                       flash_rstcounter <= flash_rstcounter + 8'd1;
-       end
+       else if(~flash_rstcounter[7])
+               flash_rstcounter <= flash_rstcounter + 8'd1;
 end
 
 assign flash_rst_n = flash_rstcounter[7];
 
 /*
 end
 
 assign flash_rst_n = flash_rstcounter[7];
 
 /*
- * Clock management. Largely taken from the NWL reference design.
+ * Clock management. Inspired by the NWL reference design.
  */
  */
+
 wire sdr_clkin;
 wire clkdiv;
 
 wire sdr_clkin;
 wire clkdiv;
 
@@ -117,12 +101,12 @@ BUFIO2 #(
        .SERDESSTROBE()
 );
 
        .SERDESSTROBE()
 );
 
-wire pll1_lckd;
-wire buf_pll1_fb_out;
-wire pll1out0;
-wire pll1out1;
-wire pll1out2;
-wire pll1out3;
+wire pll_lckd;
+wire buf_pll_fb_out;
+wire pllout0;
+wire pllout1;
+wire pllout2;
+wire pllout3;
 
 PLL_ADV #(
        .BANDWIDTH("OPTIMIZED"),
 
 PLL_ADV #(
        .BANDWIDTH("OPTIMIZED"),
@@ -136,12 +120,12 @@ PLL_ADV #(
        .CLKOUT1_DIVIDE(f_div),
        .CLKOUT1_DUTY_CYCLE(0.5),
        .CLKOUT1_PHASE(0),
        .CLKOUT1_DIVIDE(f_div),
        .CLKOUT1_DUTY_CYCLE(0.5),
        .CLKOUT1_PHASE(0),
-       .CLKOUT2_DIVIDE(4*f_div),
+       .CLKOUT2_DIVIDE(2*f_div),
        .CLKOUT2_DUTY_CYCLE(0.5),
        .CLKOUT2_DUTY_CYCLE(0.5),
-       .CLKOUT2_PHASE(0.0),
-       .CLKOUT3_DIVIDE(2*f_div),
+       .CLKOUT2_PHASE(90.0),
+       .CLKOUT3_DIVIDE(4*f_div),
        .CLKOUT3_DUTY_CYCLE(0.5),
        .CLKOUT3_DUTY_CYCLE(0.5),
-       .CLKOUT3_PHASE(90),
+       .CLKOUT3_PHASE(0.0),
        .CLKOUT4_DIVIDE(7),
        .CLKOUT4_DUTY_CYCLE(0.5),
        .CLKOUT4_PHASE(0),
        .CLKOUT4_DIVIDE(7),
        .CLKOUT4_DUTY_CYCLE(0.5),
        .CLKOUT4_PHASE(0),
@@ -153,13 +137,13 @@ PLL_ADV #(
        .REF_JITTER(0.100),
        .CLK_FEEDBACK("CLKFBOUT"),
        .SIM_DEVICE("SPARTAN6")
        .REF_JITTER(0.100),
        .CLK_FEEDBACK("CLKFBOUT"),
        .SIM_DEVICE("SPARTAN6")
-) pll1 (
+) pll (
        .CLKFBDCM(),
        .CLKFBDCM(),
-       .CLKFBOUT(buf_pll1_fb_out),
-       .CLKOUT0(pll1out0), /* < x4 180 clock for transmitter */
-       .CLKOUT1(pll1out1), /* < x4 180 clock for transmitter */
-       .CLKOUT2(pll1out2), /* < x1 clock for memory controller */
-       .CLKOUT3(pll1out3), /* < x2 90 clock to generate memory clock, clock DQS and memory address and control signals. */
+       .CLKFBOUT(buf_pll_fb_out),
+       .CLKOUT0(pllout0), /* < x4 clock for writes */
+       .CLKOUT1(pllout1), /* < x4 clock for reads */
+       .CLKOUT2(pllout2), /* < x2 90 clock to generate memory clock, clock DQS and memory address and control signals. */
+       .CLKOUT3(pllout3), /* < x1 clock for system and memory controller */
        .CLKOUT4(),
        .CLKOUT5(),
        .CLKOUTDCM0(),
        .CLKOUT4(),
        .CLKOUT5(),
        .CLKOUTDCM0(),
@@ -170,8 +154,8 @@ PLL_ADV #(
        .CLKOUTDCM5(),
        .DO(),
        .DRDY(),
        .CLKOUTDCM5(),
        .DO(),
        .DRDY(),
-       .LOCKED(pll1_lckd),
-       .CLKFBIN(buf_pll1_fb_out),
+       .LOCKED(pll_lckd),
+       .CLKFBIN(buf_pll_fb_out),
        .CLKIN1(clkdiv),
        .CLKIN2(1'b0),
        .CLKINSEL(1'b1),
        .CLKIN1(clkdiv),
        .CLKIN2(1'b0),
        .CLKINSEL(1'b1),
@@ -186,239 +170,34 @@ PLL_ADV #(
 
 BUFPLL #(
        .DIVIDE(4)
 
 BUFPLL #(
        .DIVIDE(4)
-) wr_bufpll_left (
-       .PLLIN(pll1out0),
+) wr_bufpll (
+       .PLLIN(pllout0),
        .GCLK(sys_clk),
        .GCLK(sys_clk),
-       .LOCKED(pll1_lckd),
-       .IOCLK(clk4x_wr_left),
+       .LOCKED(pll_lckd),
+       .IOCLK(clk4x_wr),
        .LOCK(),
        .LOCK(),
-       .SERDESSTROBE(clk4x_wr_strb_left)
+       .SERDESSTROBE(clk4x_wr_strb)
 );
 
 BUFPLL #(
        .DIVIDE(4)
 );
 
 BUFPLL #(
        .DIVIDE(4)
-) wr_bufpll_right (
-       .PLLIN(pll1out1),
+) rd_bufpll (
+       .PLLIN(pllout1),
        .GCLK(sys_clk),
        .GCLK(sys_clk),
-       .LOCKED(pll1_lckd),
-       .IOCLK(clk4x_wr_right),
+       .LOCKED(pll_lckd),
+       .IOCLK(clk4x_rd),
        .LOCK(),
        .LOCK(),
-       .SERDESSTROBE(clk4x_wr_strb_right)
-);
-
-BUFG bufg_x1(
-       .I(pll1out2),
-       .O(sys_clk)
+       .SERDESSTROBE(clk4x_rd_strb)
 );
 
 BUFG bufg_x2_2(
 );
 
 BUFG bufg_x2_2(
-       .I(pll1out3),
+       .I(pllout2),
        .O(clk2x_90)
 );
 
        .O(clk2x_90)
 );
 
-/*
- * Generate clk4x_rd. This clock is sourced from clk2x_90.
- * An IODELAY2 element is included in the path of this clock so that 
- * any variation in IDELAY element's base delay is compensated when this clock 
- * is used to capture read data which also goes through IDELAY element.
- */
-
-wire rd_clk_out;
-
-ODDR2 #(
-       .DDR_ALIGNMENT("C0"),
-       .INIT(1'b0),
-       .SRTYPE("ASYNC")
-) rd_clk_out_inst (
-       .Q(rd_clk_out),
-       .C0(clk2x_90),
-       .C1(~clk2x_90),
-       .CE(1'b1),
-       .D0(1'b1),
-       .D1(1'b0),
-       .R(1'b0),
-       .S(1'b0)
-);
-
-wire rd_clk_out_oe_n;
-
-ODDR2 #(
-       .DDR_ALIGNMENT("C0"),
-       .INIT(1'b0),
-       .SRTYPE("ASYNC")
-) rd_clk_out_oe_inst (
-       .Q(rd_clk_out_oe_n),
-       .C0(clk2x_90),
-       .C1(~clk2x_90),
-       .CE(1'b1),
-       .D0(1'b0),
-       .D1(1'b0),
-       .R(1'b0),
-       .S(1'b0)
-);
-
-wire rd_clk_fb;
-
-/* Dummy pin used for calibration */
-IOBUF rd_clk_loop_back_inst(
-       .O(rd_clk_fb),
-       .IO(rd_clk_lb),
-       .I(rd_clk_out),
-       .T(rd_clk_out_oe_n)
-);
-
-wire rd_clk_fb_dly;
-
-IODELAY2 #(
-       .DATA_RATE("DDR"),
-       .IDELAY_VALUE(0),
-       .IDELAY2_VALUE(0),
-       .IDELAY_MODE("NORMAL"),
-       .ODELAY_VALUE(0),
-       .IDELAY_TYPE("FIXED"),
-       .COUNTER_WRAPAROUND("STAY_AT_LIMIT"),
-       .DELAY_SRC("IDATAIN"),
-       .SERDES_MODE("NONE"),
-       .SIM_TAPDELAY_VALUE(49)
-) iodelay_cm (
-       .IDATAIN(rd_clk_fb),
-       .TOUT(),
-       .DOUT(),
-       .T(1'b1),
-       .ODATAIN(1'b0),
-       .DATAOUT(rd_clk_fb_dly),
-       .DATAOUT2(),
-       .IOCLK0(1'b0),
-       .IOCLK1(1'b0),
-       .CLK(1'b0),
-       .CAL(1'b0),
-       .INC(1'b0),
-       .CE(1'b0),
-       .RST(1'b0),
-       .BUSY()
-);
-
-wire rd_clk_fb_dly_bufio;
-
-BUFIO2 #(
-       .DIVIDE(1),
-       .DIVIDE_BYPASS("FALSE"),
-       .I_INVERT("FALSE")
-) bufio2_inst (
-       .I(rd_clk_fb_dly),
-       .IOCLK(),
-       .DIVCLK(rd_clk_fb_dly_bufio),
-       .SERDESSTROBE()
-);
-
-wire pll2_lckd;
-wire buf_pll2_fb_out;
-wire pll2out0;
-wire pll2out1;
-
-PLL_ADV #(
-       .BANDWIDTH("OPTIMIZED"),
-       .CLKFBOUT_MULT(4),
-       .CLKFBOUT_PHASE(0.0),
-       .CLKIN1_PERIOD(clk2x_period),
-       .CLKIN2_PERIOD(clk2x_period),
-       .CLKOUT0_DIVIDE(2),
-       .CLKOUT0_DUTY_CYCLE(0.5),
-       .CLKOUT0_PHASE(0.0),
-       .CLKOUT1_DIVIDE(2),
-       .CLKOUT1_DUTY_CYCLE(0.5),
-       .CLKOUT1_PHASE(0.0),
-       .CLKOUT2_DIVIDE(7),
-       .CLKOUT2_DUTY_CYCLE(0.5),
-       .CLKOUT2_PHASE(0.0),
-       .CLKOUT3_DIVIDE(7),
-       .CLKOUT3_DUTY_CYCLE(0.5),
-       .CLKOUT3_PHASE(0.0),
-       .CLKOUT4_DIVIDE(7),
-       .CLKOUT4_DUTY_CYCLE(0.5),
-       .CLKOUT4_PHASE(0.0),
-       .CLKOUT5_DIVIDE(7),
-       .CLKOUT5_DUTY_CYCLE (0.5),
-       .CLKOUT5_PHASE(0.0),
-       .COMPENSATION("INTERNAL"),
-       .DIVCLK_DIVIDE(1),
-       .REF_JITTER(0.100),
-       .CLK_FEEDBACK("CLKFBOUT"),
-       .SIM_DEVICE("SPARTAN6")
-) pll2 (
-       .CLKFBDCM(),
-       .CLKFBOUT(buf_pll2_fb_out),
-       .CLKOUT0(pll2out0), /* < x4 clock to capture read data */
-       .CLKOUT1(pll2out1), /* < x4 clock to capture read data */
-       .CLKOUT2(),
-       .CLKOUT3(),
-       .CLKOUT4(),
-       .CLKOUT5(),
-       .CLKOUTDCM0(),
-       .CLKOUTDCM1(),
-       .CLKOUTDCM2(),
-       .CLKOUTDCM3(),
-       .CLKOUTDCM4(),
-       .CLKOUTDCM5(),
-       .DO(),
-       .DRDY(),
-       .LOCKED(pll2_lckd),
-       .CLKFBIN(buf_pll2_fb_out),
-       .CLKIN1(rd_clk_fb_dly_bufio),
-       .CLKIN2(1'b0),
-       .CLKINSEL(1'b1),
-       .DADDR(5'b00000),
-       .DCLK(1'b0),
-       .DEN(1'b0),
-       .DI(16'h0000),
-       .DWE(1'b0),
-       .RST(~pll1_lckd),
-       .REL(1'b0)
-);
-
-BUFPLL #(
-       .DIVIDE(4)
-) rd_bufpll_left (
-       .PLLIN(pll2out0),
-       .GCLK(sys_clk),
-       .LOCKED(pll2_lckd),
-       .IOCLK(clk4x_rd_left),
-       .LOCK(),
-       .SERDESSTROBE(clk4x_rd_strb_left)
-);
-
-BUFPLL #(
-       .DIVIDE(4)
-) rd_bufpll_right (
-       .PLLIN(pll2out1),
-       .GCLK(sys_clk),
-       .LOCKED(pll2_lckd),
-       .IOCLK(clk4x_rd_right),
-       .LOCK(),
-       .SERDESSTROBE(clk4x_rd_strb_right)
-);
-
-wire sdram_sys_clk_lock_d16;
-reg sdram_sys_clk_lock_d17;
-
-/*
- * Async reset generation
- * The reset is de-asserted 16 clocks after both internal clocks are locked.
- */
-
-SRL16 reset_delay_sr(
-       .CLK(sys_clk),
-       .D(pll1_lckd & pll2_lckd),
-       .A0(1'b1),
-       .A1(1'b1),
-       .A2(1'b1),
-       .A3(1'b1),
-       .Q(sdram_sys_clk_lock_d16)
+BUFG bufg_x1(
+       .I(pllout3),
+       .O(sys_clk)
 );
 );
-
-always @(posedge sys_clk)
-       sdram_sys_clk_lock_d17 <= sdram_sys_clk_lock_d16;
-
-assign reset_n = sdram_sys_clk_lock_d17;
  
 endmodule
  
 endmodule
diff --git a/verilog/s6ddrphy/README b/verilog/s6ddrphy/README
deleted file mode 100644 (file)
index eddbdd0..0000000
+++ /dev/null
@@ -1 +0,0 @@
-The Verilog files of the Spartan-6 DDR PHY from Xilinx/Northwest Logic go here.
diff --git a/verilog/s6ddrphy/patches/s6ddrphy.diff b/verilog/s6ddrphy/patches/s6ddrphy.diff
deleted file mode 100644 (file)
index 4ae6a54..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-Index: s6ddrphy/spartan6_soft_phy.v
-===================================================================
---- s6ddrphy.orig/spartan6_soft_phy.v
-+++ s6ddrphy/spartan6_soft_phy.v
-@@ -116,7 +116,6 @@ module spartan6_soft_phy # (
-     inout  [NUM_DQ-1:0]                         sd_dq,                          // Data in from SDRAM device
-     output [NUM_DQS-1:0]                        sd_dm,                          // Data mask to SDRAM devices
-     inout  [NUM_DQS-1:0]                        sd_dqs,                         // DQS
--    inout  [NUM_DQS-1:0]                        sd_dqs_n,                       // complimentary DQS
-     // configuration ports
-     input  [2:0]                                cfg_al,                         // Posted CAS additive latency
-@@ -300,12 +299,11 @@ genvar j;
- generate
-     for (j = 0; j < NUM_DQ/8*(NIBBLE_DEVICES+1) ; j = j + 1)
-     begin:dqs_iob
--        IOBUFDS iobufds (
-+        IOBUF iobufds (
-             .O              (sd_dqs_in[j]),
-             .I              (sd_dqs_out[j]),
-             .T              (sd_dqs_oe_n[j]),
--            .IO             (sd_dqs[j]),
--            .IOB            (sd_dqs_n[j])
-+            .IO             (sd_dqs[j])
-             );
-     end
- endgenerate
diff --git a/verilog/s6ddrphy/patches/series b/verilog/s6ddrphy/patches/series
deleted file mode 100644 (file)
index dd08e5b..0000000
+++ /dev/null
@@ -1 +0,0 @@
-s6ddrphy.diff
diff --git a/verilog/s6ddrphy/s6ddrphy.v b/verilog/s6ddrphy/s6ddrphy.v
new file mode 100644 (file)
index 0000000..f7cd05f
--- /dev/null
@@ -0,0 +1,59 @@
+module s6ddrphy #(
+       parameter NUM_AD = 0,
+       parameter NUM_BA = 0,
+       parameter NUM_D = 0 /* < number of data lines per DFI phase */
+) (
+       /* Clocks */
+       input sys_clk,
+       input clk2x_90,
+       input clk4x_wr,
+       input clk4x_wr_strb,
+       input clk4x_rd,
+       input clk4x_rd_strb,
+       
+       /* DFI phase 0 */
+       input [NUM_AD-1:0] dfi_address_p0,
+       input [NUM_BA-1:0] dfi_bank_p0,
+       input dfi_cs_n_p0,
+       input dfi_cke_p0,
+       input dfi_ras_n_p0,
+       input dfi_cas_n_p0,
+       input dfi_we_n_p0,
+       input dfi_wrdata_en_p0,
+       input [NUM_D/8-1:0] dfi_wrdata_mask_p0,
+       input [NUM_D-1:0] dfi_wrdata_p0,
+       input dfi_rddata_en_p0,
+       output [NUM_D-1:0] dfi_rddata_w0,
+       output dfi_rddata_valid_w0,
+       
+       /* DFI phase 1 */
+       input [NUM_AD-1:0] dfi_address_p1,
+       input [NUM_BA-1:0] dfi_bank_p1,
+       input dfi_cs_n_p1,
+       input dfi_cke_p1,
+       input dfi_ras_n_p1,
+       input dfi_cas_n_p1,
+       input dfi_we_n_p1,
+       input dfi_wrdata_en_p1,
+       input [NUM_D/8-1:0] dfi_wrdata_mask_p1,
+       input [NUM_D-1:0] dfi_wrdata_p1,
+       input dfi_rddata_en_p1,
+       output [NUM_D-1:0] dfi_rddata_w1,
+       output dfi_rddata_valid_w1,
+       
+       /* DDR SDRAM pads */
+       output sd_clk_out_p,
+       output sd_clk_out_n,
+       output [NUM_AD-1:0] sd_a,
+       output [NUM_BA-1:0] sd_ba,
+       output sd_cs_n,
+       output sd_cke,
+       output sd_ras_n,
+       output sd_cas_n,
+       output sd_we_n,
+       inout [NUM_D/2-1:0] sd_dq,
+       output [NUM_D/16-1:0] sd_dm,
+       inout [NUM_D/16-1:0] sd_dqs
+);
+
+endmodule