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.

Using both falling and rising edge of clock: timing consequences

Status
Not open for further replies.

J90

Junior Member level 1
Joined
Aug 14, 2010
Messages
17
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Location
Italy
Activity points
1,443
Hi there,

I have a project that involves a state machine. Some states require the machine to wait for a certain amount of time.
I thought of implementing the delays using some simple counters, so the design would be something like:

Code:
process(clk)
begin
	if rising_edge(clk) then
		-- description of the state machine
	end if;
end process;

process(clk)
begin
	if rising_edge(clk) then
		-- description of one counter
	end if;
end process;

But wait, this way I'm gonna get some really bad glitches, ain't I?
The state machine, in order to jump to the next state, checks the value of the counter, but the counter increments its value at the same time, resulting in unpredictable results.

I thought of using something like this instead:

Code:
process(clk)
begin
	if rising_edge(clk) then
		-- description of the state machine
	end if;
end process;

process(clk)
begin
	if falling_edge(clk) then
		-- description of one counter
	end if;
end process;

This way the check is being done on the rising edge of the clock, while the counter is incrementing its value on the falling edge of the same clock, resulting in no glitches.

Now, my question is, how is this going to be synthesized on the FPGA? By the way I'm working with a Spartan3 device.

Furthermore, is this going to reduce the maximum admissible clk frequency?


Thanks :wink:
 
Last edited:

But wait, this way I'm gonna get some really bad glitches, ain't I?
The state machine, in order to jump to the next state, checks the value of the counter, but the counter increments its value at the same time, resulting in unpredictable results.
No. The counter does not increment it's value at the same time. The new counter value will be evaluated at the next clock edge. That's how all synchronous logic works. It's the same with the state machine logic itself.

The prerequisition for operating synchronous logic this way is, that the clock tree delay skew must not be larger than the sum of logic cell delays and the required hold time of all involved register. This is checked by a timing analysis after logic synthesis.
 
  • Like
Reactions: J90 and shmoib

    shmoib

    Points: 2
    Helpful Answer Positive Rating

    J90

    Points: 2
    Helpful Answer Positive Rating
Indeed. VHDL forces you to use the <= non-blocking assign for signals. In verilog, you can use either blocking or non-blocking, and that is where you run into problems. The simulator/synthesizer will detect that clock has changed, then go to each process that has the clock in the sensitivity list and evaluate it. The non-blocking assign says "wait for all logic to be evaluated, then do this". In verilog, using blocking assigns can result in unpredictable simulations, as blocking assigns will immediately update the signal.
 
  • Like
Reactions: J90

    J90

    Points: 2
    Helpful Answer Positive Rating
Thank you both for your answers.


No. The counter does not increment it's value at the same time. The new counter value will be evaluated at the next clock edge.

I don't understand :-( Is this true only in the hardware implementation (so it's a direct cause of the routing delays) or is this true even when simulating? (i.e. is this defined by VHDL?)

I wrote a simple chunk of code to do some tests:

Code:
entity top is
	port(	
			clk: in std_logic;
			dummy_out: out std_logic
		);
end top;

architecture Behavioral of top is

	type state_type is (s0, s1);
	signal curr_state: state_type := s0;
	signal next_state: state_type;
	signal count: natural := 0;
	
begin

	process(clk)
	begin
		if rising_edge(clk) then
			curr_state <= next_state;
		end if;
	end process;
	
	process(curr_state, count)
	begin
		case curr_state is
			when s0 =>
				dummy_out <= '0';
				if count = 20 then
					next_state <= s1;
				else
					next_state <= s0;
				end if;
			when s1 =>
				dummy_out <= '1';
				next_state <= s1;
		end case;
	end process;
	
	process(clk)
	begin
		if rising_edge(clk) then
			count <= count + 1;
		end if;
	end process;

end Behavioral;

The following is the result of the behavioral simulation:
**broken link removed**

As expected two things are happening where the cursor is positioned: count value is being incremented, meanwhile the state machine is evaluating count value to choose the next state. Actually dummy_out goes high, so it seems everything is working fine, but is there any assurance that this will be the behavior of every simulator? Is there any reference to this behavior in VHDL?

And the following is the result of the post place and route simulation:
**broken link removed**

Looks like everything is magically fine. Is this due to the skew delays conveniently calculated by the synthesizer?

Can I use this approach for my projects? I mean, is this safe?


Thanks.
 

Attachments

  • behav.PNG
    behav.PNG
    8.3 KB · Views: 124
  • post par.PNG
    post par.PNG
    10.8 KB · Views: 117

In simulation, the intended behaviour (all results of edge sensitive processes get effective in the next clock cycle) is guaranteed by basic VHDL rules of program "execution". I don't want to retell the VHDL standard or profound text books here, please take the time to review them yourself.

In my view, it's instructive to follow the equivalence between edge sensitive processes and synchronous hardware logic circuits.

For synthesized logic, timing driven place and route can be expected to inforce the rules and timing analysis to check the result.
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top