Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
11 years ago

Problem with Data Integrity & Clock between 2 FPGAs

Hi

I have a problem with data integriry & clock between 2 FPGAs. A scheme of my design is inserted at the end.

My design consists of 2 Cyclone III FPGAs. Each FPGA has several clock domains, each feeding their own logic.

In FPGA-2 there is a PLL which generates two 50 MHz clocks with 180-degree phase shift; i.e. clk2 = NOT clk1.

The clk1 feeds FPGA-2 logic. The clk2 signal goes out from FPGA-2 using a normal IO pin and feeds FPGA-1 logic through a dedicated clock pin.

FPGA-1 generates a 16-bit data using clk2 and sends it to FPGA-2.

Both FPGAs use Fast Input/Output Register on this data bus pins in order to minimize t_co & t_su.

FPGA-2 processes that data using clk1.

I used two clocks with 180 degree phase shift and I hoped that half of clock cycle is sufficient for all delays, including t_co, t_su, PCB delay, etc.

Now, using SignalTap it is evident that FPGA-1 has generated data correctly, but in FPGA-2 received data is corrupted.

What could cause this problem?

  • sending out a clock from a normal IO with Fast Output Register option enabled? Is this a good design practice?

  • Not setting IO delay constraints? Keep in mind that 50 MHz is not so high and PCB tracks are short, though with unequal lengths (less that 0.5 inch)

  • Something else ??!!!

I'm using Quartus-II v.11

My design scheme:

http://www.alteraforum.com/forum/attachment.php?attachmentid=9651&stc=1

Thanks in advance.

20 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    When I run timequest and report datasheet, I get negative values for t_h; i.e. Hold Times. Is this reasonable?

    For some synthesis, t_h is positive, when I change settings t_h becomes negative. Does it mean something is wrong?
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    When I run timequest and report datasheet, I get negative values for t_h; i.e. Hold Times. Is this reasonable?

    For some synthesis, t_h is positive, when I change settings t_h becomes negative. Does it mean something is wrong?

    --- Quote End ---

    negative slack = failure

    You should not just play with settings to get a pass but rather set it to your io correctly.

    Your design is really too complicated for a beginner to get i right because your clk is opposite data direction and you have inserted a PLL with phase shift. I suggest you first remove the pll and compute your settings then if necessary add pll
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Thanks kaz.

    I did not mean my slack is negative. All my slacks are positive.

    When I generate reports using TimeQuest, DataSheet Report can also be generated. The first section of Data Sheet report is Set Up Times and the second section is Hold Times. Keep in mind that they are NOT slack, they are real setup times & hold times (If I'm wrong, please tell me).

    This is the case even for a simple counter. When I synthesize a simple counter & run TimeQuest, I get negative values for Hold Times. When I set Fast Input Registers & Fast Output Registers options ON, I get negative Hold Time for some ports, & positive for others. This is the case for Setup Times.

    Please forget about my design, this is a fundamental question.

    I insert the two reports here for comparison. I have attached a snapshot of my TimeQuest report as well.

    I would be grateful If you have a look at them & tell me what goes wrong.

    Synthesis 1:

    
    +---------------------------------------------------------------------------+
    ; Setup Times                                                               ;
    +---------------+------------+-------+-------+------------+-----------------+
    ; Data Port     ; Clock Port ; Rise  ; Fall  ; Clock Edge ; Clock Reference ;
    +---------------+------------+-------+-------+------------+-----------------+
    ; i_clk_enable  ; clk_in     ; 1.993 ; 2.406 ; Rise       ; clk_in          ;
    ; i_data_in
      ; clk_in     ; 1.703 ; 2.096 ; Rise       ; clk_in          ;
    ;  i_data_in ; clk_in     ; 1.272 ; 1.674 ; Rise       ; clk_in          ;
    ;  i_data_in ; clk_in     ; 1.703 ; 2.096 ; Rise       ; clk_in          ;
    ;  i_data_in ; clk_in     ; 1.357 ; 1.747 ; Rise       ; clk_in          ;
    ;  i_data_in ; clk_in     ; 1.327 ; 1.715 ; Rise       ; clk_in          ;
    ; i_enable      ; clk_in     ; 2.051 ; 2.435 ; Rise       ; clk_in          ;
    ; i_load        ; clk_in     ; 2.657 ; 3.138 ; Rise       ; clk_in          ;
    +---------------+------------+-------+-------+------------+-----------------+
    +-----------------------------------------------------------------------------+
    ; Hold Times                                                                  ;
    +---------------+------------+--------+--------+------------+-----------------+
    ; Data Port     ; Clock Port ; Rise   ; Fall   ; Clock Edge ; Clock Reference ;
    +---------------+------------+--------+--------+------------+-----------------+
    ; i_clk_enable  ; clk_in     ; -1.680 ; -2.067 ; Rise       ; clk_in          ;
    ; i_data_in
      ; clk_in     ; -0.886 ; -1.288 ; Rise       ; clk_in          ;
    ;  i_data_in ; clk_in     ; -0.886 ; -1.288 ; Rise       ; clk_in          ;
    ;  i_data_in ; clk_in     ; -1.321 ; -1.705 ; Rise       ; clk_in          ;
    ;  i_data_in ; clk_in     ; -0.992 ; -1.372 ; Rise       ; clk_in          ;
    ;  i_data_in ; clk_in     ; -0.962 ; -1.340 ; Rise       ; clk_in          ;
    ; i_enable      ; clk_in     ; -1.768 ; -2.140 ; Rise       ; clk_in          ;
    ; i_load        ; clk_in     ; -1.289 ; -1.755 ; Rise       ; clk_in          ;
    +---------------+------------+--------+--------+------------+-----------------+
    +-----------------------------------------------------------------------+
    ; Clock to Output Times                                                 ;
    +-----------+------------+-------+-------+------------+-----------------+
    ; Data Port ; Clock Port ; Rise  ; Fall  ; Clock Edge ; Clock Reference ;
    +-----------+------------+-------+-------+------------+-----------------+
    ; o_done    ; clk_in     ; 7.083 ; 7.151 ; Rise       ; clk_in          ;
    +-----------+------------+-------+-------+------------+-----------------+
    +-----------------------------------------------------------------------+
    ; Minimum Clock to Output Times                                         ;
    +-----------+------------+-------+-------+------------+-----------------+
    ; Data Port ; Clock Port ; Rise  ; Fall  ; Clock Edge ; Clock Reference ;
    +-----------+------------+-------+-------+------------+-----------------+
    ; o_done    ; clk_in     ; 5.684 ; 5.668 ; Rise       ; clk_in          ;
    +-----------+------------+-------+-------+------------+-----------------+
    

    Synthesis 2:

    
    +---------------------------------------------------------------------------+
    ; Setup Times                                                               ;
    +---------------+------------+-------+-------+------------+-----------------+
    ; Data Port     ; Clock Port ; Rise  ; Fall  ; Clock Edge ; Clock Reference ;
    +---------------+------------+-------+-------+------------+-----------------+
    ; i_clk_enable  ; clk_in     ; 2.126 ; 2.583 ; Rise       ; clk_in          ;
    ; i_data_in
      ; clk_in     ; 1.746 ; 2.141 ; Rise       ; clk_in          ;
    ;  i_data_in ; clk_in     ; 1.160 ; 1.557 ; Rise       ; clk_in          ;
    ;  i_data_in ; clk_in     ; 1.585 ; 1.990 ; Rise       ; clk_in          ;
    ;  i_data_in ; clk_in     ; 1.746 ; 2.141 ; Rise       ; clk_in          ;
    ;  i_data_in ; clk_in     ; 1.735 ; 2.140 ; Rise       ; clk_in          ;
    ; i_enable      ; clk_in     ; 2.065 ; 2.499 ; Rise       ; clk_in          ;
    ; i_load        ; clk_in     ; 2.077 ; 2.526 ; Rise       ; clk_in          ;
    +---------------+------------+-------+-------+------------+-----------------+
    +-----------------------------------------------------------------------------+
    ; Hold Times                                                                  ;
    +---------------+------------+--------+--------+------------+-----------------+
    ; Data Port     ; Clock Port ; Rise   ; Fall   ; Clock Edge ; Clock Reference ;
    +---------------+------------+--------+--------+------------+-----------------+
    ; i_clk_enable  ; clk_in     ; -1.757 ; -2.177 ; Rise       ; clk_in          ;
    ; i_data_in
      ; clk_in     ; -0.781 ; -1.177 ; Rise       ; clk_in          ;
    ;  i_data_in ; clk_in     ; -0.781 ; -1.177 ; Rise       ; clk_in          ;
    ;  i_data_in ; clk_in     ; -1.209 ; -1.604 ; Rise       ; clk_in          ;
    ;  i_data_in ; clk_in     ; -1.361 ; -1.747 ; Rise       ; clk_in          ;
    ;  i_data_in ; clk_in     ; -1.351 ; -1.747 ; Rise       ; clk_in          ;
    ; i_enable      ; clk_in     ; -1.781 ; -2.199 ; Rise       ; clk_in          ;
    ; i_load        ; clk_in     ; -0.948 ; -1.363 ; Rise       ; clk_in          ;
    +---------------+------------+--------+--------+------------+-----------------+
    +-----------------------------------------------------------------------+
    ; Clock to Output Times                                                 ;
    +-----------+------------+-------+-------+------------+-----------------+
    ; Data Port ; Clock Port ; Rise  ; Fall  ; Clock Edge ; Clock Reference ;
    +-----------+------------+-------+-------+------------+-----------------+
    ; o_done    ; clk_in     ; 7.100 ; 7.159 ; Rise       ; clk_in          ;
    +-----------+------------+-------+-------+------------+-----------------+
    +-----------------------------------------------------------------------+
    ; Minimum Clock to Output Times                                         ;
    +-----------+------------+-------+-------+------------+-----------------+
    ; Data Port ; Clock Port ; Rise  ; Fall  ; Clock Edge ; Clock Reference ;
    +-----------+------------+-------+-------+------------+-----------------+
    ; o_done    ; clk_in     ; 5.683 ; 5.653 ; Rise       ; clk_in          ;
    +-----------+------------+-------+-------+------------+-----------------+
    
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Those tables are not final slack except that you have thought of them as slack.

    They are to do with arrival times (neg for hold, pos for setup relevant to clk edge) and you don't need them now.

    look at slack report => setup or hold summary or top failing paths. You can select these from TQ GUI directly without need for commands.

    Normally if timing fails you get red coloured text as a warning and quartus reports timing failure at end of messages.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Thanks for your prompt response.

    As you advised me in the previous posts, I want to know setup times & hold times of my IO:

    --- Quote Start ---

    However in practice you can first set input delays of fpga2 at some convenient values and see report(datasheet) to find out tSU/tH achieved at input pins. Then go to fpga1 and set output delays accordingly taking board delays into account

    --- Quote End ---

    The only report that I found was Datasheet Report/Setup Times & Hold Times.

    Setup Summary & Hold Summary only show setup & hold times of my clock, not IO.

    To summarize my problem:

    i want to know setup time & hold time of my ios. How can I have them? Timequest datasheet report? Or some other way?

    If TimeQuest Datasheet Report is that, then is there any problem with negative t_su & t_h values? (These parameters are not slack)
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    If design has one fpga outputting to a DAC(for example) then you get DAC tSU/tH and enter constraints for FPGA outputs accordingly.

    in your case you have two FPGAs. Now you have set input delays for FPGA2 on an arbitrary basis and got above tables for arrival times(the worst values to be taken as tSU/tH of FPGA2).

    Now go to FPGA1 and set output delays based on FPGA2 figures for tSU/tH i.e. max output delay of tSU and min output delay as -tH

    but if clk and data were in same direction(source synchronous).

    In your case clk is opposite data and there is additionally pll phase shift so you need to work that out
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    you have set input delays for FPGA2 on an arbitrary basis and got above tables for arrival times(the worst values to be taken as tSU/tH of FPGA2).

    --- Quote End ---

    And What if the tSU/tH become negative? Does it mean that something goes wrong?
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    And What if the tSU/tH become negative? Does it mean that something goes wrong?

    --- Quote End ---

    it doesn't matter.

    Ideally and right "silicon" deep level of a register both are positive by definition. However, the tool then gives the figures from pins perspective of clk and data as this is more relevant to the designer. This results in a shift of window(of setup + hold) relative to clk edge due to different delays inserted on clk path/data path. a positive setup means it is still before edge and a negative hold means its before edge as well i.e. the window has shifted forward. and vice versa