问题描述
我有以下包,它定义了一个二维数组类型和一些返回初始化二维数组的随机函数。
-- <matrix.vhd>
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
package matrix is
type matrix is array(integer range<>,integer range<>) of std_logic;
function initmatrix(m: integer; n: integer) return matrix;
end package matrix;
package body matrix is
function initmatrix(m: integer; n: integer) return matrix is
variable a: matrix(m - 1 downto 0,n - 1 downto 0);
begin
for i in a'range(1) loop
for j in a'range(2) loop
if i = j then
a(i,j) := '1';
else
a(i,j) := '0';
end if;
end loop;
end loop;
return a;
end function initmatrix;
end package body matrix;
在下面的示例中,我尝试将函数 initmatrix 的返回值分配给一个信号。不过这有一些奇怪的行为。
-- <tb_test.vhd>
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use work.matrix.all;
entity tb_test is
end tb_test;
architecture x of tb_test is
signal m: matrix(3 downto 0,2 downto 0);
begin
process
variable t: matrix(3 downto 0,2 downto 0);
begin
m <= ("000","000","000");
wait for 10 ns;
-- This one does not work!
-- results in ("000",1UU","UUU","UUU")
m <= initmatrix(4,3);
wait for 10 ns;
-- This one does work!
-- exactly the same as the function body
for i in t'range(1) loop
for j in t'range(2) loop
if i = j then
t(i,j) := '1';
else
t(i,j) := '0';
end if;
end loop;
end loop;
m <= t;
wait;
end process;
end x;
相同的构造(将函数的返回值分配给信号)似乎只对多维数组失败。我一直在为任何其他类型这样做。
我是否忽略了什么?
我使用的是 Vivado 2020.2,除了 Vivado 内置的模拟器之外,没有尝试过任何其他模拟器。
解决方法
看来 Vivado 模拟器不喜欢将不受约束的多维数组作为函数的返回类型,至少对于 2008 年之前的 VHDL 版本而言是这样。
像这样的无约束单维数组或有约束多维数组都没有问题:
set_property FILE_TYPE {VHDL 2008} [get_files *.vhd]
为了使用 Vivado 正确模拟问题中的示例,需要将源文件的文件类型设置为 VHDL 2008。请注意,并非所有工具都可以完全处理 VHDL 2008,仍然不建议使用此如果您希望代码可移植。
在 Vivado 中将(所有)源文件设置为 VHDL 2008 是通过
{{1}}