Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

VHDL: How to declare a variable width generic [duplicate]

Tags:

vhdl

I want to create a VHDL entity with a one generic that changes the width of another generic.

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

Unfortunately, it seems I can't reference an earlier defined generic later in the generic list. Active-HDL gives the following errors:

Error: COMP96_0300: modules/m3_test_load/lfsr_n.vhd : (26, 45): Cannot reference "WIDTH" until the interface list is complete.

Error: COMP96_0077: modules/m3_test_load/lfsr_n.vhd : (26, 66): Undefined type of expression. Expected type 'STD_LOGIC_VECTOR'.

One workaround would be to make POLYNOMIAL a port. But it properly should be a generic since since the value is constant at elaboration time. I know that if I apply a constant to the port, it will synthesize the way I want and optimize the constants values into the module, but I'd like to find someway to make it a generic. Any suggestions how to do this?

like image 468
Barry Moss Avatar asked Feb 14 '15 01:02

Barry Moss


People also ask

How do you declare a constant in VHDL?

Explanation: The correct syntax to declare a CONSTANT data object in VHDL is shown in option a. The keyword CONSTANT is followed by the name of the constant which in turn is followed by a colon (:) sign. After the colon sign, the type of constant is specified and the value is assigned by using := assignment operator.

What is the purpose of generics in VHDL?

VHDL allows the designer to parametrize the entity during the component instantiation.


Video Answer


1 Answers

If you want the POLYNOMIAL parameter to remain a generic you can specify it as an unconstrained array. You can also dispense with the WIDTH parameter by replacing all references by POLYNOMIAL'range, POLYNOMIAL'length-1 downto 0, or POLYNOMIAL'length as needed.

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;

Unconstrained arrays are a powerful feature that help simplify code by implicitly controlling widths rather than needing a dedicated generic parameter. When used effectively they reduce the number of hard-coded array sizes in your source resulting in naturally resizable logic. You can freely change the POLYNOMIAL generic to another value with a different length and the rest of your logic should adapt without any additional effort.

like image 141
Kevin Thibedeau Avatar answered Sep 22 '22 11:09

Kevin Thibedeau