首页 文章

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

提问于
浏览
3

问题:

如果可能的话,如何声明一个用于任何类型 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 回答

  • 1

    在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;
    

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

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

    当你最终决定使用VHDL-2008时,你可以问自己:“我会先使用这个函数而不先定义一个数组吗?" Likely not. So you might use a generic ("模板化”)包可以作为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;
    

    我认为这是您在当前VHDL中最接近模板化参数的方法 .

  • 3

    在VHDL-2008中,泛型类型的实现非常少 . 我已经写了几页LRM更改,以便在VHDL-2017中获得更好的通用类型 . 新标准将在几个月内投入使用 .

    更改集在LCS-2016-059中指定 .

    function foo
      generic (
        type array_type is array(type is (<>)) of type is private
      )
      parameter (
        input    : array_type;
        selected : array_type'index
      )
      return array_type'element is
    begin
      return input(selected);
    end function;
    

相关问题