VHDL:有错误编码的除法,但在 Quartus II 上编译时有错误,但在 Xilinx ISE 上没有

VHDL: Division with error coding but there are errors in compiling on Quartus II but not on Xilinx ISE

我是 VHDL 的新手,我想获得一些帮助。你看,我们的导师告诉我们对二进制除法进行编码(首先将二进制转换为整数),如果除数为零,则输出误差波形将显示在仿真中。这是我的代码:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity division_in is
    Port ( A : in  STD_LOGIC_VECTOR (7 downto 0);
           B : in  STD_LOGIC_VECTOR (7 downto 0);
           clk : in  STD_LOGIC;
           Y : out  STD_LOGIC_VECTOR (7 downto 0);
           err : out  STD_LOGIC);
end division_in;

architecture Behavioral of division_in is

begin

  process(clk)
  begin
    if clk='1' and clk'event then -- error here
      Y <= conv_std_logic_vector(conv_integer(A)/conv_integer(B),8);
      err <= '0';
    elsif B = 0 then
      err <= '1';
    end if;
  end process;

end Behavioral;

当我尝试在 Xilinx ISE 9.1i(大学使用)中使用 "check syntax" 时,成绩单上没有显示任何语法错误。我什至可以毫无问题地使用测试台波形来模拟它。 然而,当我将此代码导入 Quartus II 时,我在消息中遇到了 5 个错误,尤其是在这个消息中:

Error (10818): Can't infer register for "err" at division_in.vhd(45) because it does not hold its value outside the clock edge

我不知道我在将确切代码从 Xilinx 复制到 Quartus 时做错了什么,但非常感谢您提供一点帮助,解释为什么我在 Quartus II 上出现此错误,但在 Xilinx ISE 9.1i 上却没有。由于 Xilinx ISE 已经不再兼容我的笔记本电脑,我只使用 Quartus II,因为它还有一个模拟功能,即 "Vector Waveform File" 模拟。

好的,首先,不要use IEEE.STD_LOGIC_ARITH.ALL;use IEEE.STD_LOGIC_UNSIGNED.ALL。您应该 use ieee.numeric_std.all,它为您提供使用类型 signedunsigned 的算术运算,以及 std_logic_vectorinteger.

的转换和转换函数

现在让我们看看您的代码:

if clk='1' and clk'event then -- error here
  Y <= conv_std_logic_vector(conv_integer(A)/conv_integer(B),8);
  err <= '0';
elsif B = 0 then
  err <= '1';
end if;

只看err信号,意思是在时钟上升沿,设置err'0'否则 如果 B = 0,则将 err 设置为 '1'。您提到这在模拟中有效,但对于综合,您需要考虑这在真实硬件中意味着什么。您如何想象 没有 检测到时钟边沿的情况?答案是不能。

目前尚不清楚您要实现的目标,但是在对上述包进行更改后,有两个可行的替代方案是:

if rising_edge(clk) then -- Use rising_edge() function
  Y <= std_logic_vector(signed(A)/signed(B));
  err <= '0'; -- Synchronous clear of `err`
end if;
if signed(B) = 0 then -- Asynchronous set of `err`
  err <= '1';
end if;

if rising_edge(clk) then
  Y <= std_logic_vector(signed(A)/signed(B));
  if signed(B) = 0 then
    err <= '1'; -- Synchronous control of `err`
  else
    err <= '0';
  end if;
end if;

如果您为端口提供它们实际的类型,即 signed,代码将需要更少的类型转换。您的流程的核心将如下所示:

if rising_edge(clk) then
  Y <= A / B;
  if B = 0 then
    err <= '1'; -- Synchronous control of `err`
  else
    err <= '0';
  end if;
end if;

我希望你能看到这有多容易阅读。