1
+ /*
2
+ * 1:2 DDR PHY for Spartan-6
3
+ *
4
+ * Command path:
5
+ * posedge sys_clk + 1
6
+ * negedge clk2x_90 + 0.375
7
+ * negedge clk2x_90 + 0.5
8
+ * Command latency: 1.875 cycles
9
+ *
10
+ * Data write path (phase 0, word 0):
11
+ * posedge sys_clk [oserdes] + 1
12
+ * strobe [oserdes] + 1
13
+ * Data write latency: 2 cycles
14
+ *
15
+ * DQS OE path:
16
+ * posedge sys_clk + 1
17
+ * negedge clk2x_90 + 0.375
18
+ * negedge clk2x_90 [oddr] + 0.5
19
+ * DQS OE latency 1.875 cycles
20
+ *
21
+ * Data read path:
22
+ */
1
23
module s6ddrphy #(
2
24
parameter NUM_AD = 0 ,
3
25
parameter NUM_BA = 0 ,
@@ -162,7 +184,7 @@ always @(negedge clk2x_90) begin
162
184
r2_dfi_we_n_p1 <= r_dfi_we_n_p1;
163
185
end
164
186
165
- always @(posedge clk2x_90) begin
187
+ always @(negedge clk2x_90) begin
166
188
if (phase_sel) begin
167
189
sd_a <= r2_dfi_address_p1;
168
190
sd_ba <= r2_dfi_bank_p1;
@@ -188,14 +210,15 @@ end
188
210
189
211
genvar i;
190
212
191
- wire drive_dqs;
213
+ wire drive_dqs_p0;
214
+ wire drive_dqs_p1;
192
215
wire [NUM_D/ 16 - 1 :0 ] dqs_o;
193
216
wire [NUM_D/ 16 - 1 :0 ] dqs_t;
194
217
generate
195
218
for (i= 0 ;i< NUM_D/ 16 ;i= i+ 1 )
196
219
begin : gen_dqs
197
220
ODDR2 #(
198
- .DDR_ALIGNMENT("C0 " ),
221
+ .DDR_ALIGNMENT("C1 " ),
199
222
.INIT(1'b0 ),
200
223
.SRTYPE("ASYNC" )
201
224
) dqs_o_oddr (
@@ -209,16 +232,16 @@ generate
209
232
.S(1'b0 )
210
233
);
211
234
ODDR2 #(
212
- .DDR_ALIGNMENT("C0 " ),
235
+ .DDR_ALIGNMENT("C1 " ),
213
236
.INIT(1'b0 ),
214
237
.SRTYPE("ASYNC" )
215
238
) dqs_t_oddr (
216
239
.Q(dqs_t[i]),
217
240
.C0(clk2x_90),
218
241
.C1(~clk2x_90),
219
242
.CE(1'b1 ),
220
- .D0(~drive_dqs ),
221
- .D1(~drive_dqs ),
243
+ .D0(~drive_dqs_p0 ),
244
+ .D1(~drive_dqs_p1 ),
222
245
.R(1'b0 ),
223
246
.S(1'b0 )
224
247
);
@@ -230,7 +253,8 @@ generate
230
253
end
231
254
endgenerate
232
255
233
- wire drive_dq;
256
+ wire drive_dq_p0;
257
+ wire drive_dq_p1;
234
258
wire [NUM_D/ 2 - 1 :0 ] dq_i;
235
259
wire [NUM_D/ 2 - 1 :0 ] dq_o;
236
260
wire [NUM_D/ 2 - 1 :0 ] dq_t;
@@ -256,10 +280,10 @@ generate
256
280
.D3(dfi_wrdata_p1[2 *i]),
257
281
.D4(dfi_wrdata_p1[2 *i+1 ]),
258
282
.TQ(dq_t[i]),
259
- .T1(~drive_dq ),
260
- .T2(~drive_dq ),
261
- .T3(~drive_dq ),
262
- .T4(~drive_dq ),
283
+ .T1(~drive_dq_p0 ),
284
+ .T2(~drive_dq_p0 ),
285
+ .T3(~drive_dq_p1 ),
286
+ .T4(~drive_dq_p1 ),
263
287
.TRAIN(1'b0 ),
264
288
.TCE(1'b1 ),
265
289
.SHIFTIN1(1'b0 ),
@@ -352,9 +376,27 @@ endgenerate
352
376
* DQ/DQS/DM control
353
377
*/
354
378
355
- // TODO
379
+ reg r_dfi_wrdata_en_p0;
380
+ reg r_dfi_wrdata_en_p1;
381
+
382
+ always @(posedge sys_clk) begin
383
+ r_dfi_wrdata_en_p0 <= dfi_wrdata_en_p0;
384
+ r_dfi_wrdata_en_p1 <= dfi_wrdata_en_p1;
385
+ end
386
+
387
+ reg r2_dfi_wrdata_en_p0;
388
+ reg r2_dfi_wrdata_en_p1;
389
+
390
+ always @(negedge clk2x_90) begin
391
+ r2_dfi_wrdata_en_p0 <= r_dfi_wrdata_en_p0;
392
+ r2_dfi_wrdata_en_p1 <= r_dfi_wrdata_en_p1;
393
+ end
394
+
395
+ assign drive_dqs_p0 = r2_dfi_wrdata_en_p0;
396
+ assign drive_dqs_p1 = r2_dfi_wrdata_en_p1;
397
+ assign drive_dq_p0 = dfi_wrdata_en_p0;
398
+ assign drive_dq_p1 = dfi_wrdata_en_p1;
356
399
357
- assign drive_dqs = 0 ;
358
- assign drive_dq = 0 ;
400
+ // TODO: dfi_rddata_valid_w0/1?
359
401
360
402
endmodule
0 commit comments