我是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;
当我尝试使用&#34;检查语法&#34;在Xilinx ISE 9.1i(由大学使用)中,成绩单上没有显示语法错误。我甚至可以使用测试平台波形来模拟它而没有任何问题。 但是,当我将此代码导入Quartus II时,我在消息中得到了5个错误,特别是在这个错误中:
错误(10818):无法推断注册&#34;错误&#34;在division_in.vhd(45)因为它没有在时钟边缘之外保持其值
我不知道在将Xilinx的精确代码复制到Quartus时我做错了什么但是对于为什么我在Quartus II上出现这个错误而不是在Xilinx ISE 9.1上得到这个错误有一点帮助一世。由于Xilinx ISE已不再与我的笔记本电脑兼容,我只使用Quartus II,因为它还具有模拟功能,即矢量波形文件&#34;模拟。
答案 0 :(得分:1)
好的,首先是第一件事,不要use IEEE.STD_LOGIC_ARITH.ALL;
或use IEEE.STD_LOGIC_UNSIGNED.ALL
。您应use ieee.numeric_std.all
,它为您提供使用signed
和unsigned
类型的算术,以及std_logic_vector
和integer
的强制转换和转换函数。
现在让我们来看看你的代码:
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'
,否则将设置为 {{1 }} = 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
我希望你能看到这是多么容易阅读。