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
-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 && 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
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
 
-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.
@@ -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
-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
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.rd_clk_lb, "K5", extra="IOSTANDARD = SSTL2_I")
        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%;
-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
index 37b19e5a01a4e8fc7a806324b11c87f510d3015a..a0b49b61ac3d9f3d9a2317c3a8ca39aaedb583bf 100644 (file)
@@ -15,21 +15,15 @@ class M1CRG:
                        "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))  
                
-               self.rd_clk_lb = Signal()
-               
                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)
-                       ], [
-                               ("rd_clk_lb", self.rd_clk_lb)
-                       ], [
+                       ],
+                       parameters=[
                                ("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],
-                       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.bank.description import *
-from migen.bank import csrgen
 
 class S6DDRPHY:
-       def __init__(self, csr_address, a, ba, d):
+       def __init__(self, a, ba, d):
                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 = []
-               sd_d = d//4
                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_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)
@@ -46,93 +39,20 @@ class S6DDRPHY:
                        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 += [
-                       ("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,
                        [
-                               ("DSIZE", d),
                                ("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):
-               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 <hw/s6ddrphy.h>
 #include <hw/dfii.h>
 
 #include "ddrinit.h"
@@ -79,54 +78,11 @@ static void init_sequence(void)
        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");
        
-       CSR_DDRPHY_STATUS = DDRPHY_STATUS_RESETN;
        init_sequence();
-       CSR_DDRPHY_STATUS = DDRPHY_STATUS_RESETN|DDRPHY_STATUS_INIT_DONE;
-       calibrate_phy();
        
        return 1;
 }
index 9a58faac9f2e466f9140e791939a531fcace6383..045e25aede4f70d6d2d260968000fc709e9085a8 100644 (file)
@@ -20,7 +20,7 @@
 
 #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_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 */
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_d = 128 # TODO -> 64
+dfi_d = 64
 
 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)
@@ -42,8 +38,8 @@ def get():
        #
        # 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)
 
        #
@@ -80,7 +76,6 @@ def get():
        uart0 = uart.UART(0, clk_freq, baud=115200)
        csrcon0 = csr.Interconnect(wishbone2csr0.csr, [
                uart0.bank.interface,
-               ddrphy0.bank.interface,
                dfii0.bank.interface
        ])
        
index e885a0c0cae7445642a19b22aa4a11880629d948..0ab04410560b5769c1583bf73a525a9ce3beb707 100644 (file)
@@ -32,37 +32,25 @@ module m1crg #(
        output videoin_rst_n,
        output flash_rst_n,
        
-       /* DDR PHY clocks and reset */
+       /* DDR PHY clocks */
        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
  */
 
-wire reset_n;
-
 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;
-               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;
@@ -79,23 +67,19 @@ assign videoin_rst_n = ~sys_rst;
 
 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;
-       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];
 
 /*
- * Clock management. Largely taken from the NWL reference design.
+ * Clock management. Inspired by the NWL reference design.
  */
+
 wire sdr_clkin;
 wire clkdiv;
 
@@ -117,12 +101,12 @@ BUFIO2 #(
        .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"),
@@ -136,12 +120,12 @@ PLL_ADV #(
        .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_PHASE(0.0),
-       .CLKOUT3_DIVIDE(2*f_div),
+       .CLKOUT2_PHASE(90.0),
+       .CLKOUT3_DIVIDE(4*f_div),
        .CLKOUT3_DUTY_CYCLE(0.5),
-       .CLKOUT3_PHASE(90),
+       .CLKOUT3_PHASE(0.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")
-) pll1 (
+) pll (
        .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(),
@@ -170,8 +154,8 @@ PLL_ADV #(
        .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),
@@ -186,239 +170,34 @@ PLL_ADV #(
 
 BUFPLL #(
        .DIVIDE(4)
-) wr_bufpll_left (
-       .PLLIN(pll1out0),
+) wr_bufpll (
+       .PLLIN(pllout0),
        .GCLK(sys_clk),
-       .LOCKED(pll1_lckd),
-       .IOCLK(clk4x_wr_left),
+       .LOCKED(pll_lckd),
+       .IOCLK(clk4x_wr),
        .LOCK(),
-       .SERDESSTROBE(clk4x_wr_strb_left)
+       .SERDESSTROBE(clk4x_wr_strb)
 );
 
 BUFPLL #(
        .DIVIDE(4)
-) wr_bufpll_right (
-       .PLLIN(pll1out1),
+) rd_bufpll (
+       .PLLIN(pllout1),
        .GCLK(sys_clk),
-       .LOCKED(pll1_lckd),
-       .IOCLK(clk4x_wr_right),
+       .LOCKED(pll_lckd),
+       .IOCLK(clk4x_rd),
        .LOCK(),
-       .SERDESSTROBE(clk4x_wr_strb_right)
-);
-
-BUFG bufg_x1(
-       .I(pll1out2),
-       .O(sys_clk)
+       .SERDESSTROBE(clk4x_rd_strb)
 );
 
 BUFG bufg_x2_2(
-       .I(pll1out3),
+       .I(pllout2),
        .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
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