Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Techniques for using VHDL Generics fixed value constants vs parameters

Status
Not open for further replies.

clayt

Newbie level 5
Joined
Jan 31, 2013
Messages
9
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Location
Canberra, Australia
Activity points
1,372
I see two uses for Generics in a VHDL entity:

1. To provide a Name to an otherwise magic number, but where the value is never intended to be changed.
2. A Parameter that allows the entity function to be changed from instance to instance.

Eg:


Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
entity Multiply16Bit is
generic
    (
    WIDTH         : integer := 16
    );
port
    (
    clk_in          : in  std_logic;
 
    a_in            : in  std_logic_vector ( (WIDTH - 1) downto 0) := (others => '0');
    b_in            : in  std_logic_vector ( (WIDTH - 1) downto 0) := (others => '0');
 
    mult_out        : out std_logic_vector ( (WIDTH - 1) downto 0) := (others => '0')
    );
end Multiply16Bit;



Here the entity is a 16 bit multiplier. WIDTH is intended to be used to define the width of the interface, but it is not intended to be changed. It is a 'fixed value'. Allowing it to change may make implementation difficult, or would require testing at different widths or whatever.
'WIDTH' is just used to put a Name to what would otherwise be '16' (a potentially meaningless value).

and:


Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
entity Delay_1 is
    generic (
        --! Data width parameter
        DATA_WIDTH              : integer := 16
    );
 
    port 
    (   
        --! Clock input
        clk_in      : in  std_logic;
        --! Data Input
        data_in     : in  std_logic_vector((DATA_WIDTH - 1) downto 0);
        --! Data Output
        data_out    : out  std_logic_vector((DATA_WIDTH - 1) downto 0)
    );
end Delay_1;



Here the intention is that DATA_WIDTH can be changed to any values as required for each instance. It is a 'parameter'.


What I am trying to determine is how to enforce or encourage users to make a distinction between these two uses, and ensure that 'fixed value' generics don't get changed. Maybe there is a convention of a name prefix or suffix that can indicate one or other. Of course comments can indicate the usage. An ASSERT would also be another way to ensure a fixed value does not get changed.

Any ideas? Are there any standard conventions for such things?

Clayton
Canberra, Australia
 

1. WIDTH is a reserved VHDL name (standard attribute) and shouldn't be used for a generic.
2. There's little use of putting a fixed parameter in a generic. You better use a constant.

In practice there may be cases where you wanted to write parameterizable code but took a short cut at some point. So it works with the present generic parameter set only. Of course you may put in an assert "support for other generic values soon come...".
 

1. WIDTH is a reserved VHDL name (standard attribute) and shouldn't be used for a generic.

Attributes are not reserved names/words, and width is not a pre-defined attribute. did you mean length? But using attribute names may be a little confusing.

This is legal vhdl:


Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
constant low : integer := 100;
signal event : ufixed(1 downto -10);
signal length : unsigned(width-1 downto 0);
signal high : unsigned(low-1 downto event'high);
 
....
 
if event'event then
  if length'length > WIDTH + high'low then
    -- Im sure you're confused;




To the OP:
1. If you want it to always be a fixed width, then dont use a generic at all. Just hard code it in the interface. You should only use generics if you intend the entity to be configurable. You can always but asserts on your generics in your code to ensure generics are "legal". This will kill simulation or synthesis if someone choses illegal combinations:


Code VHDL - [expand]
1
2
3
-- This can go inline, doesnt have to be in a process
 
assert( WIDTH > 7 and WIDTH < 10 ) report "Illegal Width chosen" severity failure;



2. I dont quite get what the problem is? Give your generics names as obvious as possible to avoid big comments. Engineers should understand stuff like DATA_WITH. And as you say, you can always use asserts like above to enforce legal generic combinations. But if you want it to be fixed - dont provide a generic. It can be more confusing when a generic is provided that then doesnt allow for change!

As a side note, Generics for things like bus widths may not be needed at all. VHDL '93 (and all compilers I know of) allows for interfaces with no determined length, and you can use attributes to get their length. The length is determined by whatever the signal is connected to:


Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
entity generic_ent is
  port (
    port_a  : std_logic_vector;
    port_b : std_logic_vector;
 
    output : std_logic_vector
  );
end entity
 
architecture rtl of generic_ent is
  signal some_signal : std_logic_vector(port_a'range);
begin
 
  assert (port_a'length = port_b'length) report "Port A and B widths must match" severity failure;
 
  some_signal <= port_a and port_b;
  output <= some_signal;
 
end architecture;

 
Last edited:
  • Like
Reactions: FvM

    FvM

    Points: 2
    Helpful Answer Positive Rating
you can also declare a generic with a range. eg, WIDTH : natural range 16 to 16 := 16. Now it is clear this cannot be changed.

This cuts down the number of asserts required to determine valid configs.

In terms of "unconstrained ports" -- where a port is declared just "std_logic_vector" and then attributes are used internally -- this can also be done. However, the input should be normalized to a desired range. Specifically, an input could be (7 downto 4) or could be (0 to 3). This is annoying if you make assumptions about index 0 existing or with the direction being "downto". unconstrained output ports can be annoying as you cannot use "open" if they are unused. If you don't normalize the inputs, you run the risk of the otherwise well-tested code breaking in weird ways when re-used.
 
  • Like
Reactions: FvM

    FvM

    Points: 2
    Helpful Answer Positive Rating
Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top