2015-09-04 155 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

是的。就像大多數編程語言一樣。編譯依賴項之前的依賴項。 –