【问题标题】:Please help me with VHDL compile error [duplicate]请帮我解决VHDL编译错误[重复]
【发布时间】:2018-06-07 17:24:40
【问题描述】:
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;

我为我的家庭作业制作了这个代码来制作数字门锁。 而这一行在我编译时有错误。

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

错误如下所示

** 错误:D:\modelsim\Door.vhd(53): 无法读取输出“警报”。

VHDL 2008 允许读取输出。 通过使用 -2008 编译启用此功能。

** 错误:D:\modelsim\Door.vhd(53): 无法读取输出“门”。

VHDL 2008 允许读取输出。 通过使用 -2008 编译启用此功能。

** 错误:D:\modelsim\Door.vhd(53): 无法读取输出“关闭”。

VHDL 2008 允许读取输出。 通过使用 -2008 编译启用此功能。

** 错误:D:\modelsim\Door.vhd(55): VHDL 编译器正在退出

我不知道为什么会这样,请帮帮我

【问题讨论】:

  • 错误消息说明了整个故事:一个输出端口从您的模块中出来,无法读取。您只能读取输入端口和信号。您可以为dooralarmturnoff 定义内部信号并将它们分配给输出端口,或者使用允许读取输出端口的VHDL-2008。
  • 将编译器设置为 VHDL-2008 模式,或开始使用中间信号。
  • 附言。如果您要使用 VHDL-2008,请考虑使用 case? 语句而不是这个 if-elsif-elsif-etc。结构。
  • 哦,您的信号有多个驱动程序。请考虑使用时钟并将所有作业放在一个进程中。
  • @JHBonarius 你刚刚在你的 cmets 中写下了整个答案。你为什么不写他们的答案?

标签: compilation vhdl


【解决方案1】:

首先:“请帮助我”不是一个好问题。最好是类似“编译时Modelsim错误“无法读取输出””

第二点:错误描述性很强。 “无法读取输出“警报””。 alarm 被声明为

alarm : out std_logic;

因此它是一个输出端口。在 2008 年之前的 VHDL 中,不允许读取输出端口。接下来编译器提示如何修复它:

“VHDL 2008 允许读取输出。此功能通过使用 -2008 编译启用。”

那就这样做吧! 在你的modelsim编译窗口中选择“默认选项”

然后设置为VHDL-2008

或者,您实际上可以在命令行上执行所描述的操作(添加-2008):

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

瞧。完成的!不是吗?


别等了,还是不行!

您有多个驱动程序错误。在第 23 行它指出:

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

这就像一个闩锁,实际上是一样的

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

因此,一旦出现reset='0',该进程会将door 驱动为固定值。在password-触发的过程中,您再次驱动door!这将很难解决。例如。如果(password = "------10"),那么door &lt;= "00000001"。这将解决:

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

因为将'0' 连接到'1' 相当于短路。

让我们来看看合适的设计。您现在正在触发 password 的更改。不是很好,但这是可能的。我会使用另一个触发器,例如未使用的enable 信号。但无论如何:我们引入了一个额外的信号来检测变化password_delay。但更重要的是我们引入了时钟。在数字硬件中,大多数系统都使用时钟。最后,我们使用新的 VHDL-2008 语句 case? 来解码 don't cares。

VHDL-2008代码一起变成:

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;

那是不同的东西,嗯?对不起,我没时间给你写一个测试台。

注意:代码给出编译器警告

警告:C:/HDL/doorlock/doorlock.vhd(20): (vcom-1013) "password_delay" 的初始值取决于信号 "password" 的值。

忽略这个。这是模拟所必需的,否则password_delay 的未定义初始值将导致password /= password_delay 的触发。

【讨论】:

  • 非常感谢,但我可以再问你一个问题吗?我编写了完全相同的代码并对其进行了模拟,但是当我更改输入时输出没有改变。在我的课堂上 30 分钟关于 vhdl 的讲座不足以解决这个问题 ;(
  • @JinHoyong 学习远远超过 30 分钟的讲座(顺便说一下,30 分钟很短):它是看书,做练习等。使用别人的代码不是学习。我是大学的导师,如果我看到某人的作业包含那个人还不知道的代码,我会请学生来解释代码。如果他/她不能,我会让他/她在这门课上不及格。所以不要使用你无法解释的代码......
猜你喜欢
  • 2015-07-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-18
  • 1970-01-01
  • 2022-09-27
  • 1970-01-01
  • 2023-04-10
相关资源
最近更新 更多