Forum Discussion
Altera_Forum
Honored Contributor
14 years agoMinimum pulse width violation
Hey guys,
I'm using the timequest analyzer. I first setup the clock using the wizard. 120Mhz. I'm using Cyclone II, C6. After performing compilation and checking the timequest results, I found that I have minimum pulse width violations. They occur with the latches on the altsyncram memory. Is it that my clock frequency is too high? It's only 120 Mhz. Also, there is both a slow and fast model. What is the difference.7 Replies
- Altera_Forum
Honored Contributor
Not at all i dont think 120 Mhz can cause any problem...i have worked with 225 Mhz and i never got dis violation.
I dont have much idea of the cause but i dont think inferring a latch is a good idea and as you mentioned latch with a clock then it is shud be removed as far as i know. Slow and fast models are corners of a model. The results of a slow model helps you determine hold violation. You can ignore setup violations if they are of very small -ve slack but if the -ve slack for setup violations are big then they shud be considered. But no hold violation is acceptable in slow corner. In fast corner its just the reverse. The results of a fast model helps you determine setup violation. You can ignore hold violations if they are of very small -ve slack but if the -ve slack for hold violations are big then they shud be considered. But no setup violation is acceptable in fast corner. One thing to be noted is that even if your fast as slow corners show good results with reference to my above statements you have to take in account that what the +ve slack is in these corners. If it is very small say 0.4 ns then you need to work on optimizing your design as your design wont be exposed to fast or slow corner speed grades when in application. It will be working in some industrial speed grade which is the correct balance of the two. you can say suppose you are having a setup violation in fast corner then you design can never meet any setup requirements with the current optimization you have applied or if you are having hold violations in slow corner then your design can never meet hold timings with current settings. I hope you understand what i mean to say. Fast and slow corners are the limits to check violations in the best cases and if the respective setup or hold violation fails then you have to turn up with some good quartus settings for your designs to meet these timings or in worst case change the rtl code. - Altera_Forum
Honored Contributor
Thanks for the help ashishkaps. If the clock frequency is acceptable, then what could be causing this problem?
I can't avoid the latches. The altsyncram memory is synchronous. Every input to the module is latched with the clock. It seems that the error is occuring with that component. - Altera_Forum
Honored Contributor
Here is the part that is giving the violation. It is an altsyncram memory:
circular_buffer:xncb|input_buffer:ib|altsyncram:altsyncram_component|altsyncram_n9r1:auto_generated|q_b[0] - Altera_Forum
Honored Contributor
--- Quote Start --- Thanks for the help ashishkaps. If the clock frequency is acceptable, then what could be causing this problem? I can't avoid the latches. The altsyncram memory is synchronous. Every input to the module is latched with the clock. It seems that the error is occuring with that component. --- Quote End --- There may be a terminology problem here, a 'latch' is something that looks like this
A flip flop looks like thisLATCH_PROC : process(clk, d) begin if clk = '1' then -- Note: Simply comparing clk to '1', not an edge q <= d; end if; end process;
Latches are almost always avoidable, and in an FPGA they must be avoided to get a working design. Edge triggered flip flops are required. Odds are that the syncram is not the source of the problem, it is just the signal that is reporting the error. - How are your inputs to the memory generated? (i.e. Latch_Proc or Flop_Proc) - Is the clock free running from either a clock input pin or the output of a PLL? Or is it generated internally in the design? Kevin JenningsFLOP_PROC : process(clk, d) begin if clk = '1' and clk'event then -- Note: Looking for a rising edge on clk q <= d; end if; end process; - Altera_Forum
Honored Contributor
--- Quote Start --- Here is the part that is giving the violation. It is an altsyncram memory: circular_buffer:xncb|input_buffer:ib|altsyncram:altsyncram_component|altsyncram_n9r1:auto_generated|q_b[0] --- Quote End --- Post the full error that you are getting as well. - Altera_Forum
Honored Contributor
Thanks for your help JK,
Here is the full error below:
Some of the signals that drive the input of memory are inferred as latches by the compiler. Here is the code that drives the memory shown below:-0.127 2.000 2.127 High Pulse Width fclk Rise circular_buffer:xncb|input_buffer:ib|altsyncram:altsyncram_component|altsyncram_g9r1:auto_generated|q_b
It is the output part of a state machine that operates a circular buffer. For some reason, I recieved these warnings that stated that some of the signals input into the memory were inferred as latches:always @(pstate) begin case(pstate) s0: begin //state 0 resets all control signals and aligns the read pointer of the acc_reset<=0; //circular input buffer to the latest input sample. If the wrptr for the rdptrw<=0; //input buffer isn't zero, then decrement the wrptr by one and set that calc<=0; //equal to the read pointer. This is because everytime a new value is written wn_w<=0; //to the input buffer via xn_w, then the write pointer automatically increments if(wrptr !=0) //to the next location. Thus, one minus the current wrptr gives the location of rdptr<=wrptr-1; // the most recent input sample. else rdptr<=(L-1); end s1: begin counter<=0; //reset the counter to zero since this is the first product of the convolution. end //also delay by one cycle to accomodate memory latency s2: begin rden<=1; //assert read enable to read first coefficient from memory. Also clear the accumulator. acc_reset<=0; end s3: begin rden<=0; //now that the old coefficient is output, assert calc to calculate a new coefficient calc<=1; wn_w<=0; end s4: begin rden<=0; //increment the counter for the next multiplication calc<=0; wn_w<=0; counter<=counter+11'd1; end s5: begin wn_w<=1; //store the new coefficient end s6: begin wn_w<=0; //output input value to begin multiplication rden<=1; end s7: begin rden<=0; //perform multiplication and latch it in the MAC mac_latch<=1; if(rdptr==0) //if the current input sample is coming from the bottom begin //of the input buffer, then wrap around to the top in a circular rdptr<=(L-1); //fashion. Otherwise, just decrement the pointer. end else begin rdptr<=rdptr-1; end rden<=0; if(!(counter==(L))) //if there are still more convolution multiplications left begin //increment the read pointer to the coefficient buffer if(rdptrw==(L-1)) rdptrw<=0; else rdptrw<=rdptrw+1; end end s8: begin mac_latch<=0; //calculate the next coefficient rden<=1; end s9: begin calc<=1; wn_w<=0; rden<=0; end s10: begin calc<=0; end s11: begin //if there are no more convolution products to be calculated, firdone<=1; //then convolution is finished. Assert firdone to indicate this condition. acc_reset<=1; //also reset the accumulator for the next cycle. end s12: begin //wn_w<=0; firdone<=0; //deassert firdone end default: begin rden<=0; calc<=0; firdone<=0; acc_reset<=0; wn_w<=0; rdptr<=0; rdptrw<=0; counter<=0; end endcase end
Any help would be greatly appreciated.Warning (10240): Verilog HDL Always Construct warning at circular_buffer.v(196): inferring latch(es) for variable "rden", which holds its previous value in one or more paths through the always construct Warning (10240): Verilog HDL Always Construct warning at circular_buffer.v(196): inferring latch(es) for variable "calc", which holds its previous value in one or more paths through the always construct Warning (10240): Verilog HDL Always Construct warning at circular_buffer.v(196): inferring latch(es) for variable "firdone", which holds its previous value in one or more paths through the always construct Warning (10240): Verilog HDL Always Construct warning at circular_buffer.v(196): inferring latch(es) for variable "acc_reset", which holds its previous value in one or more paths through the always construct Warning (10240): Verilog HDL Always Construct warning at circular_buffer.v(196): inferring latch(es) for variable "wn_w", which holds its previous value in one or more paths through the always construct Warning (10240): Verilog HDL Always Construct warning at circular_buffer.v(196): inferring latch(es) for variable "rdptr", which holds its previous value in one or more paths through the always construct Warning (10240): Verilog HDL Always Construct warning at circular_buffer.v(196): inferring latch(es) for variable "rdptrw", which holds its previous value in one or more paths through the always construct Warning (10240): Verilog HDL Always Construct warning at circular_buffer.v(196): inferring latch(es) for variable "counter", which holds its previous value in one or more paths through the always construct Warning (10240): Verilog HDL Always Construct warning at circular_buffer.v(196): inferring latch(es) for variable "mac_latch", which holds its previous value in one or more paths through the always construct - Altera_Forum
Honored Contributor
Look wat all signals you have assigned in default you have to assign some value in each and every case otherwise it will definately give a latch.
Example always @ (x) begin case (x) begin s1: begin a=1'b1; // 2 signals in s1 b=1'b1; end s2: begin a=1'b0; // 1 signal in s2 end default: a=1'b0; b=1'b0; // 3signals in default c=1'b0; My reasoning is that each and every case should have eaqual signals which have been used or it will give a latch if even a single signal is unassigned in a case which has been assigned in other case.