如何在VHDL中将整数数组指定为通用类型?

6
我希望为基于SPI的IO扩展器创建通用驱动程序。想法是在实例化中传递初始化值,以匹配所请求的IO设置。
我的当前尝试看起来像这样:
entity max7301_simple is
   generic ( 
        IO_cfg : array (1 to 7) OF integer range 0 to 255 := (16#55#, 16#55#, 16#55#, 16#55#, 16#55#, 16#55#, 16#55#)
           );
     port  (
        -- Application interface :
        clk_i       :   in std_logic;        -- input clock, xx MHz.
        rst_i       :   in std_logic;        -- sync reset.
        en_i        :   in std_logic;        -- enable, forces re-init of pins on MAX7301.
        output_i    :   in std_logic_vector(27 downto 0);   --data to write to output pins on MAX7301
        irq_o       :   out std_logic;       -- IRQ, TODO: what triggers, change on inputs ?
        input_o     :   out std_logic_vector(27 downto 0);  --data read from input pins on MAX7301
        -- MAX7301 SPI interface
        sclk        :   out std_logic;        -- SPI clock
        din         :   in std_logic;        -- SPI data input
        dout        :   out std_logic;       -- SPI read data
        cs          :   out std_logic        -- SPI chip select
    );
end max7301_simple;

问题出在IO_cfg数组上,我尝试过多种不同的方式(如使用/不使用初始值等),但似乎无法确定如何指定数组。
我相信读到过可以将数组作为通用类型传递,但是一直没有得到很好的运行结果。Xilinx ISE只告诉我“语法错误:'array'附近”,这并不足以让我有所进展。
如果能提供任何帮助将不胜感激。
在实例化此模块时,我总是需要7个值。
3个回答

8
你可以将数组作为泛型参数使用,但是不允许在那里即时声明一个匿名类型。
你需要先在单独的包中声明整数数组类型(可以在同一个文件中或在另一个文件中),然后在实体中使用该包并在实例化时使用它。
以下是如何操作的示例:
-- package declaration
package mytypes_pkg is

     type my_array_t is array (1 to 7) of integer range 0 to 255;

end package mytypes_pkg;

-- entity "uses" the package   
use work.mytypes_pkg.all;

entity max7301_simple is
   generic ( 
        IO_cfg : my_array_t := (16#55#, 16#55#, 16#55#, 16#55#, 16#55#, 16#55#, 16#55#)
           );
   -- ports [...]
end max7301_simple;

请注意在实例化实体的架构中也要使用该包。


(可选阅读)

为什么像您那样写真的是一个语法错误?

查看VHDL(2002)标准中的VHDL语法,每个通用参数的声明都是一个interface_constant_declaration,您有以下语法规则:

4.3.2]
interface_constant_declaration ::=  
            [ constant ] identifier_list : [ in ] subtype_indication [ := static_expression ]

[§ 4.2]
subtype_indication ::= 
            [ resolution_function_name ] type_mark [ constraint ]

类型引用只能是现有类型的名称(type_mark)或现有类型的限制。

5
我建议采用更加通用的方法,使用 2008 VHDL 标准和预定义属性 - 这样可以 传递任意长度的数组。 在您的包中定义类型,如下所示:
package data_types is
    type array_of_integers is array(natural range <>) of integer;
end package;

现在在您的代码中按以下方式传递通用数组:
generic(
    COEFFICIENTS : array_of_integers := (-1, 0, 1)
);

现在软件将使用默认索引方案。它可以通过预定的'left属性进行考虑(参考链接:http://www.csee.umbc.edu/portal/help/VHDL/attribute.html)。
-- First coefficient
    ... <= COEFFICIENTS(COEFFICIENTS'left);
-- Second coefficient
    ... <= COEFFICIENTS(COEFFICIENTS'left + 1);

通常情况下,您应该在某种循环或生成语句中使用此数组:
GENERATE_STATEMENT: for entry in 0 to COEFFICIENTS'length-1 generate
    out(entry) <= std_logic_vector(to_signed(COEFFICIENTS(COEFFICIENTS'left + entry), out(entry)'length));
end generate;

作为一个小的侧面说明,对于Quartus II用户来说,在.bdf原理图文件中使用通用数组也是可能的。将参数类型设置为Auto并以这种格式重写参数值-A(D"-1",D"0",D"1"),其中D代表十进制数据类型(有用的链接:http://quartushelp.altera.com/14.0/mergedProjects/assign/asd/asd_tab_param.htm)。

2
如果您不介意使用较少限制的通用方法,可以这样做:
generic (IO_cfg : integer_vector);

只要您有一个 VHDL-2008 编译器即可。

实际上,VHDL-2008 为布尔、整数、实数和时间类型定义了数组类型(自然范围)。然而,在我使用的工具(ModelSim、QuartusII)中,对 VHDL-2008 的支持仍然非常有限。 - wap26
@wap26: "非常有限"有点过了。现在,Modelsim支持大部分功能,Aldex支持所有功能。Altera和Xilinx也支持相当多的功能。类型/包泛型似乎是最糟糕的方面。就我所知,所有工具都支持2008模式下的integer_vector - Martin Thompson
好的,谢谢你提供的最新消息。我会检查我的工具的最新版本! - wap26

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接