Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

tri state buffer and Holding violation

Status
Not open for further replies.

Mina Magdy

Member level 3
Member level 3
Joined
Jun 19, 2012
Messages
67
Helped
6
Reputation
12
Reaction score
5
Trophy points
1,288
Location
Cairo, Egypt
Activity points
1,742
Hi
when i synthesis my project i found a 27000 tristate buffer
at the first i think i was from an if condition that is used only one time in the hole process as the synthesis report pointed on it but after i remove that condition it still no change.
so may this due to any holding violation that bring a buffer? and if it is , how can i overcome that problem?and was holding violation bring tristate buffers or normal buffers?

another question about holding violation
when there is a holding viloation why Tool didn't decrease the holding time other than but a buffer?
 
Last edited:

Your description is incomplete and a bit hard to read and follow clearly (e.g. is it a tri-state buffer internal to the design, or is it an I/O-pad driver?).
But a few comments come to mind ...

I would not jump to the conclusion that synthesis is inserting a tri-state buffer due to trying to fix hold violations.
Did the hold-violations go away with the tri-state buffers being there?
(Some synthesis tools will not even try to fix hold violations unless you explicitly enable certain settings-options in the tool, but you also did not specify what synthesis tool you are using?)
You will need to examine closely a detailed hold-violation timing report (the full-path style of report) to understand why you have hold violations.

Are you somehow inferring a tri-state buffer in the RTL code, perhaps by assigning a "Z" under certain conditions?

What is "a 27000 tristate buffer"? A buffer type name? Or did you mean "27000 tristate buffers" (i.e. 27K instances of a tri-state buffer being inserted)?

Is the enable pin on these tri-state buffers being held to a constant level 0 or 1, or are they being driven by another signal?
(examine the netlist or else a schematic view to see this)
Looking at what signal is driving the enable on these tri-state buffers might give you a clue as to why the synthesis tool is putting them in there.
 
thanks for your replay
Did the hold-violations go away with the tri-state buffers being there?
i dont know but this is the report
HTML:
Data Sheet report: 
 ----------------- 
 All values displayed in nanoseconds (ns) 
  
 Setup/Hold to clock clk 
 ------------+------------+------------+------------+------------+------------------+--------+ 
             |Max Setup to|  Process   |Max Hold to |  Process   |                  | Clock  | 
 Source      | clk (edge) |   Corner   | clk (edge) |   Corner   |Internal Clock(s) | Phase  | 
 ------------+------------+------------+------------+------------+------------------+--------+ 
 data_in     |   -0.661(R)|      FAST  |    3.146(R)|      SLOW  |clk_BUFGP         |   0.000| 
 reset       |    0.786(R)|      FAST  |    3.276(R)|      SLOW  |clk_BUFGP         |   0.000| 
 ------------+------------+------------+------------+------------+------------------+--------+ 
  
 Clock clk to Pad 
 ------------+-----------------+------------+-----------------+------------+------------------+--------+ 
             |Max (slowest) clk|  Process   |Min (fastest) clk|  Process   |                  | Clock  | 
 Destination |  (edge) to PAD  |   Corner   |  (edge) to PAD  |   Corner   |Internal Clock(s) | Phase  | 
 ------------+-----------------+------------+-----------------+------------+------------------+--------+ 
 data_out    |         8.675(R)|      SLOW  |         3.929(R)|      FAST  |clk_BUFGP         |   0.000| 
 ------------+-----------------+------------+-----------------+------------+------------------+--------+ 
  
 Clock to Setup on destination clock clk 
 ---------------+---------+---------+---------+---------+ 
                | Src:Rise| Src:Fall| Src:Rise| Src:Fall| 
 Source Clock   |Dest:Rise|Dest:Rise|Dest:Fall|Dest:Fall| 
 ---------------+---------+---------+---------+---------+ 
 clk            |    3.551|         |         |         | 
 ---------------+---------+---------+---------+---------+

synthesis tool i use is Xilinx 14.2.



Are you somehow inferring a tri-state buffer in the RTL code, perhaps by assigning a "Z" under certain conditions?
No

if you would like to see a part of code
Code:
	 always@(posedge clk)
	 begin
		if(reset)
		begin		
			bit_counter=359;
			row_counter=-1;
			data_counter=-1;
		
		 table_1_2[0][0]=14'd20;
		 table_1_2[0][1]=14'd712;
		 table_1_2[0][2]=14'd2386;
		 table_1_2[0][3]=14'd6354;
		 table_1_2[0][4]=14'd4061;
		 table_1_2[0][5]=14'd1062;
		 table_1_2[0][6]=14'd5045;
		 table_1_2[0][7]=14'd5158;
		 table_1_2[1][0]=14'd21;
		 table_1_2[1][1]=14'd2543;
		 table_1_2[1][2]=14'd5748;
		 table_1_2[1][3]=14'd4822;
		 table_1_2[1][4]=14'd2348;
		 table_1_2[1][5]=14'd3089;
		 table_1_2[1][6]=14'd6328;
		 table_1_2[1][7]=14'd5876;	
		 table_1_2[2][0]=14'd22;
		 table_1_2[2][1]=14'd926;
		 table_1_2[2][2]=14'd5701;
		 table_1_2[2][3]=14'd269;
		 table_1_2[2][4]=14'd3693;
		 table_1_2[2][5]=14'd2438;
		 table_1_2[2][6]=14'd3190;
		 table_1_2[2][7]=14'd3507;
		 table_1_2[3][0]=14'd23;
		 table_1_2[3][1]=14'd2802;
		 table_1_2[3][2]=14'd4520;
		 table_1_2[3][3]=14'd3577;
		 table_1_2[3][4]=14'd5324;
		 table_1_2[3][5]=14'd1091;
		 table_1_2[3][6]=14'd4667;
		 table_1_2[3][7]=14'd4449;
		 table_1_2[4][0]=14'd24;
		 table_1_2[4][1]=14'd5140;
		 table_1_2[4][2]=14'd2003;
		 table_1_2[4][3]=14'd1263;
		 table_1_2[4][4]=14'd4742;
		 table_1_2[4][5]=14'd6497;
		 table_1_2[4][6]=14'd1185;
		 table_1_2[4][7]=14'd6202;
		 table_1_2[5][0]=14'd0;
		 table_1_2[5][1]=14'd4046;
		 table_1_2[5][2]=14'd6934;
		 table_1_2[5][3]=14'd0;
		 table_1_2[5][4]=14'd0;
		 table_1_2[5][5]=14'd0;
		 table_1_2[5][6]=14'd0;
		 table_1_2[5][7]=14'd0;
		 table_1_2[6][0]=14'd1;
		 table_1_2[6][1]=14'd2855;
		 table_1_2[6][2]=14'd66;
		 table_1_2[6][3]=14'd0;
		 table_1_2[6][4]=14'd0;
		 table_1_2[6][5]=14'd0;
		 table_1_2[6][6]=14'd0;
		 table_1_2[6][7]=14'd0;
		 table_1_2[7][0]=14'd2;
		 table_1_2[7][1]=14'd6694;
		 table_1_2[7][2]=14'd212;
		 table_1_2[7][3]=14'd0;
		 table_1_2[7][4]=14'd0;
		 table_1_2[7][5]=14'd0;
		 table_1_2[7][6]=14'd0;
		 table_1_2[7][7]=14'd0;
		 table_1_2[8][0]=14'd3;
		 table_1_2[8][1]=14'd3439;
		 table_1_2[8][2]=14'd1158;
		 table_1_2[8][3]=14'd0;
		 table_1_2[8][4]=14'd0;
		 table_1_2[8][5]=14'd0;
		 table_1_2[8][6]=14'd0;
		 table_1_2[8][7]=14'd0;
		 table_1_2[9][0]=14'd4;
		 table_1_2[9][1]=14'd3850;
		 table_1_2[9][2]=14'd4422;
		 table_1_2[9][3]=14'd0;
		 table_1_2[9][4]=14'd0;
		 table_1_2[9][5]=14'd0;
		 table_1_2[9][6]=14'd0;
		 table_1_2[9][7]=14'd0;
		 table_1_2[10][0]=14'd5;
		 table_1_2[10][1]=14'd5924;
		 table_1_2[10][2]=14'd290;
		 table_1_2[10][3]=14'd0;
		 table_1_2[10][4]=14'd0;
		 table_1_2[10][5]=14'd0;
		 table_1_2[10][6]=14'd0;
		 table_1_2[10][7]=14'd0;
		 table_1_2[11][0]=14'd6;
		 table_1_2[11][1]=14'd1467;
		 table_1_2[11][2]=14'd4049;
		 table_1_2[11][3]=14'd0;
		 table_1_2[11][4]=14'd0;
		 table_1_2[11][5]=14'd0;
		 table_1_2[11][6]=14'd0;
		 table_1_2[11][7]=14'd0;
		 table_1_2[12][0]=14'd7;
		 table_1_2[12][1]=14'd7820;
		 table_1_2[12][2]=14'd2242;
		 table_1_2[12][3]=14'd0;
		 table_1_2[12][4]=14'd0;
		 table_1_2[12][5]=14'd0;
		 table_1_2[12][6]=14'd0;
		 table_1_2[12][7]=14'd0;
		 table_1_2[13][0]=14'd8;
		 table_1_2[13][1]=14'd4606;
		 table_1_2[13][2]=14'd3080;
		 table_1_2[13][3]=14'd0;
		 table_1_2[13][4]=14'd0;
		 table_1_2[13][5]=14'd0;
		 table_1_2[13][6]=14'd0;
		 table_1_2[13][7]=14'd0;
		 table_1_2[14][0]=14'd9;
		 table_1_2[14][1]=14'd4633;
		 table_1_2[14][2]=14'd7877;
		 table_1_2[14][3]=14'd0;
		 table_1_2[14][4]=14'd0;
		 table_1_2[14][5]=14'd0;
		 table_1_2[14][6]=14'd0;
		 table_1_2[14][7]=14'd0;
		 table_1_2[15][0]=14'd10;
		 table_1_2[15][1]=14'd3884;
		 table_1_2[15][2]=14'd6868;
		 table_1_2[15][3]=14'd0;
		 table_1_2[15][4]=14'd0;
		 table_1_2[15][5]=14'd0;
		 table_1_2[15][6]=14'd0;
		 table_1_2[15][7]=14'd0;
		 table_1_2[16][0]=14'd11;
		 table_1_2[16][1]=14'd8935;
		 table_1_2[16][2]=14'd4996;
		 table_1_2[16][3]=14'd0;
		 table_1_2[16][4]=14'd0;
		 table_1_2[16][5]=14'd0;
		 table_1_2[16][6]=14'd0;
		 table_1_2[16][7]=14'd0;		
		 table_1_2[17][0]=14'd12;
		 table_1_2[17][1]=14'd3028;
		 table_1_2[17][2]=14'd764;
		 table_1_2[17][3]=14'd0;
		 table_1_2[17][4]=14'd0;
		 table_1_2[17][5]=14'd0;
		 table_1_2[17][6]=14'd0;
		 table_1_2[17][7]=14'd0;			
		 table_1_2[18][0]=14'd13;
		 table_1_2[18][1]=14'd5988;
		 table_1_2[18][2]=14'd1057;
		 table_1_2[18][3]=14'd0;
		 table_1_2[18][4]=14'd0;
		 table_1_2[18][5]=14'd0;
		 table_1_2[18][6]=14'd0;
		 table_1_2[18][7]=14'd0;			
		 table_1_2[19][0]=14'd14;
		 table_1_2[19][1]=14'd7411;
		 table_1_2[19][2]=14'd3450;
		 table_1_2[19][3]=14'd0;
		 table_1_2[19][4]=14'd0;
		 table_1_2[19][5]=14'd0;
		 table_1_2[19][6]=14'd0;
		 table_1_2[19][7]=14'd0;
		end
		
		else
		begin
		
				data_counter=data_counter+1;
				
				if(data_counter < 7200)
				begin
				
					if(bit_counter == 359)
					begin
						bit_counter=0;
						row_counter=row_counter+1;
					end
					else
						bit_counter=bit_counter+1;
			 
					if(row_counter < 5)
						no_bit=8;
					else
						no_bit=3;
						
					data=data_in;
					data_out=data;
					[COLOR="#FF0000"]for(j=0;j<8;j=j+1)
					begin
						if((j<no_bit))
						begin
							address=table_1_2[row_counter][j];
							temp= address + bit_counter * qldpc;
								if(temp>=9000)
								begin
									parity_address=temp-9000;
								end
								else
								begin
									parity_address=temp;
								end
							parity[parity_address]=parity[parity_address] ^ data;
						end
					end[/COLOR]					
				end
				else
				begin
					if(data_counter<16200)
					begin
						if((data_counter == 7200))
						begin
							parity_address=0;
							data_out=parity[parity_address];
							parity_temp=data_out;
						end
						else
						begin	 
							parity_address=parity_address+1;
							data_out=parity[parity_address]^parity_temp;
							parity_temp=data_out;	
						end
					end	
				end
		end
	end

- - - Updated - - -

i mean 27k tristate bufffer
 

It appears you were just speculating about a hold-timing cause & effect with the tri-states, but never saw any actual evidence of hold violations?

One detail in your code might be worth further checking ...
You are using a 5-bit (or maybe wider - can't tell) register "row_counter" to index the outer-dimension of your "table_1_2" array.
But, I doubt the synthesis tool is "smart" enough to know that row_counter will never be larger than 19, and perhaps this relates to the issue.
(i.e. it is assuming an undefined behavior when row_counter is larger than 19)
As an experiment, you might want to increase that max outer dimension to 31 (or whatever, per the bit-width of row_counter).
And then use a for-loop (or else explicit assignments) to initialize all table values for outer indices from 20 to 31 to equal 14'd0.

Note the same concern would apply to the inner table dimension, e.g. if "j" was wider than 3-bits (but again I cannot tell since you did not show any declarations).
 
i do what you say and it solve the problem of tristate buffer but it makes a latchs
HTML:
WARNING:Xst:1895 - Due to other FF/Latch trimming, FF/Latch _7_2462> (without init value) has a constant value of 0 in block . This FF/Latch will be trimmed during the optimization process.WARNING:Xst:1895 - Due to other FF/Latch trimming, FF/Latch _7_2461> (without init value) has a constant value of 0 in block . This FF/Latch will be trimmed during the optimization process.
and
HTML:
WARNING:Xst:1895 - Due to other FF/Latch trimming, FF/Latch _7_1220> (without init value) has a constant value of 0 in block . This FF/Latch will be trimmed during the optimization process.WARNING:Xst:1895 - Due to other FF/Latch trimming, FF/Latch _7_1219> (without init value) has a constant value of 0 in block . This FF/Latch will be trimmed during the optimization process.
 

The warning is NOT saying that a latch is being inferred or created (did you click on it or search the Xilinx web-site to see a detailed explanation of it?).
Instead, it is informing you that the register value never changes from the init value, and therefore is not truly needed and can be replaced by a constant logic level.
This logic level could in-turn be optimized during synthesis to be absorbed into the LUT logic equations.
This is actually a good thing, because otherwise you would be consuming flop resources that actually contribute nothing.

Stepping back, there could be a better way to tackle the overall issue and avoid any warnings, but I am not sure what that is, and I'm not sure this is really a problem.
The problem is that you are indexing into an array that has a non-power-of-2 dimension, but you still must use a power-of-2 register to index into it.
Furthermore, XST apparently must create a Z out of the array when it gets indexed outside of its bounds.

It is possible that there are other ways to prevent that Z assumption from happening, maybe via "pragmas" in the RTL or some kind of other option or setting.

I have had a similar situation using Design Compiler for an ASIC flow, but this Z-assumption did not happen.
(Synopsys Design Compiler behavior differs from XST in this situation.)
Instead, I simply got warnings about simulation mismatches due to the index being able to go outside of the array bound, and behavior was undefined if that actually happened.
(i.e. the value from the array was not predictable, but also I did not care)
But I also was not using multi-dimensional arrays, so perhaps that is also related to why this is happening.

You might be able to search for an app-note or Q&A about this on Xilinx's web-site, since they are the ones who developed and own the XST tool.
Also keep in mind that having warnings like this one is not necessary a bad thing, as long as you completely understand what it is telling you.

Finally, you might consider instead using true RAMs, and changing the 2-dimensional index into a one-dimensional index.
e.g. index = (row_counter << 3) + j; // assumes inner-dimension is 8
This may waste some of the RAM, but would still use less resources than creating a RAM out of discrete flops and LUTs (assuming you have RAM blocks available in your device).
And, the behavior would no longer need to create Z's from tristates.
 
Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top