VHDL - 任何类型数组的函数/过程

PiC*_*CTo 5 vhdl

题:

如果可能的话,如何声明一个用于任何类型参数的函数,T其中唯一的约束T是它被定义为 1D,array

type T is array ( integer range <> ) of a_random_type;
Run Code Online (Sandbox Code Playgroud)

哪里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;
Run Code Online (Sandbox Code Playgroud)

然后可以用于任何 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);
Run Code Online (Sandbox Code Playgroud)

显然,这个问题是关于定义函数的方式,而不是关于函数本身:我不是在寻找a'length.


可能的解决方案:

来自Ashenden 的VHDL-2008:只是新东西

可以为子程序指定通用类型。

我们可以通过以下方式在泛型列表中声明正式的泛型类型

type indentifier
Run Code Online (Sandbox Code Playgroud)

具有通用列表的函数采用以下形式:

function indentifier
    generic   ( ... )
    parameter ( ... ) return result_type is
    ... -- declarations
begin
    ... -- statements
end function identifier
Run Code Online (Sandbox Code Playgroud)

这将允许以下定义

function measure_size_of_any_array
    generic   ( type arr_type )
    parameter ( arr : arr_type );
Run Code Online (Sandbox Code Playgroud)

和以下用途

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);
Run Code Online (Sandbox Code Playgroud)

这提供了在不同调用之间共享函数体的所需行为,无论 的元素的类型如何,array但仍然需要实例化的函数(它可以根据需要是本地的,所以它不是那么糟糕)。

由于主要供应商对 VHDL-2008 的支持很少(我尝试过的编译器无法理解以前的解决方案),因此首选 VHDL-87、-93 或 -2002 解决方案。

收到第一个答案后发表评论:

前面的信息是我试图找到一种编写 VHDL 子程序的方法,只要它是一个array回答最初的问题)就可以接受任何参数。预期的答案不一定应该使用相同的方法(即使用 VHDL-2008 通用子程序)!

JHB*_*ius 4

2008 年之前,仅允许在实体级别定义泛型。因此,您可以通过为该函数创建一个特殊实体来将泛型传递给该函数。例如

entity function_ent is
    generic(return_value : natural);
    port(output : out natural);
end entity;

architecture func_def of function_ent is
    function measure_size_of_any_array return natural is
    begin
        return return_value;
    end function;
begin
    output <= measure_size_of_any_array;
end architecture;
Run Code Online (Sandbox Code Playgroud)

但是,您希望将类型作为泛型参数传递...<2008 年这是不可能的。所以,你必须使用VHDL-2008。

但是,当在 VHDL 中使用泛型时,您始终必须将某个值(或在 vhdl-2008 中键入)映射到它们。没有智能(预)编译器能够像 C++ 那样自动检测输入类型。

当您最终决定使用 VHDL-2008 时,您可以问自己:“我会在先定义数组的情况下使用该函数吗?” 可能不会。因此,您可以使用通用(“模板化”)包作为与 C++ 类相当的东西。例子:

package array_pkg is
    generic (type element_type);

    type array_type is array (natural range <>) of element_type;

    function measure_size_of_array(
        arr : array_type) return natural;
end package;

package body array_pkg is
    function measure_size_of_array(
        arr : array_type) return natural is
    begin
        return arr'length;
    end function;
end package body;

entity test is
end entity test;

library ieee;

architecture beh of test is
    package natural_array_pkg is new work.array_pkg
        generic map (element_type => natural);

    signal test_sig1 : natural_array_pkg.array_type(0 to 10);
    constant test_out1 : natural := natural_array_pkg.measure_size_of_array(test_sig1);

    use ieee.std_logic_1164.all;

    package slv_array_pkg is new work.array_pkg
        generic map (element_type => std_logic_vector);

    signal test_sig2 : slv_array_pkg.array_type(0 to 12)(5 downto 0);
    constant test_out2 : natural := slv_array_pkg.measure_size_of_array(test_sig2);
begin

end architecture;
Run Code Online (Sandbox Code Playgroud)

我认为这是最接近当前 VHDL 中的模板化参数的。