Monday, October 5, 2009

OFFSET IN constraints for source synchronous DDR inputs

There are several ways to set up OFFSET IN constraints for source synchronous DDR inputs. Personally I like to put all inputs into a timing group and add OFFSET IN constraint on the timing group. There are several advantages with this method:
  • Inputs with different names can be easily grouped together.
  • Only one (SDR) or two (DDR) OFFSET IN constraints are required for each timing group.
  • Timing report is more concise because of fewer OFFSET IN constraints required.
Below is a Spartan6 design example with just one IDDR2 primitive instantiated:
module ss_ddr_in (
     input  clk_i,
     input  ddr_d_i,
     output d_rising_o,
     output d_falling_o
);

wire clk0, clk180;

assign clk0 = clk_i;
assign clk180 = ~clk_i;
    
IDDR2 #(
   .DDR_ALIGNMENT ("NONE"), // Sets output alignment to "NONE", "C0" or "C1" 
   .INIT_Q0       (1'b0), // Sets initial state of the Q0 output to 1'b0 or 1'b1
   .INIT_Q1       (1'b0), // Sets initial state of the Q1 output to 1'b0 or 1'b1
   .SRTYPE        ("SYNC") // Specifies "SYNC" or "ASYNC" set/reset
) IDDR2_inst (
   .Q0 (d_rising_o), // 1-bit output captured with C0 clock
   .Q1 (d_falling_o), // 1-bit output captured with C1 clock
   .C0 (clk0), // 1-bit clock input
   .C1 (clk180), // 1-bit clock input
   .CE (1'b1), // 1-bit clock enable input
   .D  (ddr_d_i),   // 1-bit DDR data input
   .R  (1'b0),   // 1-bit reset input
   .S  (1'b0)    // 1-bit set input
);

endmodule
Below are UCF constraints for the data input.
NET "clk_i" TNM_NET = clk_i;
TIMESPEC TS_clk_i = PERIOD "clk_i" 20 ns HIGH 50%;

INST "ddr_d_i" TNM = TN_ddr_in_pads;
TIMEGRP "TN_ddr_in_pads" OFFSET = IN 5 ns VALID 10 ns BEFORE "clk_i" RISING;
TIMEGRP "TN_ddr_in_pads" OFFSET = IN 5 ns VALID 10 ns BEFORE "clk_i" FALLING;
Timing report on the OFFSET constraints:
Timing constraint: TIMEGRP "TN_ddr_in_pads" OFFSET = IN 5 ns VALID 10 ns BEFORE COMP "clk_i"         "RISING";
 1 path analyzed, 1 endpoint analyzed, 0 failing endpoints
 0 timing errors detected. (0 setup errors, 0 hold errors)
 Offset is  -0.666ns.
--------------------------------------------------------------------------------
Slack (setup path):     5.666ns (requirement - (data path - clock path - clock arrival + uncertainty))
  Source:               ddr_d_i (PAD)
  Destination:          IDDR2_inst (FF)
  Destination Clock:    clk_i_BUFGP rising at 0.000ns
  Requirement:          5.000ns
  Data Path Delay:      2.724ns (Levels of Logic = 2)
  Clock Path Delay:     3.390ns (Levels of Logic = 2)
  Clock Uncertainty:    0.000ns

  Maximum Data Path: ddr_d_i to IDDR2_inst
    Location             Delay type         Delay(ns)  Logical Resource(s)
    -------------------------------------------------  -------------------
    W4.I                 Tiopi                 1.140   ddr_d_i
                                                       ddr_d_i_IBUF
                                                       ProtoComp0.IMUX.1
    ILOGIC_X0Y7.D        net (fanout=1)        0.128   ddr_d_i_IBUF
    ILOGIC_X0Y7.CLK0     Tidock                1.456   ProtoComp2.D2OFFBYP_SRC
                                                       IDDR2_inst
    -------------------------------------------------  ---------------------------
    Total                                      2.724ns (2.596ns logic, 0.128ns route)
                                                       (95.3% logic, 4.7% route)

  Minimum Clock Path: clk_i to IDDR2_inst
    Location             Delay type         Delay(ns)  Logical Resource(s)
    -------------------------------------------------  -------------------
    N4.I                 Tiopi                 1.049   clk_i
                                                       SP6_AUTOBUF_BUFGP_ML_IBUF_4
                                                       ProtoComp0.IMUX
    BUFGMUX_X3Y13.I0     net (fanout=1)        0.747   SP6_AUTOBUF_BUFGP_ML_IBUF_4_ML_NEW_I
    BUFGMUX_X3Y13.O      Tgi0o                 0.220   clk_i_BUFGP
    ILOGIC_X0Y7.CLK0     net (fanout=2)        1.374   clk_i_BUFGP
    -------------------------------------------------  ---------------------------
    Total                                      3.390ns (1.269ns logic, 2.121ns route)
                                                       (37.4% logic, 62.6% route)
Timing constraint: TIMEGRP "TN_ddr_in_pads" OFFSET = IN 5 ns VALID 10 ns BEFORE COMP "clk_i"         "FALLING";
 1 path analyzed, 1 endpoint analyzed, 0 failing endpoints
 0 timing errors detected. (0 setup errors, 0 hold errors)
 Offset is  -0.666ns.
--------------------------------------------------------------------------------
Slack (setup path):     5.666ns (requirement - (data path - clock path - clock arrival + uncertainty))
  Source:               ddr_d_i (PAD)
  Destination:          IDDR2_inst (FF)
  Destination Clock:    clk_i_BUFGP falling at 0.000ns
  Requirement:          5.000ns
  Data Path Delay:      2.724ns (Levels of Logic = 2)
  Clock Path Delay:     3.390ns (Levels of Logic = 2)
  Clock Uncertainty:    0.000ns

  Maximum Data Path: ddr_d_i to IDDR2_inst
    Location             Delay type         Delay(ns)  Logical Resource(s)
    -------------------------------------------------  -------------------
    W4.I                 Tiopi                 1.140   ddr_d_i
                                                       ddr_d_i_IBUF
                                                       ProtoComp0.IMUX.1
    ILOGIC_X0Y7.D        net (fanout=1)        0.128   ddr_d_i_IBUF
    ILOGIC_X0Y7.CLK1     Tidock                1.456   ProtoComp2.D2OFFBYP_SRC
                                                       IDDR2_inst
    -------------------------------------------------  ---------------------------
    Total                                      2.724ns (2.596ns logic, 0.128ns route)
                                                       (95.3% logic, 4.7% route)

  Minimum Clock Path: clk_i to IDDR2_inst
    Location             Delay type         Delay(ns)  Logical Resource(s)
    -------------------------------------------------  -------------------
    N4.I                 Tiopi                 1.049   clk_i
                                                       SP6_AUTOBUF_BUFGP_ML_IBUF_4
                                                       ProtoComp0.IMUX
    BUFGMUX_X3Y13.I0     net (fanout=1)        0.747   SP6_AUTOBUF_BUFGP_ML_IBUF_4_ML_NEW_I
    BUFGMUX_X3Y13.O      Tgi0o                 0.220   clk_i_BUFGP
    ILOGIC_X0Y7.CLK1     net (fanout=2)        1.374   clk_i_BUFGP
    -------------------------------------------------  ---------------------------
    Total                                      3.390ns (1.269ns logic, 2.121ns route)
                                                       (37.4% logic, 62.6% route)

Please note that ISE continues to improve the constraint syntax and report format, so you may see things work slightly differently in previous versions of ISE.

Below is a list of references that can be very useful:

1 comment:

  1. Very nicely done post. Been having issues with DDR timing from an ADC and stumbled upon this. I have one question though.

    What does the pin declaration look like for the data in pins? I have AD0_N<0>/AD0_P<0> through AD0_N<11>/AD0_P<11>, would I set it up like this:
    NET "AD0_N<0>" LOC = "P22" |IOSTANDARD = DIFF_SSTL18_II_DCI |TNM= "TN_ddr_in_pads";

    If so, where does the ddr_d_i in your INST example go, should it be replaced with AD0_N in my above statement?

    Thanks and keep it up!

    ReplyDelete