模块端口中的阵列参数化

时间:2017-05-29 15:51:39

标签: vhdl fpga

这个问题涉及定义一个可以接受参数化长度数组的模块的能力。

我目前拥有的是:

use work.my_types.all;

entity Calc is
   port (clk                : in  std_logic;
         y1, y2, yc, y3, y4 : in  u8exrow;
         lap_l, lap_r       : out s9row) ;
end Calc;

其中类型u8exrow和s9row是my_types包中定义的数组。

我希望使用泛型来改变这些数组的长度。

这是例如(除了不太好,因为它不使用类型)是不允许的:

entity Calc is
generic (row_end : in integer);
   port (clk                : in  std_logic;
         y1, y2, yc, y3, y4 : in  array (0 to row_end+1) of u8 ;
         lap_l, lap_r       : out array (0 to row_end) of s9) ;
 end Calc;

由于VHDL不喜欢其端口中的数组(我认为没有充分的理由)。

有什么方法可以定义一个可以接受参数化长度数组的模块吗?

谢谢!

2 个答案:

答案 0 :(得分:1)

VHDL没有模块,它们被称为设计实体,由实体声明(主要单元)和匹配的体系结构体(辅助单元)组成。

VHDL允许数组类型的端口对象就好了,但是你不能在端口声明的子类型指示中声明类型。

一个类型是单独声明的,用于在包中的端口中使用,或者作为泛型子句中的接口类型声明(后者在合成时不被广泛支持,如果有的话)。

该类型可以具有不受约束的范围,稍后由端口声明的子类型指示中的泛型常量部分地提供约束。

您的语法不正确。

声明具有无约束范围的数组类型的包:

package my_types_deferred_ranges is
    type u8 is range 0 to 40;
    type u8row is array (natural range <>) of u8;
    type u9 is range 0 to 80;
    type u9row is array (natural range <>) of u9;
end package;

具有端口声明的Calc设计实体,提供子类型指示:

library ieee;
use ieee.std_logic_1164.all;
use work.my_types_deferred_ranges.all;

entity Calc is
    generic (row_end : in integer);
    port (
        clk:                 in  std_logic;
        y1, y2, yc, y3, y4:  in  u8row (0 to row_end + 1);
        lap_l, lap_r:        out u9row (0 to row_end)
    );
 end entity Calc;

 architecture foo of Calc is
 begin
 end architecture;

实例化时:

library ieee;
use ieee.std_logic_1164.all;
use work.my_types_deferred_ranges.all;

entity top is
end entity;

architecture foo of top is
    constant row_end:           natural := 25;
    signal clk:                 std_logic;
    signal y1, y2, yc, y3, y4:  u8row (0 to row_end + 1);
    signal lap_l, lap_r:        u9row (0 to row_end);
begin
INST:
    entity work.Calc  -- an enity instantiation, no component declaration
        generic map (row_end => row_end)
        port map (
            clk => clk,
            y1 => y1,
            y2 => y2,
            yc => yc,
            y3 => y3,
            y4 => y4,
            lap_l => lap_l,
            lap_r => lap_r
        );

 end architecture;

按顺序分析这些示例时,可以详细阐述和模拟top,证明端口映射子类型指示有效。

  

通用值如何在端口中定义其长度?

分析是设计单元的语法和语义分析,导致设计单元存储在类似于库存档中的目标文件的库中。

详细说明会使声明生效。想想链接和加载。

分析后不变的值(由表达式提供)是局部静态的。在精化时固定的值是全局静态的。

通用常量是全局静态的,需要在精化过程中有效。当详细说明端口声明的接口列表时,实例化的组件将通用值作为约束作为端口的子类型指示的一部分进行详细说明。

类型对象的子类型指示(约束)可以通过详细说明在端口映射详细说明之前详细说明的通用映射声明来提供。

答案 1 :(得分:1)

在pkg中:

type t_u8_array is array (integer range <>) of u8;
type t_s9_array is array (integer range <>) of s9;

实体:

entity Calc is
generic (row_end : in integer);
   port (clk                : in  std_logic;
         y1, y2, yc, y3, y4 : in  t_u8_array(0 to row_end+1);
         lap_l, lap_r       : out t_s9_array(0 to row_end)
   );
 end Calc;

添加到包中也非常有用(VHDL-2008新增功能):

type slv_array is array(integer range<>) of std_logic_vector;
type u_array is array(integer range<>) of unsigned;
type s_array is array(integer range<>) of signed;

然后使用这些只是:

signal sMySig : slv_array(1 downto 0)(2 downto 0) := (others => (others => '0'));