Tuesday, August 10, 2010

Aligning DQSs - Add ODDR at IOs

I want to start seeing more appropriate write leveling data. Currently the write leveling is giving coherent results, but they are unaligned. I see that is because of the routing per each DQS from their FF. Now I've added an ODDR to put all DQSs at their respective IOs. Xilinx's tools require that the ODDR sit before the IODELAY. Here is the relevant code in top.v:


genvar dqs_i;
generate
for(dqs_i = 0; dqs_i < 8; dqs_i = dqs_i + 1) begin : dqs_gen
wire dqs_out_oddr;
wire dqs_out_delay;
ODDR dqs_oddr_inst(
.Q(dqs_out_oddr),
.C(clkout0),
.CE(1'b1),
.D1(dqs_out[dqs_i]),
.D2(dqs_out[dqs_i]),
.R(1'b0),
.S(1'b0)
);
(* IODELAY_GROUP = "IODELAY_GROUP_INST" *)
IODELAYE1 # (
.DELAY_SRC("O"),
.IDELAY_TYPE("VARIABLE"),
.ODELAY_TYPE("VARIABLE"),
.ODELAY_VALUE(0),
.REFCLK_FREQUENCY(200.0),
.SIGNAL_PATTERN("DATA")
) dqs_iodelaye1_inst(
.C(sysclk),
.CE(dqs_out_delay_ce),
.CINVCTRL(1'b0),
.CLKIN(1'b0),
.CNTVALUEIN(5'h0),
.CNTVALUEOUT(cntvalueout[dqs_i]),
.DATAIN(1'b0),
.DATAOUT(dqs_out_delay),
.IDATAIN(1'b0),
.INC(1'b1),
.ODATAIN(dqs_out_oddr),
.RST(reset_sync),
.T()
);
IOBUFDS_DIFF_OUT dqs_iobufds_diff_out_inst(
.O(dqs_in_p[dqs_i]),
.OB(dqs_in_n[dqs_i]),
.IO(DDR3_DQS_P[dqs_i]),
.IOB(DDR3_DQS_N[dqs_i]),
.I(dqs_out_delay),
.TM(dqs_tri_p[dqs_i]),
.TS(dqs_tri_n[dqs_i])
);
end
endgenerate

I now see in chipscope that the DQSs are moving in a more uniform manner.

No comments:

Post a Comment