包vhdl包含错误

时间:2015-09-04 15:47:29

标签: include package vhdl

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

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

有什么问题?

1 个答案:

答案 0 :(得分:1)

该工具抱怨,因为在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语句都在控制结构的控制之下,它会发出警告。他们这样做是因为他们不能证明函数总会返回,而函数总是会返回。我总是试图压制警告,以便任何剩余的警告都是有意义的,不可忽视。

将参数声明为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)是什么,只要它是至少有一点长。这是我喜欢的第三个原则:如果你做了一些通用的东西,那就让它真的泛型。