问题:
如果可能的话,如何声明一个用于任何类型 T
的参数的函数,其中 T
的唯一约束是它被定义为1D array
,如在
type T is array ( integer range <> ) of a_random_type;
其中 a_random_type
可以是任何 type
.
以下语法上不正确的函数是所需内容的一个示例
function measure_size_of_any_array ( a : array ( integer range <> ) ) return natural is
variable r : natural := 0;
begin
for i in a'range loop
r := r + 1;
end loop;
return r;
end function;
然后可以在任何 array
上使用
type natural_array is array ( integer range <> ) of natural;
type stdlogv_array is array ( integer range <> ) of std_logic_vector;
[...]
variable some_natural_array : natural_array;
variable some_stdlogv_array : stdlogv_array;
[...]
constant size_1 : natural := measure_size_of_any_array(some_natural_array);
constant size_2 : natural := measure_size_of_any_array(some_stdlogv_array);
显然,这个问题是关于定义函数的方式而不是关于函数本身:我不是在寻找 a'length
.
可能的解决方案:
来自Ashenden's VHDL-2008: Just the New Stuff
可以为子程序指定通用类型 . 我们可以通过以下方式在泛型列表中声明一个正式的泛型类型:type indentifier具有泛型列表的函数采用以下形式:function identityntifier
通用(...)
参数(...)返回result_type是
...... - 声明
开始
...... - 陈述
结束功能标识符
这将允许以下定义
function measure_size_of_any_array
generic ( type arr_type )
parameter ( arr : arr_type );
以及使用
function measure_size_of_natural_array is new measure_size_of_any_array
generic ( arr_type => natural_array );
function measure_size_of_stdlogv_array is new measure_size_of_any_array
generic ( arr_type => stdlogv_array );
constant size_1 : natural := measure_size_of_natural_array(some_natural_array);
constant size_2 : natural := measure_size_of_stdlogv_array(some_stdlogv_array);
这提供了在不同调用之间共享函数体的期望行为,无论 array
的元素的类型如何,但仍然需要实例化的函数(可以根据需要进行本地化,因此它不是那么糟糕) .
由于主要供应商对VHDL-2008提供的支持很少(我尝试过的编译器无法理解以前的解决方案),因此首选VHDL-87,-93或-2002解决方案 .
收到第一个答案后的评论:
以前的信息是我尝试找到一种编写接受任何参数的VHDL子程序的方法,只要它是 array
(即回答初始问题) . 预期的答案不一定要使用相同的方法(即使用VHDL-2008通用子程序)!
2 回答
在2008年之前,只允许在实体层面定义泛型 . 因此,您可以通过为该函数创建一个特殊实体来将泛型传递给函数 . 例如 .
但是,您希望将类型作为通用参数传递...这是不可能的<2008 . 所以,你必须使用VHDL-2008 .
但是当在VHDL中使用泛型时,您将始终必须将特定值(或在vhdl-2008中键入)映射到它们 . 没有智能(预)编译器会自动检测输入类型,就像在C中一样 .
当你最终决定使用VHDL-2008时,你可以问自己:“我会先使用这个函数而不先定义一个数组吗?" Likely not. So you might use a generic ("模板化”)包可以作为C类的东西 . 例:
我认为这是您在当前VHDL中最接近模板化参数的方法 .
在VHDL-2008中,泛型类型的实现非常少 . 我已经写了几页LRM更改,以便在VHDL-2017中获得更好的通用类型 . 新标准将在几个月内投入使用 .
更改集在LCS-2016-059中指定 .