Search code examples
vhdl

Can't resolve multiple constant


I'm trying to create a FSM but I'm getting the error can't resolve multiple constant drivers

Here's my code:

 library ieee;
    use ieee.std_logic_1164.all;
    use ieee.numeric_std.all;
    library work;
    use work.all;

    entity fsm is 
        port(
            reset,clk : in std_logic;
            dataout: out std_logic_vector(7 downto 0)
        );
    end entity fsm;

    architecture bhv_fsm of fsm is
    type FSM_TYPE is (standby, ready, encryption, decryption);
    signal pre_state, next_state : FSM_TYPE;
    signal cmd, cancel, busy, acquirekey : std_logic;
    signal controller: std_logic_vector(3 downto 0);
    signal dout: std_logic_vector(7 downto 0);
    begin
    controller <= cmd & cancel & busy & acquirekey;
    P1: process(clk, reset) is

    begin 
        dataout <= "00000000"; 
        if reset='1' then
        next_state <= standby;
        elsif rising_edge(clk) then
            pre_state <= next_state;
        end if;
    end process P1; 

    LC1_LC2: process(pre_state, next_state) is
    variable timer: integer :=0;
    begin
    dataout <= (others => '0');
    next_state <= pre_state;
    case pre_state is
        when standby => 
            if (controller = "0000") then
            next_state <= ready;
            end if;

        when ready =>
            if(timer<10) then
                if (controller = "1000") then
                next_state <= encryption;
                timer:=0;
                controller <= "0010";
                timer:=timer+1;
                elsif (controller = "0000") then
                next_state <= decryption;
                timer:=0;
                controller <= "0010";
                end if;
            timer:=timer+1;
            else
            next_state <= standby;
            end if;

            when encryption =>
                if(controller = "1110") then
                    next_state <= ready;
                elsif(controller = "1011") then
                    dataout <= dout;
                    next_state <= ready;
                end if; 
            -- cmd cancel busy acquire

            when decryption =>
                if(controller = "0110")then
                    next_state <= ready;
                elsif(controller = "0011") then
                    dataout <= dout;
                    next_state <= ready;
                end if; 

    end case;           
    end process LC1_LC2;
    end architecture bhv_fsm;

These are the errors:

Error (10028): Can't resolve multiple constant drivers for net "next_state.standby" at fsm.vhd(33)

Error (10029): Constant driver at fsm.vhd(22)

Error (10028): Can't resolve multiple constant drivers for net "next_state.ready" at fsm.vhd(33)

Error (10028): Can't resolve multiple constant drivers for net "next_state.encryption" at fsm.vhd(33)

Error (10028): Can't resolve multiple constant drivers for net "next_state.decryption" at fsm.vhd(33)

Error (10028): Can't resolve multiple constant drivers for net "controller[3]" at fsm.vhd(21)

Error (10029): Constant driver at fsm.vhd(33)

Error (10028): Can't resolve multiple constant drivers for net "controller[2]" at fsm.vhd(21)

Error (10028): Can't resolve multiple constant drivers for net "controller[1]" at fsm.vhd(21)

Error (10028): Can't resolve multiple constant drivers for net "controller[0]" at fsm.vhd(21)


Solution

  • When you synthesise VHDL, each process becomes a lump of hardware that drives any signal that is driven by that process. If you drive a signal from more than one process then you end up with more than one lump of hardware driving that signal; that signal is driven from more than one place. In other words, you have a short circuit.

    This is usually not the behaviour you want and is usually not behaviour that logic synthesisers are prepared to create. This is the case with your code:

    You have three concurent processes in your code. This one:

    controller <= cmd & cancel & busy & acquirekey;
    

    which drives the signal controller; this one:

    P1: process(clk, reset) is
    

    which drives the signals dataout, next_state and pre_state; and this one:

    LC1_LC2: process(pre_state, next_state) is
    

    which also drives the signals controller, next_state and data_out.

    So, the signals controller, next_state and data_out are driven from more than one process; these signals will be driven by more than one lump of hardware. You synthesiser doesn't likes this, I'm pretty sure this isn't want you want.

    You're not writing software. VHDL is a hardware description language. You need to think more hardware.

    I don't know your design intent; I can only "suspect". But, I suspect you don't need this line at all:

        dataout <= "00000000"; 
    

    and I suspect these lines:

        if reset='1' then
        next_state <= standby;
    

    should be:

        if reset='1' then
        pre_state <= standby;
    

    I suspect you don't need this line at all:

     controller <= cmd & cancel & busy & acquirekey;