- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.Link Copied
7 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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]- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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
LATCH_PROC : process(clk, d)
begin
if clk = '1' then -- Note: Simply comparing clk to '1', not an edge
q <= d;
end if;
end process;
A flip flop looks like this
FLOP_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;
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 Jennings
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks for your help JK,
Here is the full error 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
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:
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
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:
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
Any help would be greatly appreciated.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page