Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
16 years ago

Variable in state Machine going Crazy (VHDL)

OK here is the code for my state machine. I am using it to control a serial multiplier in my circuit/

library ieee;

use ieee.std_logic_1164.all;

use ieee.std_logic_unsigned.all;

entity seq_mult_stateMachine is

port(clk, reset, start : in std_logic;

load_multiplier, shift_multiplier, load_multiplicand : out std_logic;

reset_product, load_product, shift_product : out std_logic;

done : out std_logic;

the_state : out std_logic_vector(1 downto 0); -- for debugging purpose only

counter_out : out std_logic_vector(3 downto 0)

);

end entity seq_mult_stateMachine;

architecture seq_mult_stateMachine_Architecture of seq_mult_stateMachine is

type theStat is (S0, S1, S2, S3);

signal present_state: theStat := S0;

signal next_state: theStat;

signal counter : std_logic_vector(3 downto 0);

begin

seq: process (clk) is

begin

if(rising_edge(clk)) then

if(reset = '1') then

present_state <= S0;

elsif(reset = '0') then

report "reached here";

present_state <= next_state;

end if;

end if;

end process seq;

com: process(start, present_state) is

begin

load_multiplier <= '0';

shift_multiplier <= '0';

load_multiplicand <= '0';

reset_product <= '0';

load_product <= '0';

shift_product <= '0';

done <= '0';

-- using signal the_state for debugging

case present_state is

when S0 => the_state <= "00";

when S1 => the_state <= "01";

when S2 => the_state <= "10";

when S3 => the_state <= "11";

end case;

--

case present_state is

when S0 =>

if(start = '1') then

--Initializing

load_multiplier <= '1';

load_multiplicand <= '1';

reset_product <= '1';

counter <= "0000";

next_state <= S1;

else

next_state <= S0;

end if;

when S1 =>

load_product <= '1';

counter <= counter + '1';

next_state <= S2;

when S2 =>

shift_product <= '1';

shift_multiplier <= '1';

if(counter = "1111") then

next_state <= S3;

else

next_state <= S1;

end if;

when S3 =>

done <= '1';

next_state <= S0;

when others =>

next_state <= S0;

end case;

counter_out <= counter;

end process;

end seq_mult_stateMachine_Architecture;

When I implemented it, it did Not work correctly. Thus I was forced to put the_state and counter_out signals for debugging purpose. When I run the simulation in Quartus with the other blocks and put the Start input, the output is shown in the Attachment.

Problem: My 'counter' variable goes crazy once the state S1 is entered, it keeps increasing regardless of the state being changed and finally I get the error of setup time violation. It should change ONLY when the state changes right? thats how I wrote the code.

Please tell me why this is happening I have used I integer before but the same result. http://www.alteraforum.com/images/icons/icon9.gif

1 Reply

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    It's no reasonable VHDL code. You are implementing a counter in an asynchronous process. That doesn't work. A counter must be implemented in a synchronous process, in other words, it needs an edge sensitive condition to infer registers rather than combinational logic.