# Using both falling and rising edge of clock: timing consequences

Status
Not open for further replies.

#### J90

##### Junior Member level 1
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:

#### FvM

##### Super Moderator
Staff member
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.

J90 and shmoib

Points: 2

### J90

Points: 2

#### permute

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.

J90

### J90

Points: 2

#### J90

##### Junior Member level 1

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:

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:

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
8.3 KB · Views: 22
• post par.PNG
10.8 KB · Views: 20

#### FvM

##### Super Moderator
Staff member
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.