包 vhdl 包含错误

Package vhdl inclusion error

大家好,我有以下包,我自己定义的

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_misc.all;

package util_pkg is
    function log2c(n : natural) return natural;
end package util_pkg;

package body util_pkg is
    function log2c(n : natural) return natural is
        variable temp    : natural := n;
            variable ret_val : natural := 0;
    begin
        while temp > 1 loop
            ret_val := ret_val + 1;
            temp = temp/2;
        end loop;       
        return ret_val;
    end function log2c;
end package body util_pkg;

而我的设计是

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_misc.all;
use work.util_pkg.all;

entity ldz is
    generic(n : natural); --i can assume n > 1
    port(x : in std_logic_vector(n - 1 downto 0);
         y : out std_logic_vector(log2c(n) - 1 downto 0));
end entity ldz;

-- Example

architecture ldz_arch of ldz is

    function ldz_count(x : unsigned) return natural is
        n_ldz : natural := 0;
    begin

        for i in x'high to 0 loop
            if(x(i) = '1') then
                return x'length - i - 1;
            end if;
        end loop;
        return x'length - 1;
    end function ldz_count;
begin
    y <= std_logic_vector(to_unsigned(ldz_count(to_unsigned(x)));
end architecture ldz_arch;

当我尝试使用 ncvhdl 验证语法时,这是我得到的错误

unit (UTIL_PKG) not found in library (WORKLIB)

然而这样的单元(包)在设计的同一个库中。 文件是 util_pkg.vhd 而设计是 ldz.vhd

怎么了?

工具报错是因为包在 ldz 之前没有被分析(编译)。先编译然后 ldz 接下来

如评论中所述,您的代码存在多个问题。以下代码计算正数的 log2,向 0 或无穷大四舍五入:

function log2_down(n: positive) is
  variable res: natural := 0;
begin
  if n /= 1 then
    res := 1 + log2_down(n / 2);
  end if;
  return res;
end function log2_down;

function log2_up(n: positive) is
  variable res: natural := 0;
begin
  if n /= 1 then
    res := 1 + log2_up((n + 1) / 2);
  end if;
  return res;
end function log2_up;

是的,VHDL 也支持递归和大多数合成器,至少在迭代次数可静态计算时是这样。

res 变量可以避免,但它有助于避免某些工具的警告,如果函数的 return 语句都在控制结构的控制下,这些工具会警告您。他们这样做是因为他们无法证明函数将始终 return 而函数将始终 return。我总是试图抑制警告,以便任何剩余的警告都有意义并且不能被忽略。

将参数声明为positive是处理log2(0)错误的简单方法。我总是尝试使用语言的内置功能来处理错误。

使用相同的两个原则(没有警告,让语言的内置功能处理错误),您的前导零计数器 ldz_count 函数可以写成:

function ldz_count(x: unsigned) return natural is
  constant n: positive := x'length;
  constant v: unsigned(0 to n - 1) := x;
  variable res: natural := n;
begin
    for i in 0 to n - 1 loop
      if v(i) = '1' then
        res := i;
      end if;
  end if;
  return res;
end function ldz_count;       

复制具有选定位索引的 x 参数将使您的函数可用于任何 x 参数,无论其声明(7 to 359 downto 4)只要它至少有点长。这是我喜欢的第三个原则:如果你做一些通用的东西,让它真正通用。