VHDL无法驱动加载引脚

时间:2018-05-10 11:26:20

标签: vhdl synthesis

使用第一段代码,我得到了这个错误,我的一堆信号没有引脚。我很确定这是因为在第一段代码中,永远不会达到第一个if语句。为什么会这样?在第二个片段中,我修改了代码,我的所有问题都得到了解决。我把改变作为一种直觉的冲动,我不知道为什么要修复一切。有人可以解释一下合成器如何生成电路吗?

第一个片段:

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;

entity DataReg is
    generic(N: integer := 8);
    port(DIN: in std_logic_vector(N - 1 downto 0);
    DOUT: out std_logic_vector(N - 1 downto 0);
    CLK: in std_logic;
    ENABLE: in std_logic;
    RESET: in std_logic);
end DataReg;

architecture Behavioral of DataReg is
begin
    process(CLK, ENABLE)    
    begin
        if rising_edge(CLK) and ENABLE = '1' then
            DOUT <= DIN;
        end if;

        if rising_edge(CLK) and RESET = '1' then
            DOUT <= (others => '0');
        end if;
    end process;
end Behavioral;

第二个片段:(固定代码)

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;

entity DataReg is
    generic(N: integer := 8);
    port(DIN: in std_logic_vector(N - 1 downto 0);
    DOUT: out std_logic_vector(N - 1 downto 0);
    CLK: in std_logic;
    ENABLE: in std_logic
    RESET: in std_logic);
end DataReg;

architecture Behavioral of DataReg is
begin
    process(CLK, ENABLE)    
    begin
        if rising_edge(CLK) then
            if ENABLE = '1' then
                DOUT <= DIN;
            elsif RESET = '1' then
                DOUT <= (others => '0');
            end if;
        end if;
    end process;
end Behavioral;

2 个答案:

答案 0 :(得分:1)

因为HDL代码必须能够代表现有硬件。因此,当您编写RTL(寄存器传输级别)代码时,您必须坚持使用某些结构。即使您编写的第二个代码也不正确。

我无法解释所有规则,但基本上,使用边缘(上升或下降),您只能有一个信号。不是OR-es或And-es等:
  if rising_edge(CLK) then

在这样的时钟部分,您的过程可以有一个或两个以上的灵敏度信号。在某些特殊情况下,通常存在异步复位,也存在异步集。对于那些工作的人,你必须在之前时间条件。因此您的代码是错误的。只有在有时钟边沿时才会查看ENABLE和RESET。因此,将ENABLE放在灵敏度列表中是多余的。你也可以把它留下来。

此外,ENABLE if在RESET之前。因此,如果ENABLE为高,则RESET将被忽略。可能不是你想要的!

时钟部分的代码是非常标准的,我经常复制我已经存在的模板。 (我总是使用异步有源低电平复位)

process(clk, reset_n) 
begin
    if (reset_n='0') then

    elsif rising_edge(clk) then

    end if; -- reset/clocked
end process;

答案 1 :(得分:1)

首先,您提供的两段代码在模拟器中甚至不相同,因为ENABLERESET在时钟边缘都是1时,第一个代码段结果DOUT00000000,而在第二个结果中,结果为DIN

我的印象是Xilinx Vivado在综合过程中忽略了灵敏度列表(process之后括号中的部分)。我认为它们是仿制工具无法推断应该监控哪些变量以确定何时应该更新变量的遗留物。我不知道其他综合工具用它们做什么。

无论如何,您在敏感列表中指定了ENABLE,这意味着如果ENABLE更改值,您想要评估流程语句。除非正在发生上升的时钟边沿,否则所有if语句的计算结果均为false。因此,灵敏度列表中单独CLK就足以进行模拟。

所有这些,您应该将代码限制为综合工具供应商明确建议的格式。综合工具只能实现您可以用VHDL编写的所有内容的子集。对于Vivado,您可以在synthesis manual中找到建议的代码结构(这个是针对Vivado 2017.3)。在页71,您将看到他们建议使用以下形式的触发器:

process(clk) is
begin
    if rising_edge(clk) then
        if clr = '1' then
            dout <= "00000000";
        elsif ce = '1' then
            dout <= d_in;
        end if;
    end if;
end process;

您可以根据需要重命名变量。在第69页,您还将看到Xilinx建议使用同步实现(将所有内容放在rising_edge if语句中)而不是异步实现。手册中还有更多内容,例如关于如何编写移位寄存器或RAM,如果您想编写要与Vivado合成的代码,您应该熟悉它们。其他供应商的推荐代码也有类似的文档。