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

时间:2017-04-10 13:44:29

标签: vhdl

问题:

如果可能的话,如何声明一个用于任何类型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 indentifier
    generic   ( ... )
    parameter ( ... ) return result_type is
    ... -- declarations
begin
    ... -- statements
end function identifier

允许以下定义

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的元素类型如何,但仍需要实例化函数(可以根据需要使用本地函数,因此它不是#39;那很糟糕。)

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

收到第一个答案后的评论:

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

2 个答案:

答案 0 :(得分:3)

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

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;

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

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

当您最终决定使用VHDL-2008时,您可以问自己:&#34;我是否会使用函数而不用首先定义数组?&#34;可能不是。因此,您可以使用通用(&#34;模板化&#34;)包作为与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中最接近模板参数的地方。

答案 1 :(得分:1)

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;