VHDL:如何声明可变宽度的通用变量

6
我想创建一个带有一个通用参数的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个回答

10

如果您希望POLYNOMIAL参数保持通用,可以将其指定为无约束数组。您还可以通过将所有引用替换为POLYNOMIAL'rangePOLYNOMIAL'length-1 downto 0POLYNOMIAL'length来省略WIDTH参数。

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泛型到另一个具有不同长度的值,其余逻辑应无需额外努力即可适应。


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。我认为这些“1”代表的是分流位置,你可能期望这些位置在一个LFSR长度到另一个长度时会发生变化。

你可以在多项式常量中传达“WIDTH”:

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

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