1
votes

Let's say that I have the following Generic part of entity declaration:

Entity Example is

Generic
   (G_INTEGER_A : integer range C_INT_LEFT_A to C_INT_RIGHT_A;

    G_INTEGER_B : integer range C_INT_LEFT_B to C_INT_RIGHT_B);
Port
    (...)

Is there a straightforward way to use that integer range attribute to determine the equivalent bit size to dimension an std_logic_vector or unsigned array to represent values within this range?

I would like to use it only at elaboration time, to define in a generic way size of counters , etc in a way like this:

constant C_A_SIZE: integer := f_int_size(G_INTEGER_A'range);

signal s_bit_cnt : unsigned(C_A_SIZE - 1 downto 0);

Where f_int_size would be a user function, maybe defined in an external package. Is there a way to do this?

2

2 Answers

1
votes

You cannot extract the range value directly from the generic. However if you use a named type or subtype for the generic, you can use its attributes:

subtype Count_Range_A is natural range C_INT_LEFT_A to C_INT_RIGHT_A;

Generic ( G_Integer_A : Count_Range_A; ... )

function range_size(Start,End : natural return Natural is ...

constant C_A_SIZE: natural := range_size(Count_Range_A'Left, Count_Range_A'Right);

The function body may involve a log function and rounding, and careful testing across the range of values : a crude case statement is probably simpler and safer, if uglier!

I normally do this the other way round : it is simpler to start with the word width and derive everything else from it.

package Types is

    constant Packet_Bits : natural := <some value>
    -- Related declarations below are derived from it.
    constant Packet_Size : natural := 2**Packet_Bits;
    subtype Packet_Address is natural range 0 to Packet_Size - 1;
    subtype Packet_Address_Word is unsigned(Packet_Bits-1 downto 0);

end Types;
0
votes

No, it isn't: attributes (which you would need here) are defined on Types, Arrays, Signals, and Entities, but your case is neither of them. The range you provide is an attribute for simulations or synthesis. You either have to specify the lower and upper limits of your counters as separate constants, or define a record type for it.

As an afterthought: I have currently no idea what the synthesis would produce if you provide, i.e., 3 as a lower limit. Can you comment?