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;
请帮帮我,谢谢:)
答案 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