未调用 vhdl 函数

vhdl function is not being called

我写过类似这样的 vhdl 代码

entity myentity is
 port( number : in integer range 0 to 15; result : out integer);
 function myfunction(num: integer range 0 to 15) return integer is
 variable i: integer :=1;
 variable error1, error2, error, temp, concat: integer;
 variable res: integer;
 begin
  if (num<=1)then
   res := num;
  else 
   while (2**i < num) loop
    i:=i+1;
   end loop;
   error2 := num-(2**i); 
   error1 := num-(2**(i-1));
   if abs(error1)<error2 then
    error := error1;
   else error := error2;
   end if;
   if error=0 then
   res := to_integer(to_unsigned(num,8) sll i);
   else 
   temp := num-error;
   concat := myfunction(temp);
   res :=to_integer(to_unsigned(temp,4) & to_unsigned(concat,i-1));
   end if;
  end if;
 return res;
end myfunction;
end myentity;

architecture Behavioral of myentity is
begin
 result<=myfunction(number);
end Behavioral;

函数是递归的。问题是,架构体没有调用函数。即,功能线没有被执行。当我编译程序时,它没有显示错误。有什么帮助吗? 我将示例更改为原始代码。

使用您的新问题代码格式化以提高可读性,添加报告语句以进行调试,并添加测试平台以驱动数字的所有可能整数值(0 到 15),创建 Minimal, Complete and Verifiable example:

library ieee;             -- CONTEXT CLAUSE ADDED
use ieee.numeric_std.all; -- unsigned, to_unsigned, to_integer, sll
 -- superfluous parentheses removed, indentation added  for clarity:
entity myentity is
    port (
        number:  in  integer range 0 to 15; 
        result:  out integer
    );

    function myfunction (num: integer range 0 to 15) return integer is
        variable i: integer := 1;
        variable error1, error2, error, temp, concat: integer;
        variable res: integer;
    begin
        if num <= 1 then  -- CONDITION COULD BE num = 0
            res := num;
            report "num = " & integer'image(num);        -- ADDED REPORT
        else
            while 2 ** i < num loop
                i := i + 1;
            end loop;
            report "i = " & integer'image(i);            -- ADDED REPORT
            error2 := num - 2 ** i; 
            report "error2 = " & integer'image(error2);  -- ADDED REPORT
            error1 := num - 2 ** (i - 1);
            report "error1 = " & integer'image(error1);  -- ADDED REPORT
            if abs error1 < error2 then
                error := error1;
            else
                error := error2;
            end if;
            report "error = " & integer'image(error);    -- ADDED REPORT
            if error = 0 then
                res := to_integer(to_unsigned(num, 8) sll i);
                report "res = " & integer'image(res);    -- ADDED REPORT
            else
                temp := num - error;
                report "temp = " & integer'image(temp);  -- ADDED REPORT
                concat := myfunction(temp);
                report "concat = " & integer'image(concat); -- ADDED REPORT
                res := to_integer(to_unsigned(temp, 4) & 
                       to_unsigned(concat, i - 1) );
                report "res = " & integer'image(res);    -- ADDED REPORT
            end if;
        end if;
        return res;
    end myfunction;
end entity myentity;

architecture behavioral of myentity is
begin
    result <= myfunction(number);
end architecture behavioral;

entity myentity_tb is
end entity;

architecture foo of myentity_tb is
    signal result: integer;
    signal number: integer range 0 to 15;
begin

DUT:
    entity work.myentity 
        port map (
            number => number,
            result => result
        );
STIMULI:
    process
    begin
        for i in 0 to 15 loop
            number <= i;
            report "number = " & integer'image(i);
            wait for 10 ns;
        end loop;
        wait;
    end process;
end architecture;

分析代码,详细说明并运行 测试台生成 VHDL 实现相关的报告语句格式:

myentity.vhdl:17:13:@0ms:(report note): num = 0
myentity.vhdl:74:13:@0ms:(report note): number = 0
myentity.vhdl:74:13:@10ns:(report note): number = 1
myentity.vhdl:17:13:@10ns:(report note): num = 1
myentity.vhdl:74:13:@20ns:(report note): number = 2
myentity.vhdl:22:13:@20ns:(report note): i = 1
myentity.vhdl:24:13:@20ns:(report note): error2 = 0
myentity.vhdl:26:13:@20ns:(report note): error1 = 1
myentity.vhdl:32:13:@20ns:(report note): error = 0
myentity.vhdl:35:17:@20ns:(report note): res = 4
myentity.vhdl:74:13:@30ns:(report note): number = 3
myentity.vhdl:22:13:@30ns:(report note): i = 2
myentity.vhdl:24:13:@30ns:(report note): error2 = -1
myentity.vhdl:26:13:@30ns:(report note): error1 = 1
myentity.vhdl:32:13:@30ns:(report note): error = -1
myentity.vhdl:38:17:@30ns:(report note): temp = 4
myentity.vhdl:22:13:@30ns:(report note): i = 2
myentity.vhdl:24:13:@30ns:(report note): error2 = 0
myentity.vhdl:26:13:@30ns:(report note): error1 = 2
myentity.vhdl:32:13:@30ns:(report note): error = 0
myentity.vhdl:35:17:@30ns:(report note): res = 16
myentity.vhdl:40:17:@30ns:(report note): concat = 16
../../src/ieee/numeric_std-body.v93:2151:7:@30ns:(assertion warning): NUMERIC_STD.TO_UNSIGNED: vector truncated
myentity.vhdl:43:17:@30ns:(report note): res = 8
myentity.vhdl:74:13:@40ns:(report note): number = 4
myentity.vhdl:22:13:@40ns:(report note): i = 2
myentity.vhdl:24:13:@40ns:(report note): error2 = 0
myentity.vhdl:26:13:@40ns:(report note): error1 = 2
myentity.vhdl:32:13:@40ns:(report note): error = 0
myentity.vhdl:35:17:@40ns:(report note): res = 16
myentity.vhdl:74:13:@50ns:(report note): number = 5
myentity.vhdl:22:13:@50ns:(report note): i = 3
myentity.vhdl:24:13:@50ns:(report note): error2 = -3
myentity.vhdl:26:13:@50ns:(report note): error1 = 1
myentity.vhdl:32:13:@50ns:(report note): error = -3
myentity.vhdl:38:17:@50ns:(report note): temp = 8
myentity.vhdl:22:13:@50ns:(report note): i = 3
myentity.vhdl:24:13:@50ns:(report note): error2 = 0
myentity.vhdl:26:13:@50ns:(report note): error1 = 4
myentity.vhdl:32:13:@50ns:(report note): error = 0
myentity.vhdl:35:17:@50ns:(report note): res = 64
myentity.vhdl:40:17:@50ns:(report note): concat = 64
../../src/ieee/numeric_std-body.v93:2151:7:@50ns:(assertion warning): NUMERIC_STD.TO_UNSIGNED: vector truncated
myentity.vhdl:43:17:@50ns:(report note): res = 32
myentity.vhdl:74:13:@60ns:(report note): number = 6
myentity.vhdl:22:13:@60ns:(report note): i = 3
myentity.vhdl:24:13:@60ns:(report note): error2 = -2
myentity.vhdl:26:13:@60ns:(report note): error1 = 2
myentity.vhdl:32:13:@60ns:(report note): error = -2
myentity.vhdl:38:17:@60ns:(report note): temp = 8
myentity.vhdl:22:13:@60ns:(report note): i = 3
myentity.vhdl:24:13:@60ns:(report note): error2 = 0
myentity.vhdl:26:13:@60ns:(report note): error1 = 4
myentity.vhdl:32:13:@60ns:(report note): error = 0
myentity.vhdl:35:17:@60ns:(report note): res = 64
myentity.vhdl:40:17:@60ns:(report note): concat = 64
../../src/ieee/numeric_std-body.v93:2151:7:@60ns:(assertion warning): NUMERIC_STD.TO_UNSIGNED: vector truncated
myentity.vhdl:43:17:@60ns:(report note): res = 32
myentity.vhdl:74:13:@70ns:(report note): number = 7
myentity.vhdl:22:13:@70ns:(report note): i = 3
myentity.vhdl:24:13:@70ns:(report note): error2 = -1
myentity.vhdl:26:13:@70ns:(report note): error1 = 3
myentity.vhdl:32:13:@70ns:(report note): error = -1
myentity.vhdl:38:17:@70ns:(report note): temp = 8
myentity.vhdl:22:13:@70ns:(report note): i = 3
myentity.vhdl:24:13:@70ns:(report note): error2 = 0
myentity.vhdl:26:13:@70ns:(report note): error1 = 4
myentity.vhdl:32:13:@70ns:(report note): error = 0
myentity.vhdl:35:17:@70ns:(report note): res = 64
myentity.vhdl:40:17:@70ns:(report note): concat = 64
../../src/ieee/numeric_std-body.v93:2151:7:@70ns:(assertion warning): NUMERIC_STD.TO_UNSIGNED: vector truncated
myentity.vhdl:43:17:@70ns:(report note): res = 32
myentity.vhdl:74:13:@80ns:(report note): number = 8
myentity.vhdl:22:13:@80ns:(report note): i = 3
myentity.vhdl:24:13:@80ns:(report note): error2 = 0
myentity.vhdl:26:13:@80ns:(report note): error1 = 4
myentity.vhdl:32:13:@80ns:(report note): error = 0
myentity.vhdl:35:17:@80ns:(report note): res = 64
myentity.vhdl:74:13:@90ns:(report note): number = 9
myentity.vhdl:22:13:@90ns:(report note): i = 4
myentity.vhdl:24:13:@90ns:(report note): error2 = -7
myentity.vhdl:26:13:@90ns:(report note): error1 = 1
myentity.vhdl:32:13:@90ns:(report note): error = -7
myentity.vhdl:38:17:@90ns:(report note): temp = 16
./myentity_tb:error: bound check failure at myentity.vhdl:39
./myentity_tb:error: simulation failed

我们可以看到为 0 分配给结果的函数 returns 0。这解释了为什么没有通过刺激(这里是测试台,设计层次结构中的更高级别)在数字上驱动不同的值(1 到 15)为什么结果为 0 并且不产生错误。 (请注意,如果没有对结果进行赋值,它的值将是该类型的最小值 INTEGER'LOW,结果没有子类型约束并且从结果的端口声明中的类型标记继承它的子类型)。

有两条 类 的消息在输出中引起对数值 1 到 15 的关注。

第一个是来自包 numeric_std 的报告消息,告诉您您从二进制数中剪切了左边的元素,最终转换为整数并分配给了 res。这表示需要解决的算法不准确。您可以注意到,当发生这种情况时,res(在并发信号赋值语句中赋值)为 64。

第二个是当 number 被赋值 9 并且传递给递归调用 myfunction 的值超出它的参数 num 范围(0 到 15,变量 temp 的值 16)时的错误消息。越界错误足以导致模拟停止,模拟​​的完整性受到损害。 (这就是强类型为您所做的,应该选择参数 num 的子类型是为了实现 myfunction)。

当您的算法运行令人满意时,您可以轻松删除为调试而添加的每个报告语句,之后您可以再次测试。

注意数字的值可以通过它们在模拟过程中发生的时间来区分。

这个答案说明了为什么您的代码没有报告错误,并说明了如何判断它正在做什么以允许调试其他数字值。

我们可以看到第一个报告语句的存在,函数 myfunction 被调用。此外,如果未分配结果,则其默认值为负数。