Programmable Devices
CPLDs, FPGAs, SoC FPGAs, Configuration, and Transceivers
Need Forum Guidance? Click here

Search our FPGA Knowledge Articles here.
18982 Discussions

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

Honored Contributor II

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
0 Kudos
2 Replies
Honored Contributor II

See support answer: (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. 



Honored Contributor II

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.