counter in state machine

T

tringuyen858

Hi all,

I am trying to simulate a state machine that has a counter. Below is
the code. When I run the simulation, it gets stuck at BEGIN_COUNT and
start_flag_counter is X"01" throughout the whole simulation. I can't
figure out what is wrong. May be it is something obvious that I can't
see. thank you for your input.

SYNC_PROC: process (clk_100, SYS_RST_N)
begin
if (SYS_RST_N='0') then
state_count <= INIT;
clk_100_locked_reg <= '0';
lock_reg_int_reg <= '0';
elsif rising_edge(clk_100) then
state_count <= next_state;
clk_100_locked_reg <= clk_100_locked;
lock_reg_int_reg <= lock_reg_int;
end if;
end process;

start_sig: process(state_count, clk_100_locked_reg,
lock_reg_int_reg)
begin
case state_count is
when INIT =>
start_reg <= '0';
start_flag_counter <= X"00";
if clk_100_locked_reg = '1' and lock_reg_int_reg = '1'
then
next_state <= BEGIN_COUNT;
else
next_state <= INIT;
end if;
when BEGIN_COUNT =>
start_flag_counter <= start_flag_counter + 1;
start_reg <= '0';
if start_flag_counter = X"64" then
next_state <= START_FLAG;
else
next_state <= BEGIN_COUNT;
end if;
when START_FLAG =>
start_flag_counter <= start_flag_counter + 1;
start_reg <= '1';
if start_flag_counter = X"6A" then
next_state <= STOP_COUNT;
else
next_state <= START_FLAG;
end if;
when STOP_COUNT =>
start_flag_counter <= X"00";
start_reg <= '0';
next_state <= STOP_COUNT;
end case;
end process;
 
T

Tricky

Hi all,

I am trying to simulate a state machine that has a counter.  Below is
the code.  When I run the simulation, it gets stuck at BEGIN_COUNT and
start_flag_counter is X"01" throughout the whole simulation.  I can't
figure out what is wrong.  May be it is something obvious that I can't
see.  thank you for your input.

   SYNC_PROC: process (clk_100, SYS_RST_N)
   begin
      if (SYS_RST_N='0') then
         state_count <= INIT;
         clk_100_locked_reg <= '0';
         lock_reg_int_reg <= '0';
      elsif rising_edge(clk_100) then
         state_count <= next_state;
         clk_100_locked_reg <= clk_100_locked;
         lock_reg_int_reg <= lock_reg_int;
      end if;
   end process;

   start_sig: process(state_count, clk_100_locked_reg,
lock_reg_int_reg)
   begin
      case state_count is
         when INIT =>
            start_reg <= '0';
            start_flag_counter <= X"00";
            if clk_100_locked_reg = '1' and lock_reg_int_reg = '1'
then
               next_state <= BEGIN_COUNT;
            else
               next_state <= INIT;
            end if;
         when BEGIN_COUNT =>
            start_flag_counter <= start_flag_counter + 1;
            start_reg <= '0';
            if start_flag_counter = X"64" then
               next_state <= START_FLAG;
            else
               next_state <= BEGIN_COUNT;
            end if;
         when START_FLAG =>
            start_flag_counter <= start_flag_counter + 1;
            start_reg <= '1';
            if start_flag_counter = X"6A" then
               next_state <= STOP_COUNT;
            else
               next_state <= START_FLAG;
            end if;
         when STOP_COUNT =>
            start_flag_counter <= X"00";
            start_reg <= '0';
            next_state <= STOP_COUNT;
      end case;
   end process;


You need to put the counter in it's own clocked process. At the
moment, when it gets into the "BEGIN_COUNT" state, nothing is changing
that causes the sensitivity list to fire and cause the counter to
increment. instead of putting the counter inside the state, put an
enable instead:

when BEGIN_COUNT =>
start_flag_count_en <= '1';
.......


count_proc : process(clk_100, SYS_RST_N)
begin
if SYS_RST_N = '0' then
start_flag_counter <= x"00";
elsif rising_edge(clk_100) then
if start_flag_count_en = '1' then
--add sync reset conditions first
start_flag_counter <= start_flag_counter + 1;
end if;
end if;
end process;



Of course, moving the whole state machine into a single process would
eliminate this problem because it would be clocked anyway.
 
B

Bert_Paris

(e-mail address removed) a exposé le 09/04/2009 :
start_flag_counter <= start_flag_counter + 1;

In a combinational process ?????
Bad, bad, bad....

You probably wouldn't have goofed if you had your FSM in a single
process.

Bert
 
A

Andy

Of course, moving the whole state machine into a single process would
eliminate this problem because it would be clocked anyway.

Agreed. Two-process (separate clocked and combinatorial processes)
descriptions are prone to latches (what you got), require twice the
signal declarations, twice the process executions per clock cycle,
cumbersome sensitivity lists, and a host of other bad side effects.

Andy
 
S

sdguy

Hi all,

I am trying to simulate a state machine that has a counter.  Below is
the code.  When I run the simulation, it gets stuck at BEGIN_COUNT and
start_flag_counter is X"01" throughout the whole simulation.  I can't
figure out what is wrong.  May be it is something obvious that I can't
see.  thank you for your input.

   SYNC_PROC: process (clk_100, SYS_RST_N)
   begin
      if (SYS_RST_N='0') then
         state_count <= INIT;
         clk_100_locked_reg <= '0';
         lock_reg_int_reg <= '0';
      elsif rising_edge(clk_100) then
         state_count <= next_state;
         clk_100_locked_reg <= clk_100_locked;
         lock_reg_int_reg <= lock_reg_int;
      end if;
   end process;

   start_sig: process(state_count, clk_100_locked_reg,
lock_reg_int_reg)
   begin
      case state_count is
         when INIT =>
            start_reg <= '0';
            start_flag_counter <= X"00";
            if clk_100_locked_reg = '1' and lock_reg_int_reg = '1'
then
               next_state <= BEGIN_COUNT;
            else
               next_state <= INIT;
            end if;
         when BEGIN_COUNT =>
            start_flag_counter <= start_flag_counter + 1;
            start_reg <= '0';
            if start_flag_counter = X"64" then
               next_state <= START_FLAG;
            else
               next_state <= BEGIN_COUNT;
            end if;
         when START_FLAG =>
            start_flag_counter <= start_flag_counter + 1;
            start_reg <= '1';
            if start_flag_counter = X"6A" then
               next_state <= STOP_COUNT;
            else
               next_state <= START_FLAG;
            end if;
         when STOP_COUNT =>
            start_flag_counter <= X"00";
            start_reg <= '0';
            next_state <= STOP_COUNT;
      end case;
   end process;

thanks for all the suggestions. It works!!
 

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

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,060
Latest member
BuyKetozenseACV

Latest Threads

Top