【问题标题】:VHDL - Function/Procedure for any type of arrayVHDL - 任何类型数组的函数/过程
【发布时间】:2017-04-10 13:44:28
【问题描述】:

问题:

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

type T is array ( integer range &lt;&gt; ) of <i>a_random_type</i>;

其中<i>a_random_type</i> 可以是任何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 <i>indentifier</i>

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

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 的元素类型如何,但仍然需要实例化函数(可以根据需要在本地,所以它不是太糟糕了)。

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

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

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

【问题讨论】:

  • 顺便说一句,如果您添加一些 minimal complete verifiable example 代码而不是伪代码,这个问题会更好。
  • @J.H.Bonarius 当我的问题基本上是“我如何用 VHDL 表达这个?”时,我怎么能写这样一个例子?因此,如果我能够写出您要求的示例,那么这个问题就不存在了。
  • 一个有趣的问题。如果没有 VHDL-2008,我认为您不会找到答案。

标签: vhdl


【解决方案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;

但是,您希望将 type 作为通用参数传递...这是不可能的 必须使用 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;

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

【讨论】:

  • 很抱歉,这如何回答我的问题?您的示例中没有形式参数(或等效参数)。我想这些应该输入ports,但问题是完全一样的:你如何定义这些端口来接受signal类型的array of [...]
  • @PiCTo 在您的问题中声明您已经有了解决方案。您要问的是是否有 VHDL
  • 请原谅。我意识到我通过专注于代码误读了您的答案。您的回答确实是“不,在
  • 我没有刷新,只是看到你的更新;您要添加的示例确实已经很优雅了。太糟糕了,在
【解决方案2】:

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

【讨论】:

  • 这很有趣,但没有回答我的问题,因为它甚至不是 VHDL 的一部分(截至目前)。此外,正如我所说,我更喜欢 2008 年前的解决方案,但我必须说我并不期待 VHDL-2017 中的解决方案!我很确定我的问题的答案是这是不可能的,但我仍然希望有一个不错的 hack。出于好奇,这仍然需要实例化还是可以称为foo(T)(in, sel)
  • 我想表达的是:a) 现在(2008 年)不可能,因为他们在 2008 年将泛型类型的想法剥离到了最低限度(不可用)。b)它永远不会适用
  • 另一个 LCS 直接在调用中处理通用子程序的直接实例化。该语法需要“泛型映射”关键字,否则您无法区分带有/不带有泛型/参数的重载:)。
  • @PiCTo 人们给了你很好的答案,你似乎很生气,因为他们不是你想要的答案。但是你想要的是不可能的。请善待愿意免费帮助您的人。
  • @PiCTo 是的 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多