2 * 1:2 frequency-ratio DDR PHY for Spartan-6
4 ************* DATAPATH SIGNALS ***********
5 * Assert dfi_wrdata_en and present the data
6 * on dfi_wrdata_mask/dfi_wrdata in the same
7 * cycle as the write command.
9 * Assert dfi_rddata_en in the same cycle as the read
10 * command. The data will come back on dfi_rddata
11 * 4 cycles later, along with the assertion of
14 * This PHY only supports CAS Latency 3.
15 * Read commands must be sent on phase 0.
16 * Write commands must be sent on phase 1.
22 parameter NUM_D = 0 /* < number of data lines per DFI phase */
33 input [NUM_AD-1:0] dfi_address_p0,
34 input [NUM_BA-1:0] dfi_bank_p0,
40 input dfi_wrdata_en_p0,
41 input [NUM_D/8-1:0] dfi_wrdata_mask_p0,
42 input [NUM_D-1:0] dfi_wrdata_p0,
43 input dfi_rddata_en_p0,
44 output [NUM_D-1:0] dfi_rddata_w0,
45 output dfi_rddata_valid_w0,
48 input [NUM_AD-1:0] dfi_address_p1,
49 input [NUM_BA-1:0] dfi_bank_p1,
55 input dfi_wrdata_en_p1,
56 input [NUM_D/8-1:0] dfi_wrdata_mask_p1,
57 input [NUM_D-1:0] dfi_wrdata_p1,
58 input dfi_rddata_en_p1,
59 output [NUM_D-1:0] dfi_rddata_w1,
60 output dfi_rddata_valid_w1,
65 output reg [NUM_AD-1:0] sd_a,
66 output reg [NUM_BA-1:0] sd_ba,
72 inout [NUM_D/2-1:0] sd_dq,
73 output [NUM_D/16-1:0] sd_dm,
74 inout [NUM_D/16-1:0] sd_dqs
81 .DDR_ALIGNMENT("NONE"),
95 .DDR_ALIGNMENT("NONE"),
114 always @(posedge clk2x_270)
115 phase_sel <= sys_clk;
117 reg [NUM_AD-1:0] r_dfi_address_p0;
118 reg [NUM_BA-1:0] r_dfi_bank_p0;
124 reg [NUM_AD-1:0] r_dfi_address_p1;
125 reg [NUM_BA-1:0] r_dfi_bank_p1;
132 always @(posedge clk2x_270) begin
133 r_dfi_address_p0 <= dfi_address_p0;
134 r_dfi_bank_p0 <= dfi_bank_p0;
135 r_dfi_cs_n_p0 <= dfi_cs_n_p0;
136 r_dfi_cke_p0 <= dfi_cke_p0;
137 r_dfi_ras_n_p0 <= dfi_ras_n_p0;
138 r_dfi_cas_n_p0 <= dfi_cas_n_p0;
139 r_dfi_we_n_p0 <= dfi_we_n_p0;
141 r_dfi_address_p1 <= dfi_address_p1;
142 r_dfi_bank_p1 <= dfi_bank_p1;
143 r_dfi_cs_n_p1 <= dfi_cs_n_p1;
144 r_dfi_cke_p1 <= dfi_cke_p1;
145 r_dfi_ras_n_p1 <= dfi_ras_n_p1;
146 r_dfi_cas_n_p1 <= dfi_cas_n_p1;
147 r_dfi_we_n_p1 <= dfi_we_n_p1;
150 always @(posedge clk2x_270) begin
152 sd_a <= r_dfi_address_p0;
153 sd_ba <= r_dfi_bank_p0;
154 sd_cs_n <= r_dfi_cs_n_p0;
155 sd_cke <= r_dfi_cke_p0;
156 sd_ras_n <= r_dfi_ras_n_p0;
157 sd_cas_n <= r_dfi_cas_n_p0;
158 sd_we_n <= r_dfi_we_n_p0;
160 sd_a <= r_dfi_address_p1;
161 sd_ba <= r_dfi_bank_p1;
162 sd_cs_n <= r_dfi_cs_n_p1;
163 sd_cke <= r_dfi_cke_p1;
164 sd_ras_n <= r_dfi_ras_n_p1;
165 sd_cas_n <= r_dfi_cas_n_p1;
166 sd_we_n <= r_dfi_we_n_p1;
177 wire [NUM_D/16-1:0] dqs_o;
178 wire [NUM_D/16-1:0] dqs_t;
181 for(i=0;i<NUM_D/16;i=i+1)
184 .DDR_ALIGNMENT("C1"),
198 .DDR_ALIGNMENT("C1"),
206 .D0(~(drive_dqs | postamble)),
218 always @(posedge clk2x_270)
219 postamble <= drive_dqs;
221 reg [NUM_D-1:0] d_dfi_wrdata_p0;
222 reg [NUM_D-1:0] d_dfi_wrdata_p1;
223 reg [NUM_D/8-1:0] d_dfi_wrdata_mask_p0;
224 reg [NUM_D/8-1:0] d_dfi_wrdata_mask_p1;
225 always @(posedge sys_clk) begin
226 d_dfi_wrdata_p0 <= dfi_wrdata_p0;
227 d_dfi_wrdata_p1 <= dfi_wrdata_p1;
228 d_dfi_wrdata_mask_p0 <= dfi_wrdata_mask_p0;
229 d_dfi_wrdata_mask_p1 <= dfi_wrdata_mask_p1;
234 wire [NUM_D/2-1:0] dq_i;
235 wire [NUM_D/2-1:0] dq_o;
236 wire [NUM_D/2-1:0] dq_t;
238 for(i=0;i<NUM_D/2;i=i+1)
242 .DATA_RATE_OQ("SDR"),
243 .DATA_RATE_OT("SDR"),
244 .SERDES_MODE("NONE"),
245 .OUTPUT_MODE("SINGLE_ENDED")
251 .IOCE(clk4x_wr_strb),
254 .D1(d_dfi_wrdata_p0[i]),
255 .D2(d_dfi_wrdata_p1[i+NUM_D/2]),
256 .D3(d_dfi_wrdata_p1[i]),
257 .D4(dfi_wrdata_p0[i+NUM_D/2]),
277 .BITSLIP_ENABLE("FALSE"),
278 .SERDES_MODE("NONE"),
279 .INTERFACE_TYPE("RETIMED")
285 .IOCE(clk4x_rd_strb),
291 .Q1(dfi_rddata_w0[i+NUM_D/2]),
292 .Q2(dfi_rddata_w0[i]),
293 .Q3(dfi_rddata_w1[i+NUM_D/2]),
294 .Q4(dfi_rddata_w1[i]),
312 for(i=0;i<NUM_D/16;i=i+1)
313 begin: gen_dm_oserdes
316 .DATA_RATE_OQ("SDR"),
317 .DATA_RATE_OT("SDR"),
318 .SERDES_MODE("NONE"),
319 .OUTPUT_MODE("SINGLE_ENDED")
325 .IOCE(clk4x_wr_strb),
328 .D1(d_dfi_wrdata_mask_p0[i]),
329 .D2(d_dfi_wrdata_mask_p1[i+NUM_D/16]),
330 .D3(d_dfi_wrdata_mask_p1[i]),
331 .D4(dfi_wrdata_mask_p0[i+NUM_D/16]),
355 reg d_dfi_wrdata_en_p1;
356 always @(posedge sys_clk)
357 d_dfi_wrdata_en_p1 <= dfi_wrdata_en_p1;
359 assign drive_dq = dfi_wrdata_en_p1;
360 assign d_drive_dq = d_dfi_wrdata_en_p1;
363 reg r2_dfi_wrdata_en;
364 always @(posedge clk2x_270) begin
365 r_dfi_wrdata_en <= d_dfi_wrdata_en_p1;
366 r2_dfi_wrdata_en <= r_dfi_wrdata_en;
369 assign drive_dqs = r2_dfi_wrdata_en;
373 assign dfi_rddata_valid_w0 = rddata_sr[0];
374 assign dfi_rddata_valid_w1 = rddata_sr[0];
375 always @(posedge sys_clk)
376 rddata_sr <= {dfi_rddata_en_p0, rddata_sr[4:1]};