s6ddrphy: clock, address and command
authorSebastien Bourdeauducq <sebastien@milkymist.org>
Sun, 19 Feb 2012 19:49:56 +0000 (20:49 +0100)
committerSebastien Bourdeauducq <sebastien@milkymist.org>
Sun, 19 Feb 2012 19:49:56 +0000 (20:49 +0100)
constraints.py
verilog/s6ddrphy/s6ddrphy.v

index f68e5bb3de80843ec7c6ab13098a806bd1aa371c..075a955e96d705ba215dbc216c25f9014145e8a0 100644 (file)
@@ -62,6 +62,8 @@ def get(ns, crg0, norflash0, uart0, ddrphy0):
 TIMESPEC "TSclk50" = PERIOD "GRPclk50" 20 ns HIGH 50%;
 INST "m1crg/wr_bufpll" LOC = "BUFPLL_X0Y2";
 INST "m1crg/rd_bufpll" LOC = "BUFPLL_X0Y3";
+
+PIN "m1crg/bufg_x1.O" CLOCK_DEDICATED_ROUTE = FALSE;
 """
        
        return r
index f7cd05faa6eaa901e5dca3930e26efb2908f292a..daa724ab2a13c6ca48725edd50b27bac5c1aed2a 100644 (file)
@@ -44,16 +44,147 @@ module s6ddrphy #(
        /* 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,
+       output reg [NUM_AD-1:0] sd_a,
+       output reg [NUM_BA-1:0] sd_ba,
+       output reg sd_cs_n,
+       output reg sd_cke,
+       output reg sd_ras_n,
+       output reg sd_cas_n,
+       output reg 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
 );
 
+/* 
+ * SDRAM clock
+ */
+ODDR2 #(
+       .DDR_ALIGNMENT("NONE"),
+       .INIT(1'b0),
+       .SRTYPE("SYNC")
+) sd_clk_forward_p (
+       .Q(sd_clk_out_p),
+       .C0(clk2x_90),
+       .C1(~clk2x_90),
+       .CE(1'b1),
+       .D0(1'b1),
+       .D1(1'b0),
+       .R(1'b0),
+       .S(1'b0)
+);
+ODDR2 #(
+       .DDR_ALIGNMENT("NONE"),
+       .INIT(1'b0),
+       .SRTYPE("SYNC")
+) sd_clk_forward_n (
+       .Q(sd_clk_out_n),
+       .C0(clk2x_90),
+       .C1(~clk2x_90),
+       .CE(1'b1),
+       .D0(1'b0),
+       .D1(1'b1),
+       .R(1'b0),
+       .S(1'b0)
+);
+
+/* 
+ * Command/address
+ */
+
+reg phase_sel;
+always @(negedge clk2x_90)
+       phase_sel <= sys_clk;
+
+reg [NUM_AD-1:0] r_dfi_address_p0;
+reg [NUM_BA-1:0] r_dfi_bank_p0;
+reg r_dfi_cs_n_p0;
+reg r_dfi_cke_p0;
+reg r_dfi_ras_n_p0;
+reg r_dfi_cas_n_p0;
+reg r_dfi_we_n_p0;
+reg [NUM_AD-1:0] r_dfi_address_p1;
+reg [NUM_BA-1:0] r_dfi_bank_p1;
+reg r_dfi_cs_n_p1;
+reg r_dfi_cke_p1;
+reg r_dfi_ras_n_p1;
+reg r_dfi_cas_n_p1;
+reg r_dfi_we_n_p1;
+       
+always @(posedge sys_clk) begin
+       r_dfi_address_p0 <= dfi_address_p0;
+       r_dfi_bank_p0 <= dfi_bank_p0;
+       r_dfi_cs_n_p0 <= dfi_cs_n_p0;
+       r_dfi_cke_p0 <= dfi_cke_p0;
+       r_dfi_ras_n_p0 <= dfi_ras_n_p0;
+       r_dfi_cas_n_p0 <= dfi_cas_n_p0;
+       r_dfi_we_n_p0 <= dfi_we_n_p0;
+       
+       r_dfi_address_p1 <= dfi_address_p1;
+       r_dfi_bank_p1 <= dfi_bank_p1;
+       r_dfi_cs_n_p1 <= dfi_cs_n_p1;
+       r_dfi_cke_p1 <= dfi_cke_p1;
+       r_dfi_ras_n_p1 <= dfi_ras_n_p1;
+       r_dfi_cas_n_p1 <= dfi_cas_n_p1;
+       r_dfi_we_n_p1 <= dfi_we_n_p1;
+end
+
+reg [NUM_AD-1:0] r2_dfi_address_p0;
+reg [NUM_BA-1:0] r2_dfi_bank_p0;
+reg r2_dfi_cs_n_p0;
+reg r2_dfi_cke_p0;
+reg r2_dfi_ras_n_p0;
+reg r2_dfi_cas_n_p0;
+reg r2_dfi_we_n_p0;
+reg [NUM_AD-1:0] r2_dfi_address_p1;
+reg [NUM_BA-1:0] r2_dfi_bank_p1;
+reg r2_dfi_cs_n_p1;
+reg r2_dfi_cke_p1;
+reg r2_dfi_ras_n_p1;
+reg r2_dfi_cas_n_p1;
+reg r2_dfi_we_n_p1;
+       
+always @(negedge clk2x_90) begin
+       r2_dfi_address_p0 <= r_dfi_address_p0;
+       r2_dfi_bank_p0 <= r_dfi_bank_p0;
+       r2_dfi_cs_n_p0 <= r_dfi_cs_n_p0;
+       r2_dfi_cke_p0 <= r_dfi_cke_p0;
+       r2_dfi_ras_n_p0 <= r_dfi_ras_n_p0;
+       r2_dfi_cas_n_p0 <= r_dfi_cas_n_p0;
+       r2_dfi_we_n_p0 <= r_dfi_we_n_p0;
+       
+       r2_dfi_address_p1 <= r_dfi_address_p1;
+       r2_dfi_bank_p1 <= r_dfi_bank_p1;
+       r2_dfi_cs_n_p1 <= r_dfi_cs_n_p1;
+       r2_dfi_cke_p1 <= r_dfi_cke_p1;
+       r2_dfi_ras_n_p1 <= r_dfi_ras_n_p1;
+       r2_dfi_cas_n_p1 <= r_dfi_cas_n_p1;
+       r2_dfi_we_n_p1 <= r_dfi_we_n_p1;
+end
+
+always @(posedge clk2x_90) begin
+       if(phase_sel) begin
+               sd_a <= r2_dfi_address_p1;
+               sd_ba <= r2_dfi_bank_p1;
+               sd_cs_n <= r2_dfi_cs_n_p1;
+               sd_cke <= r2_dfi_cke_p1;
+               sd_ras_n <= r2_dfi_ras_n_p1;
+               sd_cas_n <= r2_dfi_cas_n_p1;
+               sd_we_n <= r2_dfi_we_n_p1;
+       end else begin
+               sd_a <= r2_dfi_address_p0;
+               sd_ba <= r2_dfi_bank_p0;
+               sd_cs_n <= r2_dfi_cs_n_p0;
+               sd_cke <= r2_dfi_cke_p0;
+               sd_ras_n <= r2_dfi_ras_n_p0;
+               sd_cas_n <= r2_dfi_cas_n_p0;
+               sd_we_n <= r2_dfi_we_n_p0;
+       end
+end
+
+// TODO
+assign sd_dq = 32'hzzzzzzzz;
+assign sd_dm = 0;
+assign sd_dqs = 4'hz;
 endmodule