2015-09-04 120 views
0

嗨,大家好,我有以下包装,由我自己定义的包装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

确保你在'ldz.vhd'之前编译了软件包,并确保通过添加'-work work'将你的软件包编译到工作库中。 – 0xMB

+0

您的log2c功能不正确。例如:n = 5d = 101b。它迭代2次并将ret_val递增为2,但log2ceil(5)不是2,它是3. – Paebbels

+0

如果x大于1位,则此循环'for i in x'high to 0 loop' has a empty range。 – Paebbels

回答

1

该工具的抱怨是因为在ldz之前未对包进行分析(编译)。先编译它,然后ldz

正如在评论中提到的,你的代码会遇到几个问题。下面的代码计算一个正的log 2,朝向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变量可以避免,但它有助于避免某些工具的警告,如果函数的返回语句全部受控于控制结构,则会警告您。他们这样做是因为他们无法证明函数总是返回而函数总是返回。我总是试图压制警告,使得任何剩余的警告都是有意义的,不能被忽略。

声明参数为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)。这是我喜欢的第三个原则:如果你做出一些通用的,使它真的通用。

+0

所以我必须首先使用ncvhdl包?然后对我的设计也一样? – user8469759

+0

是的。就像大多数编程语言一样。编译依赖项之前的依赖项。 –