Counter with asynchronous enable

R

Ramya Murali

I have a counter (positive edge triggered) whose enable (active high)
is generated by a two state FSM (positive edge state transition).
Counter_enable is set to '0' in State 1 and set to '1' in State 2.

signal count : std_logic_vector (3 downto 0) := "0000";
p1 : process (clk, counter_enable)
begin
if ((rising_edge (clk) and (counter_enable = '1')) then
count <= count +1;
end if;
end process p1;

p2 : process (current_state)
case current_state is
when '0' => next_state <= '1'; counter_enable <= '0';
when '1' => next_state <= '1'; counter_enable <= '1;
when OTHERS => next_state <= '0'; counter_enable <= '0';
end case;
end process;

While simulating using ModelSim, at the positive edge of the clock
( say edge1) when the state transitions from S1 to S2, the
counter_enable is set to '1' correctly. But the counter doesnot begin
to count at this positive edge (edge1) but begins to count at the next
positive edge of the clock (edge2).

My reasoning is as follows.
The assignment to counter_enable occurs at the end of process p2,
which is at delta time after edge1. At delta time, even though the
process p1 is activated as counter_enable is included in its
sensitivity list, the condition rising_edge(clk) is not true and the
count is not incremented.

Is this correct? Is the counter_enable asynchronous?
 
G

Gabor

Ramya said:
I have a counter (positive edge triggered) whose enable (active high)
is generated by a two state FSM (positive edge state transition).
Counter_enable is set to '0' in State 1 and set to '1' in State 2.

signal count : std_logic_vector (3 downto 0) := "0000";
p1 : process (clk, counter_enable)
begin
if ((rising_edge (clk) and (counter_enable = '1')) then
count <= count +1;
end if;
end process p1;

p2 : process (current_state)
case current_state is
when '0' => next_state <= '1'; counter_enable <= '0';
when '1' => next_state <= '1'; counter_enable <= '1;
when OTHERS => next_state <= '0'; counter_enable <= '0';
end case;
end process;

While simulating using ModelSim, at the positive edge of the clock
( say edge1) when the state transitions from S1 to S2, the
counter_enable is set to '1' correctly. But the counter doesnot begin
to count at this positive edge (edge1) but begins to count at the next
positive edge of the clock (edge2).

My reasoning is as follows.
The assignment to counter_enable occurs at the end of process p2,
which is at delta time after edge1. At delta time, even though the
process p1 is activated as counter_enable is included in its
sensitivity list, the condition rising_edge(clk) is not true and the
count is not incremented.

Is this correct? Is the counter_enable asynchronous?

It is correct and it is synchronous. This is how synchronous
logic behaves. By the way, you should not have counter_enable in
the sensitivity list of the clocked process. For simulation
it does nothing, because the only place it is used is when
it is ANDed with a rising edge of the clock. For synthesis
it could confuse the tools to think you're trying to use
counter_enable as an asynchronous reset input, or it could also do
nothing, or it could cause an error like "invalid sequential
description" depending on the synthesizer you use.

In any sort of real synchronous logic, anything that depends on
the rising edge of the clock takes its inputs from logic
levels before the rising edge of the clock and won't change
its output until after the rising edge of the clock. If you
want your counter to count on the same edge when your state machine
goes into state 2, then you need to enable the counter with
the same terms that cause the state transition so the count
enable is valid before the clock where the state transitions.

-- Gabor
 
J

JimLewis

Clock rises, the output of the current_state flip-flop
changes state, it is decoded, and the counter_enable
output is generated. Just like real hardware, the
counter_enable does not update on the same clock
edge that generates it, however, it is synchronous
since it is generated off of Clk (the same clock we are
referencing).

Asynchronous signals are independent of the current
clock domain and require special handling.

You may want to try out your count enable in your preferred synthesis
tool as some have issues with that coding style. You may need to
code counter_enable in a separate if statement.
My reasoning is as follows.
The assignment to counter_enable occurs at the end of process p2,
which is at delta time after edge1. At delta time, even though the
process p1 is activated as counter_enable is included in its
sensitivity list, the condition rising_edge(clk) is not true and the
count is not incremented.
Counter_enable change 2 delta cycles after clock. One for the update
to current_state and one for the update to counter_enable.

It will help if you draw all of your timing diagrams with
a small propagation delays - the real hardware will have these.
Although delta cycles are part of the simulation algorithm, in
an abstract way they work similar to a propagation delay.
 
A

Andy

You may want to try out your count enable in your preferred synthesis
tool as some have issues with that coding style.  You may need to
code counter_enable in a separate if statement.

1076.6-2004, section 6.1.3.1, example 4, supports this construct. By
now, every synthesis tool should support it or be drawn and
quartered.

That said, verifying feature support by the tool in use is never a bad
idea! We don't want to draw and quarter anyone unless they really
deserve it.

Andy
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,479
Members
44,899
Latest member
RodneyMcAu

Latest Threads

Top