Search code examples
compilationvhdl

Please help me with VHDL compile error


library IEEE;
use IEEE.std_logic_1164.all;

entity doorlock is
port(   reset : in std_logic;
    enable : in std_logic;
    password : in std_logic_vector (7 downto 0);
    door : out std_logic_vector (7 downto 0);
    lock : out std_logic;
    alarm : out std_logic;
    turnoff : out std_logic);
end doorlock;

--password is 10(decimal no.) which is 00010000(binary no.)

architecture DDL of doorlock is
signal err_count : integer range 0 to 5 := 0;

begin
lock <= '0' when (reset = '0');
alarm <= '0' when (reset = '0');
turnoff <= '0' when (reset = '0');
door <= "00000000" when (reset = '0');
lock <= '0' when (enable <= '0');

process(password)
begin
    if (password = "-------1") then
    door <= "00000000";
    elsif (password = "------10") then
    door <= "00000001";
    elsif (password = "-----100") then
    door <= "00000011";
    elsif (password = "----1000") then
    door <= "00000111";
    elsif (password = "---00000") then
    door <= "00001111";
    elsif (password = "--110000") then
    door <= "00011111";
    elsif (password = "-1010000") then
    door <= "00111111";
    elsif (password = "10010000") then
    door <= "01111111";
    elsif (password = "00010000") then
    door <= "11111111";
    end if;

    err_count <= err_count + 1;
end process;

alarm <= '1' when (err_count = 3);
turnoff <= '1' when (err_count = 5);
lock <= '1' when (door = "11111111" and turnoff = '0' and alarm = '0');

end DDL;

I made this code for my homework making digital door lock. And this line have error as I compile it.

lock <= '1' when (door = "11111111" and turnoff = '0' and alarm = '0');

Error is like this below

** Error: D:\modelsim\Door.vhd(53): Cannot read output "alarm".

VHDL 2008 allows reading outputs. This facility is enabled by compiling with -2008.

** Error: D:\modelsim\Door.vhd(53): Cannot read output "door".

VHDL 2008 allows reading outputs. This facility is enabled by compiling with -2008.

** Error: D:\modelsim\Door.vhd(53): Cannot read output "turnoff".

VHDL 2008 allows reading outputs. This facility is enabled by compiling with -2008.

** Error: D:\modelsim\Door.vhd(55): VHDL Compiler exiting

I don't know why it happens please help me


Solution

  • First off: "Please help me" is not a good question. Better would be something like "Modelsim error "cannot read output" when compiling"

    Second off: The error is quite descriptive. "Cannot read output "alarm"". alarm is declared as

    alarm : out std_logic;
    

    Thus it is an output port. In pre-2008 VHDL it was not allowed to read output ports. Next the compiler hints on how to fix it:

    "VHDL 2008 allows reading outputs. This facility is enabled by compiling with -2008."

    So do so! In your modelsim compilation window select "default options"

    enter image description here

    And then set to VHDL-2008

    enter image description here

    Alternatively you can actually do what is described (add the -2008) on the command line:

    vcom -reportprogress 300 -work work -2008 doorlock.vhd

    Voila. Finished! Not?


    No wait, still doesn't work!

    You have a multiple driver error. In line 23 it states:

    door <= "00000000" when (reset = '0');
    

    This acts as a latch, effectively being the same as

    process(reset) begin
        if reset = '0' then
            door <= "00000000";
        end if;
    end process;
    

    Thus once reset='0' has occurred, the process will drive door to a fixed value. In the password-triggered process you again drive door! This will resolve badly. E.g. if (password = "------10"), then door <= "00000001". This will resolve:

    resolve("00000000", "00000001") = "0000000X"
    

    Because connecting '0' to '1' is equivalently a short-circuit.

    So let's look at proper design. You're now triggering on a change of password. Not so nice, but it's possible. I would use another trigger, like the enable signal that is not being used. But anyhow: we introduce an extra signal to detect the change password_delay. But more importantly we introduce a clock. In digital hardware most systems use a clock. Finally, we use the new VHDL-2008 statement case? to decode the don't cares.

    Together the VHDL-2008 code becomes:

    library IEEE;
    use IEEE.std_logic_1164.all;
    
    entity doorlock is
        port(
            clk : in std_logic;
            reset : in std_logic;
            enable : in std_logic;
            password : in std_logic_vector (7 downto 0);
            door : out std_logic_vector (7 downto 0);
            lock : out std_logic;
            alarm : out std_logic;
            turnoff : out std_logic
            );
    end doorlock;
    
    --password is 10(decimal no.) which is 00010000(binary no.)
    
    architecture DDL of doorlock is
        signal password_delay : std_logic_vector(password'range) := password;
        use ieee.numeric_std_unsigned.all;
        signal err_count : integer range 0 to 5 := 0;
    begin
        clk_proc : process(clk) begin
            if rising_edge(clk) then
                if reset = '0' then
                    door <= (others => '0');
                    lock <= '0';
                    alarm <= '0';
                    turnoff <= '0';
                    err_count <= 0;
                else -- no reset :)
                    if password /= password_delay then
                        case? password is
                            when "-------1" => door <= "00000000";
                            when "------10" => door <= "00000001";
                            when "-----100" => door <= "00000011";
                            when "----1000" => door <= "00000111";
                            when "---00000" => door <= "00001111";
                            when "--110000" => door <= "00011111";
                            when "-1010000" => door <= "00111111";
                            when "10010000" => door <= "01111111";
                            when "00010000" => door <= "11111111";
                            when others => null;
                        end case?;
                        err_count <= err_count + 1;
                    end if;
                    case err_count is
                        when 3 => alarm <= '1';
                        when 5 => turnoff <= '1';
                        when others => null;
                    end case;
                    if door = "11111111" and turnoff = '0' and alarm = '0' then
                        lock <= '1';
                    end if;
                end if;
                password_delay <= password;
            end if;
        end process;
    end DDL;
    

    That's something different, eh? I'm sorry, but I don't have time to write a test bench for you.

    NOTE: The code gives a compiler warning

    Warning: C:/HDL/doorlock/doorlock.vhd(20): (vcom-1013) Initial value of "password_delay" depends on value of signal "password".

    Ignore this. This is required for simulation as else undefined initial value of password_delaywill cause a trigger of password /= password_delay.