cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Scholar
Scholar
3,671 Views
Registered: ‎06-23-2014

How to deal with MIG timing constraints?

I'm using Vivado 2017.1 and the KC705 development board.

 

I still don't understand well how to set timing constraints.  Please allow me to ask a specific question.  I have a create_clock constraint for SYSCLK_P in my constraints file.  I have used MIG and had good success in the past with the memory actually working on the KC705.  Now, however, I'm having some timing trouble, not directly with the memory, but nearby.

 

In the Timing Summary under Check Timing, I find some no_clock signals that appear related to my circuitry surrounding my memory interface.  Specifically, the u_mig_7series_0 module receives a 200MHz "clk" from me and produces a 200MHz "ui_clk".  My circuitry surrounding this (a multi-port memory controller I've written), uses the ui_clk, not clk, and connects with outside circuitry that does use clk via two-clock FIFOs.  So these no_clock signals seem related to my use of ui_clk.  They are signals inside an "always @(posedge ui_clk)" block.  This makes me think I should put in a clock constraint for ui_clk.  

 

However, when I try to use "Edit Timing Constraints" and create a new clock, I don't know what source object to use.  I guess I'd have the same question if I edited my constraints file directly.  I could simply mention that ui_clk has a particular period, but I wouldn't know what to provide to "get_ports".

 

Thinking big picture, I am seeing funny data in the ILA and it seems like setup problems.  I have a number of timing errors.  The situation above is just the tip of the iceberg in trying to resolve all this.

 

Please help!

 

Thanks,

Helmut

0 Kudos
9 Replies
Highlighted
Voyager
Voyager
3,640 Views
Registered: ‎06-24-2013

Re: How to deal with MIG timing constraints?

Hey @helmutforren

 

It has been some time that I read through the MIG documentation, but if I remember correctly, the MIG contains a PLL which generates the various clock signals including the logic clock which is the base for ui_clk.

Long story short, the ui_clk output should be a derived clock which gets its clock constraint from the PLL.

 

But maybe that changed somehow ...

 

Hope it helps,

Herbert

-------------- Yes, I do this for fun!
0 Kudos
Highlighted
Scholar
Scholar
3,587 Views
Registered: ‎06-23-2014

Re: How to deal with MIG timing constraints?

@hpoetzl thanks for that info.  Next, given that ui_clk should therefore be so constrained, do you have any idea why I might be getting the "no_clock" warnings for signals that appear to be clocked by ui_clk?  Do you know of any common human errors that might lead to this warning?  For example, from experience I know of warnings that are subtle but true, and I know of warnings that are totally mis-representative of the true problem (like missing semicolons cause when parsing).

0 Kudos
Highlighted
Voyager
Voyager
3,577 Views
Registered: ‎06-24-2013

Re: How to deal with MIG timing constraints?

@@helmutforren

 

Do you have any idea why I might be getting the "no_clock" warnings for signals that appear to be clocked by ui_clk?

Do you know of any common human errors that might lead to this warning?

 

Sorry, no idea. But it is hard to tell without any examples (of code and of the signals in question).

 

Best,

Herbert

-------------- Yes, I do this for fun!
0 Kudos
Highlighted
Xilinx Employee
Xilinx Employee
3,539 Views
Registered: ‎09-20-2012

Re: How to deal with MIG timing constraints?

Hi @helmutforren

 

Are the MIG input pins sys_clk_* directly connected to top level ports in your design? If you have chosen "single ended" or "differential" for system clock buffer type then the IP generates clock period constraint. If you have selected "no buffer" option, you need to write create_clock constraint in your top level xdc.

 

Can you run report_clocks command on synthesized design and show us the result?

Thanks,
Deepika.
--------------------------------------------------------------------------------------------
Google your question before posting. If someone's post answers your question, mark the post as answer with "Accept as solution". If you see a particularly good and informative post, consider giving it Kudos (the star on the left)
0 Kudos
Highlighted
Scholar
Scholar
3,523 Views
Registered: ‎06-23-2014

Re: How to deal with MIG timing constraints?

@vemulad Deepika,

 

Thanks very much for your prompt reply.  I saw it this morning at 8am.  It's now 4:30pm here.  Note I've been working on the other thing, the interface modports, and other interruptions.  I'll be posting again to that other thread after I have a firm result.  Your advice for that seems right on the mark.

 

For this thread, for MIG input pins...  Ah ha!  So I have 

        mig_7series_0 u_mig_7series_0 (
            // System Clock Ports
            .sys_clk_i /* No Buffer */     (clk),
            .sys_rst                       (rst),
            // Memory interface ports
            ...
            ...
            ...

Where "clk" eventually comes from my own SYS_CLK. 

    IBUFGDS #(
        .DIFF_TERM(DIFF_TERM)
    ) 
    CL_iob (
        .I(SYSCLK_P),
        .IB(SYSCLK_N),
        .O(SYS_CLK)
    );

Note that DIFF_TERM="FALSE".

 

It's actually indirect, being passed up and down through three different modules, but I think all that matters is that **I** am providing the IBUFGDS and therefore MIG got configured with "no buffer".     YOU ARE SOOOOOOO GOOOOOOD!!!!!!!

 

You say I need to write a create_clock constraint.  What, for my SYS_CLK?  I thought the tool would see through the IBUFGDS...

 

I will add a SYS_CLK constraint now and start a new build.  In the mean time, the report_clocks output is attached.

 

EDIT: Well, after adding a create_clock constraint for SYS_CLK, nothing changed.  The "no_clock" signals are still in the 20,000's, and the one I picked out is still there.  Attached is a subsequent report_clocks output.

SUBSEQUENT EDIT: critical warning "create_clock: No valid object(s) found for '-objects [get_ports SYS_CLK]'.  So obviously I don't know how to use "create_clock".  I will try again.   Hmmm...  SYS_CLK goes into MIG and my interface structure element MIGXface.ui_clk comes out.  Do I need to do a "create_clock" for MIGXface.ui_clk instead?

SUBSEQUENT EDIT: Google finds me AR#63640.  Currently trying to understand HOW to implement that solution, very similar to your suggestion...

0 Kudos
Highlighted
Xilinx Employee
Xilinx Employee
3,495 Views
Registered: ‎09-20-2012

Re: How to deal with MIG timing constraints?

Hi @helmutforren

 

You need to specify the create_clock constraint on SYSCLK_P port. 

Thanks,
Deepika.
--------------------------------------------------------------------------------------------
Google your question before posting. If someone's post answers your question, mark the post as answer with "Accept as solution". If you see a particularly good and informative post, consider giving it Kudos (the star on the left)
0 Kudos
Highlighted
Scholar
Scholar
3,471 Views
Registered: ‎06-23-2014

Re: How to deal with MIG timing constraints?

But the following line is already in the constraints file NEAR THE BOTTOM:

 

create_clock -period 5.000 -name SYSCLK -waveform {0.000 2.500} [get_ports SYSCLK_P]

 

 

I've played around since I did the report_clocks, so the constraints file has had additional things added.  At this very moment, the clock related constraints read like this:

 

create_clock -period 5.000 -name SYSCLK -waveform {0.000 2.500} [get_ports SYSCLK_P]
#create_clock -period 5.000 -name SYS_CLK -waveform {0.000 2.500} [get_ports SYS_CLK]
create_clock -period 5 [get_ports clk_ref_p]
#create_clock -period 5.000 -name MIG_CLK -waveform {0.000 2.500} [get_ports MIG_Xface.ui_clk]
create_clock -period 1.961 -name ROIC_bitclk -waveform {0.000 0.981} [get_ports FMC_HPC_LA07_P]

 

Right now, with exactly those settings, I'll run the report_clocks again.  I HAVE ATTACHED IT.

 

 

0 Kudos
Highlighted
Xilinx Employee
Xilinx Employee
3,462 Views
Registered: ‎09-20-2012

Re: How to deal with MIG timing constraints?

Hi @helmutforren

 

The constraints are correct now. In the report_clocks output, the below clock is ui_clk. Do you still see it in "no clocks" section?

 

clk_pll_i                                                                                                                                                  5.000       {0.000 2.500}   P,G,A       {DDR3_Memory_Wrapper/u_mig_7series_0/u_mig_7series_0_mig/u_ddr3_infrastructure/gen_mmcm.mmcm_i/CLKFBOUT}

 

Thanks,
Deepika.
--------------------------------------------------------------------------------------------
Google your question before posting. If someone's post answers your question, mark the post as answer with "Accept as solution". If you see a particularly good and informative post, consider giving it Kudos (the star on the left)
0 Kudos
Highlighted
Scholar
Scholar
3,451 Views
Registered: ‎06-23-2014

Re: How to deal with MIG timing constraints?

@vemulad Deepika,

 

Thanks VERY Much for continuing to work with me on this.

 

It is *not* that I am seeing ui_clk *directly* in the "no clock" section.  My problem is that I have 27,420 entries in the "no_clocks" section, and when I look into the first ones they *appear* to be *related* to ui_clk.  I will take the very first one and explain...

 

First, here is the very beginning of the "no clock" section:

no_clock 20170810 (annotated).jpg

Notice that the first line has "Storage_Manager/MEM_rd_fifo" in the middle, pointed to by the red arrow.   Then to make later analysis in this post easier, I scroll down to find:

no_clock 20170810B (annotated).jpg

Notice that "MPMC/output_test" appears, pointed to by the red arrow.  (With 27420 entries, the scroll bar barely moved.)

 

So I go find both "MEM_rd_fifo" in Storage_Manager() and "output_test" in MPMC().  

 

"MEM_rd_fifo" is both a type of fifo as well as the name of an invocation of that type of fifo.  The source is below:

    
    //=================================================================================================================
    // MEM_rd_fifo section
    //=================================================================================================================
    
    i_MEM_rd_fifo_din MEM_rd_fifo_fromspmc_din();    // Instance the interface
    i_MEM_rd_fifo_dout MEM_rd_fifo_fromspmc_dout();    // Instance the interface
    
    MEM_rd_fifo MEM_rd_fifo (
        .rst(rst),
        .wr_clk(MIG_Xface.ui_clk),
        .rd_clk(clk),
        .din(MEM_rd_fifo_fromspmc_din.din.data),
        .wr_en(MEM_rd_fifo_fromspmc_din.din.wr_en),
        .rd_en(MEM_rd_fifo_fromspmc_dout.dout.rd_en),
        .dout(MEM_rd_fifo_fromspmc_dout.dout.data),
        .full(MEM_rd_fifo_fromspmc_din.din.full),
        .prog_full(MEM_rd_fifo_fromspmc_din.din.prog_full),
        .empty(MEM_rd_fifo_fromspmc_dout.dout.empty)
    );
    
    i_MEM_rd_fifo_din MEM_rd_fifo_TEST_din();    // Instance the interface
    i_MEM_rd_fifo_dout MEM_rd_fifo_TEST_dout();    // Instance the interface
    
    MEM_rd_fifo MEM_rd_fifo_TEST (
        .rst(rst),
        .wr_clk(clk),
        .rd_clk(clk),
        .din(MEM_rd_fifo_TEST_din.din.data),
        .wr_en(MEM_rd_fifo_TEST_din.din.wr_en),
        .rd_en(MEM_rd_fifo_TEST_dout.dout.rd_en),
        .dout(MEM_rd_fifo_TEST_dout.dout.data),
        .full(MEM_rd_fifo_TEST_din.din.full),
        .prog_full(MEM_rd_fifo_TEST_din.din.prog_full),
        .empty(MEM_rd_fifo_TEST_dout.dout.empty)
    );

Then, for output_main_flow in MPMC() the *germane* source is, I believe, below:

    //=================================================================================================================
    // MPMC (Multi-Port Memory Controller) section
    //=================================================================================================================
    
    MPMC #(
           .INCLUDE_ILA(INCLUDE_ILA)
    ) MPMC (
        .clk(clk),
        .rst(rst),
        .input_1(MEM_wr_fifo_TEST_dout),
        .input_2(MEM_write_segment_fifo_dout),
        .input_3(MEM_wr_fifo_3_dout),
        .to_spmc(MEM_wr_fifo_tospmc_din),
        
        .from_spmc(MEM_rd_fifo_fromspmc_dout),   // i_MEM_rd_fifo_dout
        .output_test(MEM_rd_fifo_TEST_din), // i_MEM_rd_fifo_din
        .output_main_flow(MEM_read_segment_fifo_din), // i_MEM_rd_fifo_din
        
        // Testing Only
        .DDR3_Memory_Do_Test(DDR3_Memory_Do_Test),
        .DDR3_Memory_Testing(DDR3_Memory_Testing),
        .DDR3_Memory_Error(DDR3_Memory_Error),
        .CL_FVAL(CL_FVAL),
        .CL_LVAL(CL_LVAL),
        .CL_DVAL(CL_DVAL)
    );

Note that "MEM_rd_fifo_TEST_din" of the first code block above is used in the MPMC invocation in the second code block above.  It is connected to "output_test", which is what I'm looking for.

 

So now I *believe* I have established that the no_clock section is specifically referring to this FIFO that is going by two different names.  It is invocated as "MEM_rd_fifo" and "MEM_rd_fifo_TEST" in the first code block, and it is the "MEM_rd_fifo_TEST "invocation that we're interested in right now.  It is also referred to as "output_test" by virtue of being connected as shown in the second code block.

 

So *why* do these appear in the no_clock section of the timing report?  They seem to all be clocked by "clk".  (WARNING: at this point I realize I am tracking down something for "clk" and not "ui_clk".  I will continue tracking down this "clk" since it also needs fixing.)  (NOTE: I realize that the FIFO is defined with dual clocks and I'm passing the same clock twice.  That's not possibly the cause, is it?)  Anyway, this "clk" comes from "SYS_CLK" in the caller (My_Project), which contains 

    IBUFGDS #(
        .DIFF_TERM(DIFF_TERM)
    ) 
    CL_iob (
        .I(SYSCLK_P),
        .IB(SYSCLK_N),
        .O(SYS_CLK)
    );

where DIFF_TERM="False".  There you see SYSCLK_P, which comes from the same name in the top module and the constraints file.  SYSCLK_P has a create_clock line.  So why in the world did I get the no_clock entries I've chased down?

 

-------------------------------------------------------

 

Now, going back to try and connect with "ui_clk".  If I collapse the first "Register/Latch pins" line, the second such line also refers to a MEM_rd_fifo.  The detail below this one has "SPMC/Output_FIFO".

no_clock 20170810C (annotated).jpg

That invocation is actually in the source code between my previously posted two code blocks.  Here it is:

    //=================================================================================================================
    // SPMC (Single Port Memory Controller) section
    //=================================================================================================================
    
    SPMC #(
           .INCLUDE_ILA(INCLUDE_ILA)
    ) SPMC (
        .MIG_Xface(MIG_Xface),
        .Input_FIFO(MEM_wr_fifo_tospmc_dout),
        .Output_FIFO(MEM_rd_fifo_fromspmc_din),
        
        // Testing Only
        .DDR3_Memory_Do_Test(DDR3_Memory_Do_Test),
        .DDR3_Memory_Testing(DDR3_Memory_Testing),
        .DDR3_Memory_Error(DDR3_Memory_Error),
        .CL_FVAL(CL_FVAL),
        .CL_LVAL(CL_LVAL),
        .CL_DVAL(CL_DVAL)
    );

Notice that this is connecting to the first FIFO invocation in the very first code block way above in this post.  That FIFO is dual clock and receives both "clk" (already described) and "MIG_Xface.ui_clk".  Here is the "ui_clk" I am seeking.  Well, perhaps ui_clk isn't the problem at all.  A problem with clk could cause both FIFOs to have clock trouble.  So I guess focus on the clk problem chased above the ------------------------------------- line.

0 Kudos