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.

FPGA Set Up and Hold Explanation

Status
Not open for further replies.

FecP

Newbie level 6
Newbie level 6
Joined
Oct 17, 2016
Messages
14
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
160
This is code to detect falling pulses from two inputs.As the image attached shows, as soon as v_sync_a goes low or v_sync_b goes low, v_sync_a_falling goes or v_sync_b_falling go high. Now, let's say that the code were run on Hardware, If v_sync_a or v_sync_b fall at the exact same instant as the rising edge of the clock.How can the FPGA (Spartan-3E) operate as it does? Aren't there setup and hold time violations here?


Code:
module question(
	 input reset,
	 input clk,
    input v_sync_a,
    input v_sync_b,
    output reg v_sync_a_falling,
    output reg v_sync_b_falling
    );
	 reg v_sync_a_r;
	 reg v_sync_b_r;

always @(posedge clk)
begin
if(reset)
begin
v_sync_a_r <= 0;
v_sync_b_r <= 0;
end

else

begin
v_sync_a_r <= v_sync_a;
v_sync_b_r <= v_sync_b;
v_sync_a_falling <= (v_sync_a < v_sync_a_r) ? 1 : 0;
v_sync_b_falling <= (v_sync_b < v_sync_b_r) ? 1 : 0;
end

end
endmodule

Test Bench :

Code:
module test;

	// Inputs
	reg reset;
	reg clk;
	reg v_sync_a;
	reg v_sync_b;
	

	// Outputs
	wire v_sync_a_falling;
	wire v_sync_b_falling;

	// Instantiate the Unit Under Test (UUT)
	question uut (
		.reset(reset),
		.clk(clk), 
		.v_sync_a(v_sync_a), 
		.v_sync_b(v_sync_b), 
		.v_sync_a_falling(v_sync_a_falling), 
		.v_sync_b_falling(v_sync_b_falling)
	);

	initial begin
		// Initialize Inputs
		clk = 0;
		v_sync_a = 1;
		v_sync_b = 1;
		reset = 1;
		#5 reset=0;

		// Wait 100 ns for global reset to finish
		#100;
        
		// Add stimulus here

	end
	always 
	#5 clk <= ~ clk;
   always @ (posedge clk)
	begin
	#10 v_sync_a <= ~ v_sync_a;
	#20 v_sync_b <= ~ v_sync_b;
	end
endmodule


Does this code run in hardware as it does in simulation? If so, how?

question.jpg
 

What is up with this code. Why would you compare with a < comparison operator two 1-bit wide signals?

Code Verilog - [expand]
1
2
v_sync_a_falling <= (v_sync_a < v_sync_a_r) ? 1 : 0;
v_sync_b_falling <= (v_sync_b < v_sync_b_r) ? 1 : 0;



Just performing the Boolean logic equation is much simpler and easier to understand the intention.

Code Verilog - [expand]
1
2
3
4
v_sync_a_falling <= ~v_sync_a  & v_sync_a_r;
 
// or explicitly compare bits
v_sync_a_falling <= ({v_sync_a_r, v_sync_a} == 2'b10);



Now onto your simulation...it's wrong you have a delta cycle race condition with the clock because you didn't generate your testbench inputs based on the clock you are driving your DUT with.

Your use of #10 and #20 delays skews your v_sync_a and v_sync_b signals by the entire clock period, if you use a # delay to shift the input signals off of clock edges then use something closer to 1/4 or 1/8 of the clock period. In this case I would probably use #1 or #2.
 
  • Like
Reactions: FecP

    V

    Points: 2
    Helpful Answer Positive Rating

    FecP

    Points: 2
    Helpful Answer Positive Rating
@FecP

When an input can toggle at any time, you could have setup/hold violations. There are three main ways this can affect your design:
1.) Metastability -- There is a point where you sample the rising/falling waveform and the output either slowly changes to a value, or oscillates for a while and then changes to a value. This is typically mitigated using a sequence of 2-3 registers. This doesn't actually solve the problem, but it does reduce the problem to below the frequency of errors due to things like radiation/etc...
2.) Skew -- When the async signal goes to multiple destinations there can be issues if there are small differences in the delay it takes to reach each one. Some may act on the old value, some on the new value. This also applies to a multi-bit wide value that is async -- some bits of a bus could be early, some late.
3.) Glitches, when non-trivial logic drives async input -- async resets for example -- there is a higher chance that the logic will have short glitches before stablizing to a valid value. This is more of an issue with having async control signals.

For your case, you would typically have three to four registers. The first two are the "synchronizer" to remove metastability. The third would perform the one additional cycle of delay needed by your edge detect circuit. In your case, you register this value, thus you would have four registers per input to detect an edge.


You are also not modeling the actual HW. You are modeling an idealized version. If you want to see a better representation of what the S3 does, you can generate a post place-and-route simulation. This will show delayed signals. This is not normally done for FPGAs, as the normal simulation is much faster and almost always provides the same information.
 
  • Like
Reactions: FecP

    FecP

    Points: 2
    Helpful Answer Positive Rating
It feels like one might be better off using an
Code:
always @ (*)
block to handle external inputs.How does a reg declared in such a block differ from a simple wire? And from what I have understood about Synchronizing registers, they only help control clock to output delay.In that case, why would increasing the length of a synchronizing chain decrease metastability because if the output of the 1st synchronizing register hasn't settled by the next clock cycle, then isn't that error just going to propagate throughout the rest of the chain?
 

always @ (*) generates combinational logic, not registers. It can't perform any synchronizing.
 

why would increasing the length of a synchronizing chain decrease metastability because if the output of the 1st synchronizing register hasn't settled by the next clock cycle, then isn't that error just going to propagate throughout the rest of the chain?

Why? because metastability is inherently an unstable condition, and each register in a chain of synchronizer flip-flops will exhibit one or more of the following conditions when being subjected to a input changing within the setup-hold window around the clock edge: runt pulse, delayed transition, increased transition slope (i.e. slow rise time). As these all deal with the amount of energy that the input transistors see they may or may not happen every time the setup-hold window is violated.

With today's smaller feature size the transistors are much much smaller and the amount of energy needed to switch the transistors is subsequently much less and the proverbial knife edge to push it one way or another is smaller therefore the excessively long transitions where an output may hover within the no-mans land of between valid output thresholds is highly unlikely (hence the lack of runt pulses in today's technology).

If you want to understand the calculations to determine how synchronization registers help with asynchronous inputs you should look to the MTBF calculations. This site may help you understand this: http://www.interfacebus.com/Design_MetaStable.html

- - - Updated - - -

edit - this is also why there are rules about not having any logic between flip-flops in a synchronizer chain and to co-locate all the flip-flops next to each other to reduce the routing delay between flip-flops. This is why tools such as Xilinx's Vivado accepts the Verilog attribute ASYNC_REG="TRUE" on any flip-flops in the design to ensure the P&R tools will place those flip-flops in the same slice.
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top