Forum Discussion

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

"limit due to minimum pulse width violation" how to find out what is causing this.

I've got the following message/warning in the .sta report:

+------------+-----------------+------------+--------------------------------------------+
; Fmax       ; Restricted Fmax ; Clock Name ; Note                                       ;
+------------+-----------------+------------+--------------------------------------------+
; 832.64 MHz ; 645.16 MHz      ; sys_clk    ; limit due to minimum pulse width violation ;
+------------+-----------------+------------+--------------------------------------------+

How can I track what is causing this?

The Verilog file code is below, it is Migen generated.

What does 'Restricted Fmax' really mean and how does it compare to Fmax?

A more general question, above is a result from running the synthesis as

this module (below) as top level module, how applicable is this result (Fmax)

in the wider context i.e. if I instantiate, say 100, of these modules, can I

expect them all to perform more or less equally and up to this Fmax?

/* Machine-generated using Migen */
module correlator(
    input e,
    input  a,
    input  b,
    input  o,
    output reg oe,
    input sys_clk,
    input sys_rst
);
reg signed  counter = 8'sd255;
reg  product = 20'd0;
reg  accum_product = 26'd0;
reg  accum_in_a = 16'd0;
reg  accum_in_b = 16'd0;
reg  product_accum_in_a_and_b = 32'd0;
reg  final_result = 32'd0;
always @(posedge sys_clk) begin
    if (($signed({1'd0, e}) & (counter < $signed({1'd0, 1'd0})))) begin
        counter <= 7'd65;
    end else begin
        if ((counter >= $signed({1'd0, 1'd0}))) begin
            counter <= (counter - $signed({1'd0, 1'd1}));
        end
    end
    if (($signed({1'd0, e}) | (counter >= $signed({1'd0, 1'd0})))) begin
        product <= (a * b);
        accum_product <= (accum_product + product);
        accum_in_a <= (accum_in_a + a);
        accum_in_b <= (accum_in_b + b);
        product_accum_in_a_and_b <= (accum_in_a * accum_in_b);
    end
    if ((counter == $signed({1'd0, 1'd0}))) begin
        final_result <= ((accum_product * 7'd64) - product_accum_in_a_and_b);
        oe <= 1'd1;
    end
    if (oe) begin
        oe <= 1'd0;
        accum_in_a <= 1'd0;
        accum_in_b <= 1'd0;
        accum_product <= 1'd0;
        product <= 1'd0;
        product_accum_in_a_and_b <= 1'd0;
        counter <= 1'sd1;
        final_result <= 1'd0;
    end
    if (sys_rst) begin
        oe <= 1'd0;
        counter <= 8'sd255;
        product <= 20'd0;
        accum_product <= 26'd0;
        accum_in_a <= 16'd0;
        accum_in_b <= 16'd0;
        product_accum_in_a_and_b <= 32'd0;
        final_result <= 32'd0;
    end
end
endmodule

2 Replies

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

    See support answer: https://www.altera.com/support/support-resources/knowledge-base/solutions/rd09302013_60.html (Your design is limited for a different reason to the support answer.)

    Will multiple instances all run at this speed? This very much depends on the resources one instance needs and how efficiently Quartus can fit them. Fitting many in will start to compromise the resources available, particularly routing, and will impact the speed at which it will all run.

    Cheers,

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

    Ok, thanks, understood.

    For the record my example above was faulty: because no output from the module was specified ('input [25:0]' o should have been 'output [25:0] o') the multiplication inside the module was optimised away along and thus the (I guess) some 'random' logic was left and this generated the minimum pulse width violation which went away when I fixed my code.

    But I understand that regardless the point about timing of multiple instances is still valid.