VHDL:如何声明变量宽度泛型

时间:2015-02-14 01:36:38

标签: vhdl

我想创建一个VHDL实体,其中一个泛型可以改变另一个泛型的宽度。

entity lfsr_n is 
generic (
    WIDTH           : integer := 32; -- counter width
    POLYNOMIAL      : std_logic_vector (WIDTH-1 downto 0) := "1000_0000_0000_0000_0000_0000_0110_0010"
);

不幸的是,我似乎无法在通用列表中稍后引用先前定义的通用。 Active-HDL出现以下错误:

错误:COMP96_0300:modules / m3_test_load / lfsr_n.vhd:(26,45):在接口列表完成之前无法引用“WIDTH”。

错误:COMP96_0077:modules / m3_test_load / lfsr_n.vhd:(26,66):未定义的表达式。预期类型'STD_LOGIC_VECTOR'。

一种解决方法是将POLYNOMIAL设为端口。但它恰当地应该是通用的,因为值在精化时是恒定的。我知道如果我将一个常量应用到端口,它将合成我想要的方式并将常量值优化到模块中,但我想找到一些使其成为通用的。有什么建议怎么做?

2 个答案:

答案 0 :(得分:6)

如果希望POLYNOMIAL参数保持通用,则可以将其指定为无约束数组。您还可以根据需要替换WIDTHPOLYNOMIAL'rangePOLYNOMIAL'length-1 downto 0的所有引用,从而免除POLYNOMIAL'length参数。

entity lfsr_n is
  generic (
    POLYNOMIAL : std_logic_vector := X"FFAA55BB"
  );
  port (
    -- Vector with copied range (defaults to ascending from 0)
    state  : out std_logic_vector(POLYNOMIAL'range);

    -- Vector with forced descending range
    state2 : out std_logic_vector(POLYNOMIAL'length-1 downto 0)
  );
end entity;

无约束数组是一项功能强大的功能,它通过隐式控制宽度来帮助简化代码,而不需要专用的通用参数。如果有效使用,它们会减少源中硬编码数组大小的数量,从而产生自然可调整大小的逻辑。您可以自由地将POLYNOMIAL泛型更改为具有不同长度的其他值,其余逻辑应该无需任何额外的努力即可适应。

答案 1 :(得分:0)

在任何通用和任何端口声明之后有一个实体声明部分:

library ieee;
use ieee.std_logic_1164.all;

entity lfsr_n is 
    generic (
        WIDTH: integer := 32 -- counter width
    );
    port (
        foo:    integer
    );
    constant POLYNOMIAL: std_logic_vector (WIDTH-1 downto 0) 
            := B"1000_0000_0000_0000_0000_0000_0110_0010";
end entity;
architecture foo of lfsr_n is
begin
end architecture;

这分析并阐述了正确使用通用的方法。

您还可以注意到,您分配给std_logic_vector的文字并不适应更改WIDTH。我原本以为这些位置适用于点击位置,并且您预计这些可能会从一个LFSR长度变为另一个。

你可以传达“宽度”'在多项式常数中:

library ieee;
use ieee.std_logic_1164.all;

entity lfsr_n is 
    generic (
        -- WIDTH: integer := 32; -- counter width
        POLYNOMIAL: std_logic_vector := 
                 B"1000_0000_0000_0000_0000_0000_0110_0010"
    );
    port (
        foo:    integer
    );
    -- constant POLYNOMIAL: std_logic_vector (WIDTH-1 downto 0)
    --         := B"1000_0000_0000_0000_0000_0000_0110_0010";
end entity;
architecture foo of lfsr_n is
    signal shft_register:  std_logic_vector (0 to POLYNOMIAL'LENGTH-1);
begin
end architecture;

或者:

architecture foo of lfsr_n is
    -- signal shft_register:  std_logic_vector (0 to POLYNOMIAL'LENGTH-1);
    -- or
    signal shift_register: std_logic_vector(POLYNOMIAL'RANGE);