Yuan
Yuan

Reputation: 23

Vivado bistreaming message: Rule violation (LUTLP-1) Combinatorial Loop

I got a problem when bistreaming. The project is to create a clock with a 1:2 duty cycle. There are no problems during Synthesis and Implementation. I tried a few ways to solve it. But they didn't work well.

module clock_div(clk, clk_out);
input clk;
output reg clk_out;

integer count1, count2;
reg clk_div;

always@(posedge clk)
begin
    count1 <= count1 + 1;
    if(count1 == 16666667)
    begin
        count1 <= 0;
        clk_div <= ~clk_div;
    end
end

always@(clk_div)
begin
    count2 <= count2 + 1;
    if(count2 == 1)
    begin
        clk_out <= ~clk_out;
    end
    else if(count2 == 3)
    begin
        count2 <= 0;
        clk_out <= ~clk_out;
    end
end
endmodule

The message that Vivado gave is as follows:

    [DRC 23-20] Rule violation (LUTLP-1) Combinatorial Loop - 231 LUT 
    cells form a combinatorial loop. 
    This can create a race condition. 
    Timing analysis may not be accurate. 
    The preferred resolution is to modify the design to remove 
    combinatorial logic loops. 
    To allow bitstream creation for designs with combinatorial logic loops 
    (not recommended), use this command: set_property SEVERITY {Warning} 
    [get_drc_checks LUTLP-1]. 
    NOTE: When using the Vivado Runs infrastructure (e.g. launch_runs Tcl 
    command), add this command to a .tcl file and add that file as a pre- 
    hook for write_bitstream step for the implementation run. 
    clk_out_reg_i_3, clk_out_reg_i_4, clk_out_reg_i_5, clk_out_reg_i_7, 
    clk_out_reg_i_8, clk_out_reg_i_10, clk_out_reg_i_11, clk_out_reg_i_12, 
    clk_out_reg_i_13, clk_out_reg_i_14, clk_out_reg_i_15, 
    clk_out_reg_i_16, clk_out_reg_i_17, clk_out_reg_i_20, clk_out_reg_i_21 
    (the first 15 of 231 listed).

I would appreciate it if someone can help me.

Upvotes: 1

Views: 575

Answers (1)

Oldfart
Oldfart

Reputation: 6269

This is wrong:

always@(clk_div) // <<== WRONG!!!! 
begin
    count2 <= count2 + 1;
    if(count2 == 1)
    begin
        clk_out <= ~clk_out;
    end
    else if(count2 == 3)
    begin
        count2 <= 0;
        clk_out <= ~clk_out;
    end
end

You are using an incomplete sensitivity list. This gives a mismatch between simulation and synthesis. For all code that you want to synthesize use a complete sensitivity list or even easier use :always@( * )

If you use that in the section above you will find that your simulation no longer works. It will get in an infinite loop. Which is exactly the combinatorial loop the tool is complaining about.

To solve this you should put all code into the top section:

always@(posedge clk)
begin
    count1 <= count1 + 1;
    if(count1 == 16666667)
    begin
        count1 <= 0;
        // Here you should make your 2:1 clock(s!) 
        // I leave that as an exercise to you
    end
end

Problem:
As you divide by 16666667 you will not get a 2:1 clock but more a 33333334:1 clock. Unless you wanted a 2:1 clock between clk_div and clk_out, but clk_div is not coming out. In that case make both clk_div and clk_out in the above marked section

Upvotes: 1

Related Questions