我的函数没有返回值,我不明白为什么? VHDL

时间:2014-09-07 11:15:52

标签: vhdl

VHDL中的部分代码。工作区ISE。 我的函数没有返回值,我不明白为什么 请注意,我在ISE中看到的是“函数'con_integer14'并不总是返回值。”

功能是:

function con_integer14 (vNumberSTD : std_logic_vector(14 downto 0)) return integer is   
    variable vCounter        : integer range 0 to 16 := 0;      
    variable vNumberINT      : integer range 0 to 16384 := 0; 

begin

    if (vCounter = 0) then

        if ((vNumberSTD(vCounter)) = '1') then 

           vNumberINT := (vNumberINT+(2**vCounter));
        elsif ((vNumberSTD(vCounter)) = '0') then 
            vNumberINT := vNumberINT;
        end if;
        vCounter := (vCounter+1);

    elsif ((vCounter >= 1)or(vCounter < 14)) then 
        if ((vNumberSTD(vCounter)) = '1') then 
            vNumberINT := (vNumberINT+(2**vCounter));
        elsif ((vNumberSTD(vCounter)) = '0') then 
            vNumberINT := vNumberINT;
        end if;
        vCounter := (vCounter+1);

    elsif (vCounter = 14) then 
        if ((vNumberSTD(vCounter)) = '1') then 
            vNumberINT := (vNumberINT+(2**vCounter));
        elsif ((vNumberSTD(vCounter)) = '0') then 
            vNumberINT := vNumberINT;
        end if;
        vCounter := (vCounter+1);

    elsif (vCounter = 15) then  
        return vNumberINT;
        vCounter := 0;

    elsif (vCounter > 15) then  
        vNumberINT := 0;
        vCounter   := 0;    

    end if;

end function con_integer14;

请帮帮我,谢谢:)

3 个答案:

答案 0 :(得分:1)

我会更进一步告诉你,你的功能 从不 会返回一个值。我冒昧地删除了多余的括号,然后查看了函数的结构。

您将执行第一个if语句并且无法返回值 - 没有返回语句。

添加测试台:

library ieee;
use ieee.std_logic_1164.all;
use work.foo.all;

entity fum is
end entity;

architecture fie of fum is
    signal vNumberINT:  integer range 0 to 16384;
    signal vNumberSTD: std_logic_vector(14 downto 0) := "011001110111100";
begin
CALL:
    process
    begin
        wait for 1 ns;
        vNumberINT <= con_integer14(VNumberSTD);
        wait for 1 ns;
        wait;
    end process;
end architecture;

分析它,详细说明并运行它:

  

ghdl -a something.vhdl
  david_koontz @ Macbook:ghdl -e fum
  david_koontz @ Macbook:ghdl -r fum
  ./fum:error:缺少回归   功能在something.vhdl:10
  ./fum:error:模拟失败了   ghdl:编译错误

我们告诉我们第一个if语句的返回缺失,对它的调用不会返回值。

要创建将std_logic_vector转换为整数的转换例程,您应该使用带有基于输入vNumberSTD的索引范围的迭代方案的循环语句。

当循环语句完成时'计算'vNumberINT返回VNumberINT。

请注意,如果您没有对vNumberSTD元素的元值进行任何具体操作,则会将其视为“0”。

经过一些修改:

library ieee;
use ieee.std_logic_1164.all;

package foo is
     function con_integer14 (vNumberSTD: std_logic_vector(14 downto 0)) return integer;
     function conv_slv_int (input:  std_logic_vector) return natural;
end package;

package body foo is

    function con_integer14 (vNumberSTD : std_logic_vector(14 downto 0)) return integer is   
        -- variable vCounter:   integer range 0 to 16 := 0;
        -- variable vNumberINT: integer range 0 to 16384 := 0;
        variable vNumberINT: integer range 0 to 32767 := 0;
    begin
        -- if vCounter = 0 then
        --     if vNumberSTD(vCounter) = '1' then
        --        vNumberINT := vNumberINT + 2 ** vCounter;
        --     elsif vNumberSTD(vCounter) = '0' then
        --         vNumberINT := vNumberINT;
        --     end if;
        --     vCounter := vCounter + 1;
        -- elsif vCounter >= 1 or vCounter < 14  then
        --     if vNumberSTD(vCounter) = '1' then
        --         vNumberINT := vNumberINT + 2 ** vCounter;
        --     elsif vNumberSTD(vCounter) = '0' then
        --         vNumberINT := vNumberINT;
        --     end if;
        --     vCounter := vCounter + 1;
        -- elsif  vCounter = 14 then
        --     if vNumberSTD(vCounter) = '1' then
        --         vNumberINT := vNumberINT + 2 ** vCounter;
        --     elsif vNumberSTD(vCounter) = '0' then
        --         vNumberINT := vNumberINT;
        --     end if;
        --     vCounter := vCounter + 1;
        -- elsif vCounter = 15 then
        --     return vNumberINT;
        --     vCounter := 0;
        -- elsif vCounter > 15 then
        --     vNumberINT := 0;
        --     vCounter   := 0;
        -- end if;
        for i in vNumberSTD'range loop
            report "vNumberSTD(" & integer'image(i) & ") = " & std_ulogic'image(vNumberSTD(i));
            if vNumberSTD(i) = '1' then
                vNumberINT := vNumberINT + 2 ** i;
                report "vNumberINT = " & integer'image(vNumberINT);
            end if;
        end loop;
        return vNumberINT;
    end function con_integer14;

    function conv_slv_int (input:  std_logic_vector) return natural is
        alias inp: std_logic_vector (input'LENGTH - 1 downto 0) is input;
        variable int_equiv: natural range 0 to 2 ** input'LENGTH - 1  := 0;
        begin
            if Is_X(input) then  -- announce meta values - interpreted as '0's
                report "conv_slv_int input contains meta value";
            end if;
            for i in inp'RANGE loop
                if To_bit(inp(i)) = '1' then -- convert 'H' to '1', 'L' to '0'
                    int_equiv := int_equiv + 2 ** i;
                end if;
            end loop;
            return int_equiv;
        end function;
end package body;

library ieee;
use ieee.std_logic_1164.all;
use work.foo.all;

entity fum is
end entity;

architecture fie of fum is
    signal vNumberINT:  integer range 0 to 32767;
    signal vNumberSTD: std_logic_vector(14 downto 0) := "HX1001110111100";
begin
CALL:
    process
    begin
        wait for 1 ns;
        vNumberINT <= con_integer14(VNumberSTD);
        wait for 1 ns;
        report "vNumberINT = " &integer'image(vNumberINT);
        report "conv_slv_int returns " & integer'image(conv_slv_int(vNumberSTD));
        wait;
    end process;
end architecture;

注意我更正了vNumberINT的范围,它可以基于函数con_integer14的参数。

您可以删除该功能中的报表语句。我用它们来说明函数循环。

我添加了第二个函数,显示了适合自然范围的任何长度std_logic_vector的转换。如果输入的长度不适合整数,则在调用(函数局部变量详细说明)时会产生错误。

第二个函数还检测元值输入,并为输入的每个元素将“H”转换为“1”,将“L”转换为“0”。

使用别名inp进行输入可以让我们始终将输入作为自然范围处理,关注长度而不是左右边界。

运行新的测试平台时:

  

something.vhdl:45:13:@ 1ns :(报告单):vNumberSTD(14)='H'
  something.vhdl:45:13:@ 1ns :(报告单):vNumberSTD(13)='X'
  something.vhdl:45:13:@ 1ns :(报告说明):vNumberSTD(12)='1'
  something.vhdl:48:17:@ 1ns :(报告说明):vNumberINT = 4096
  something.vhdl:45:13:@ 1ns :(报告单):vNumberSTD(11)='0'
  something.vhdl:45:13:@ 1ns :(报告单):vNumberSTD(10)='0'
  something.vhdl:45:13:@ 1ns :(报告单):vNumberSTD(9)='1'
  something.vhdl:48:17:@ 1ns :(报告说明):vNumberINT = 4608
  something.vhdl:45:13:@ 1ns :(报告单):vNumberSTD(8)='1'
  something.vhdl:48:17:@ 1ns :(报告说明):vNumberINT = 4864
  something.vhdl:45:13:@ 1ns :(报告单):vNumberSTD(7)='1'
  something.vhdl:48:17:@ 1ns :(报告说明):vNumberINT = 4992
  something.vhdl:45:13:@ 1ns :(报告说明):vNumberSTD(6)='0'
  something.vhdl:45:13:@ 1ns :(报告单):vNumberSTD(5)='1'
  something.vhdl:48:17:@ 1ns :(报告说明):vNumberINT = 5024
  something.vhdl:45:13:@ 1ns :(报告单):vNumberSTD(4)='1'
  something.vhdl:48:17:@ 1ns :(报告说明):vNumberINT = 5040
  something.vhdl:45:13:@ 1ns :(报告单):vNumberSTD(3)='1'
  something.vhdl:48:17:@ 1ns :(报告说明):vNumberINT = 5048
  something.vhdl:45:13:@ 1ns :(报告说明):vNumberSTD(2)='1'
  something.vhdl:48:17:@ 1ns :(报告说明):vNumberINT = 5052
  something.vhdl:45:13:@ 1ns :(报告单):vNumberSTD(1)='0'
  something.vhdl:45:13:@ 1ns :(报告单):vNumberSTD(0)='0'
  something.vhdl:87:9:@ 2ns :(报告单):vNumberINT = 5052
  something.vhdl:59:17:@ 2ns :(报告说明):conv_slv_int输入包含元值
  something.vhdl:88:9:@ 2ns :(报告说明):conv_slv_int返回21436

我们看到您可以将std_logic_vector传递给只有conv_slt_int才能正确解释的内容。

答案 1 :(得分:0)

节省一些时间并使用内置功能。如果您只使用numeric_std,则可以执行以下操作:

library IEEE ; 
use IEEE.numeric_std.all ; 
...
signal Y_int : integer ; 
signal A_slv15 : std_logic_vector(14 downto 0) ;
...
Y_int <= to_integer( unsigned( A_slv15) ) ; 

如果你还包括numeric_std_unsigned(警告这是VHDL-2008,你的工具可能还不支持 - 尝试并报告错误,如果它不起作用) -

library IEEE ; 
use IEEE.numeric_std.all ; 
use IEEE.numeric_std_unsigned.all ; 
...
signal Y_int : integer ; 
signal A_slv15 : std_logic_vector(14 downto 0) ;
...
Y_int <= to_integer( A_slv15)  ; 

答案 2 :(得分:0)

就像已经提到的那样,你没有涵盖所有可能的条件。通过使用“else”子句或在if-elsif语句之前有一个默认值来拥有默认赋值总是好的:

function con_integer14 (...) return integer is
begin
    vNumberINT := -1;
    if (vCounter = 0) then ...
    elsif ...
    elsif ... then return vNumberINT;
    end if;

    return vNumberINT;
end function con_integer14;

或者,

function con_integer14 (...) return integer is
begin
    if (vCounter = 0) then ...
    elsif ...
    elsif ... then return vNumberINT;
    else
        return vNumberINT;
    end if;
end function con_integer14;

我个人更喜欢第一个选项,因为有些工具仍抱怨第二个选项并未覆盖所有路径,但实际上所有路径都已涵盖。无论如何,这只是风格问题。

在我看来,你只是在vCounter = 15时返回一个值:

elsif (vCounter = 15) then return vNumberINT; ...

并且您的测试平台并不总能满足这一条件(可能从未被David分析过。)

-daniel