Continue to Site

# Declaration of a constant that chooses among other constants of different sizes in vhdl

#### rafimiet

##### Member level 5
I am trying to make a generic design for a filter. The filter works on different sizes of inputs from 2x2 to 64x64 and therefore the input needs to be multiplied by a coefficient matrix of corresponding sizes. I tried the following:

Code VHDL - [expand]1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
subtype t_dim1 is signed;
type t_dim1_vector is array (natural range <>) of t_dim1;
type t_dim2_vector is array (natural range <>) of t_dim1_vector;

constant c_mult : t_rom_vector2 :=  c_dct2_b2 when (g_bl_size = 2 and g_tr_type = 0) else
c_dct2_b4 when (g_bl_size = 4 and g_tr_type = 0) else
c_dct2_b8 when (g_bl_size = 8 and g_tr_type = 0) else
c_dct2_b16 when (g_bl_size = 16 and g_tr_type = 0) else
c_dct2_b32 when (g_bl_size = 32 and g_tr_type = 0) else
c_dct2_b64 when (g_bl_size = 64 and g_tr_type = 0) else
c_dct8_b4 when (g_bl_size = 4 and g_tr_type = 1) else
c_dct8_b8 when (g_bl_size = 8 and g_tr_type = 1) else
c_dct8_b16 when (g_bl_size = 16 and g_tr_type = 1) else
c_dct8_b32 when (g_bl_size = 32 and g_tr_type = 1) else
c_dst7_b4 when (g_bl_size = 4 and g_tr_type = 2) else
c_dst7_b8 when (g_bl_size = 8 and g_tr_type = 2) else
c_dst7_b16 when (g_bl_size = 16 and g_tr_type = 2) else
c_dst7_b32 when (g_bl_size = 32 and g_tr_type = 2);

c_mult chooses between constants of different sizes. I synthesized this but it seems that it is not simulatable...

Then I tried the following:

Code VHDL - [expand]1
2
3
4
5
type t_rom_vector3 is array (natural range <>) of t_rom_vector2;

constant c_trtype_blsz : t_rom_vector3 := ( (c_dct2_b2, c_dct2_b4, c_dct2_b8, c_dct2_b16, c_dct2_b32, c_dct2_b64),
(c_zero, c_dct8_b4, c_dct8_b8, c_dct8_b16, c_dct8_b32, c_zero),
(c_zero, c_dst7_b4, c_dst7_b8, c_dst7_b16, c_dst7_b32, c_zero)    );

But again, it is not simulatable and I get the following error:
(82) At depth 2, array length is 6; aggregate length is 126
(83) At depth 2, array length is 6; aggregate length is 64
(84) At depth 2, array length is 6; aggregate length is 64
So is there a way of generating a generic code for this?

<Moderator action: changed to syntax vhdl tag for VHDL syntax highlighting>

Last edited by a moderator:

#### barry

what is g_bl_size? Is it a constant? What about g_tr_type? You also haven't covered every possible case in your when statement. You also haven't shown us the part of the code that generates the error or associated line numbers.

I think there's a better way of doing this than a WHEN statement, I'd have to think about this a bit. And it's very strange that it synthesizes "ok", but won't simulate; usually it's the other way around.

#### rafimiet

##### Member level 5
The final version of the files is as follows ( I haven't given the definition of constants after c_dct2_b8, as it will unnecessarily increase the length of the code and it is intuitive) :
Code:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

package pkg_TrCoeffMatrix is

--     subtype t_dim1_sulv is std_ulogic_vector;
--     type t_dim1_vector_sulv is array (natural range <>) of t_dim1_sulv;
--     type t_dim2_vector_sulv is array (natural range <>) of t_dim1_vector_sulv;
--     type t_dim3_vector_sulv is array (natural range <>) of t_dim2_vector_sulv;

subtype t_rom2 is integer;
type t_rom_vector1 is array (natural range <>) of t_rom2;
type t_rom_vector2 is array (natural range <>) of t_rom_vector1;
type t_rom_vector3 is array (natural range <>) of t_rom_vector2;
-- dct2 coeff matrix
constant c_zero : t_rom_vector2 (0 to 1)(0 to 1)
:=(     (0,0),
(0,0)    );
constant c_dct2_b2 : t_rom_vector2 (0 to 1)(0 to 1)
:=(     (64,64),
(64,-64)    );
constant c_dct2_b4 : t_rom_vector2 (0 to 3)(0 to 3)
:=(     (64, 64, 64, 64),
(83, 36, -36, -83),
(64, -64, -64, 64),
(36, -83, 83, -36)   );
constant c_dct2_b8 : t_rom_vector2 (0 to 7)(0 to 7)
:=(     (64, 64, 64, 64, 64, 64, 64, 64), ( 89, 75, 50, 18, -18, -50, -75, -89), ( 83, 36, -36, -83, -83, -36, 36, 83), ( 75, -18, -89, -50, 50, 89, 18, -75), ( 64, -64, -64, 64, 64, -64, -64, 64), ( 50, -89, 18, 75, -75, -18, 89, -50), ( 36, -83, 83, -36, -36, 83, -83, 36), ( 18, -50, 75, -89, 89, -75, 50, -18)   );
constant c_trtype_blsz : t_rom_vector3 := ( (c_dct2_b2, c_dct2_b4, c_dct2_b8, c_dct2_b16, c_dct2_b32, c_dct2_b64),
(c_zero, c_dct8_b4, c_dct8_b8, c_dct8_b16, c_dct8_b32, c_zero),
(c_zero, c_dst7_b4, c_dst7_b8, c_dst7_b16, c_dst7_b32, c_zero)    );
end pkg_TrCoeffMatrix;
The code using this package is as follows:
Code:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

library vvc_lib;
use vvc_lib.pkg_TrCoeffMatrix.all;

entity generic_multiplier is
generic (
g_coeff_width : natural := 16;
g_bl_size     : natural := 4;
g_bl_type     : natural := 1; --(0,1,2,3,4,5)--> bl_sz(2,4,8,16,32,64)
g_tr_type     : natural := 0 -- 0--> DCT2, 1--> DCT8, 2--> DST7
);
port (
i_data     : in  std_ulogic_vector(g_bl_size*g_bl_size*g_coeff_width-1 downto 0); -- (M--> L)SB <= (|Pix_N|...|Pix_2|Pix1|) in memory
o_data     : out std_ulogic_vector(2*g_bl_size*g_bl_size*g_bl_size*g_coeff_width-1 downto 0)
);
end entity generic_multiplier;

architecture rtl of generic_multiplier is
subtype t_dim1 is signed;
type t_dim1_vector is array (natural range <>) of t_dim1;
type t_dim2_vector is array (natural range <>) of t_dim1_vector;
signal s_data_in : t_dim2_vector (0 to g_bl_size-1)(0 to g_bl_size-1)(g_coeff_width-1 downto 0);
signal s_data_out : signed(2*g_bl_size*g_bl_size*g_bl_size*g_coeff_width-1 downto 0) := (others => '0');

constant c_mult : t_rom_vector3 := c_trtype_trblsz(0 to 3)(0 to 5)(g_tr_type)(g_bl_type);
what is g_bl_size? Is it a constant? What about g_tr_type? You also haven't covered every possible case in your when statement. You also haven't shown us the part of the code that generates the error or associated line numbers.
As now it is clear g_xyz is generic constant. The errors at 82,83 and 84 come from the following lines of code:
Code:
 constant c_trtype_blsz : t_rom_vector3 := ( (c_dct2_b2, c_dct2_b4, c_dct2_b8, c_dct2_b16, c_dct2_b32, c_dct2_b64),

(c_zero, c_dct8_b4, c_dct8_b8, c_dct8_b16, c_dct8_b32, c_zero),

(c_zero, c_dst7_b4, c_dst7_b8, c_dst7_b16, c_dst7_b32, c_zero)    );
Kindly let me know if I need to attach the complete files here.

#### barry

Sorry, but this is just a tangled mess.

It is most certainly NOT "clear g_xyz is generic constant". Nowhere does g_xyz appear in your code.

constant c_trtype_blsz : t_rom_vector3 := ( (c_dct2_b2,...
references things that don't appear anywhere (c_dct2_b2, e.g.).

I have no idea what you're trying to accomplish here.

#### rafimiet

##### Member level 5
It is most certainly NOT "clear g_xyz is generic constant". Nowhere does g_xyz appear in your code.
It simply means that the prefix g_ is a generic. You had asked for multiple keywords with prefix g_. Moreover, you can refer to the code to get answer to your primary question.
constant c_trtype_blsz : t_rom_vector3 := ( (c_dct2_b2,...
references things that don't appear anywhere (c_dct2_b2, e.g.).
I am trying to use a constant in a generic way. Please refer to the original question in thread #1. I am trying to make a constant c_mult, whose values could be c_dct2_b2 or c_dct2_b4 or something else as per their location in the c_mult constant.
So here is the summary again:
1. First I defined individually constants like c_zero, c_dct2_b2, c_dct2_b4 etc, whose size is different.
2. Then, I am trying to club these into the constant c_trtype_blsz in such a way that each one can be indexed separately.
3. Then I am trying to use the c_trtype_blsz in c_mult to call it in the function.
But it is showing me some errors while simulating.

#### TrickyDicky

@rafimiet
Im not fully convinced by your arguments:

c_mult chooses between constants of different sizes. I synthesized this but it seems that it is not simulatable...

You cant have synthesised as when..else is not available as part of a initial value assignment until VHDL 2019, and I am not aware of any synth tool that provide VHDL 2019 support of this feature. (Maybe you did it in a function, which has been supported since VHDL 2008)

Also, in VHDL (from VHDL 87 to 2019), an array must contain elements that are all the same size. While an unconstrained array type is legal since 2008, when you declare an object, all elements must be the same length/size.

You are missing several type declarations in your code postings. Please show the whole code.

So, in general, I think you have a misunderstanding of how VHDL arrays work.

#### rafimiet

##### Member level 5
@rafimiet
Im not fully convinced by your arguments:
The package is as follows:
Rich (BB code):
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

package pkg_TrCoeffMatrix is
subtype t_rom2 is integer;
type t_rom_vector1 is array (natural range <>) of t_rom2;
type t_rom_vector2 is array (natural range <>) of t_rom_vector1;
constant c_dct2_b2 : t_rom_vector2 (0 to 1)(0 to 1)
:=(     (64,64),
(64,-64)    );
constant c_dct2_b4 : t_rom_vector2 (0 to 3)(0 to 3)
:=(     (64, 64, 64, 64),
(83, 36, -36, -83),
(64, -64, -64, 64),
(36, -83, 83, -36)   );
constant c_dct2_b8 : t_rom_vector2 (0 to 7)(0 to 7)
:=(     (64, 64, 64, 64, 64, 64, 64, 64), ( 89, 75, 50, 18, -18, -50, -75, -89), ( 83, 36, -36, -83, -83, -36, 36, 83), ( 75, -18, -89, -50, 50, 89, 18, -75), ( 64, -64, -64, 64, 64, -64, -64, 64), ( 50, -89, 18, 75, -75, -18, 89, -50), ( 36, -83, 83, -36, -36, 83, -83, 36), ( 18, -50, 75, -89, 89, -75, 50, -18)   );
constant c_dct2_b16 : t_rom_vector2 (0 to 15)(0 to 15)
:=(     ( 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64), ( 90, 87, 80, 70, 57, 43, 25, 9, -9, -25, -43, -57, -70, -80, -87, -90), ( 89, 75, 50, 18, -18, -50, -75, -89, -89, -75, -50, -18, 18, 50, 75, 89), ( 87, 57, 9, -43, -80, -90, -70, -25, 25, 70, 90, 80, 43, -9, -57, -87), ( 83, 36, -36, -83, -83, -36, 36, 83, 83, 36, -36, -83, -83, -36, 36, 83), ( 80, 9, -70, -87, -25, 57, 90, 43, -43, -90, -57, 25, 87, 70, -9, -80), ( 75, -18, -89, -50, 50, 89, 18, -75, -75, 18, 89, 50, -50, -89, -18, 75), ( 70, -43, -87, 9, 90, 25, -80, -57, 57, 80, -25, -90, -9, 87, 43, -70), ( 64, -64, -64, 64, 64, -64, -64, 64, 64, -64, -64, 64, 64, -64, -64, 64), ( 57, -80, -25, 90, -9, -87, 43, 70, -70, -43, 87, 9, -90, 25, 80, -57), ( 50, -89, 18, 75, -75, -18, 89, -50, -50, 89, -18, -75, 75, 18, -89, 50), ( 43, -90, 57, 25, -87, 70, 9, -80, 80, -9, -70, 87, -25, -57, 90, -43), ( 36, -83, 83, -36, -36, 83, -83, 36, 36, -83, 83, -36, -36, 83, -83, 36), ( 25, -70, 90, -80, 43, 9, -57, 87, -87, 57, -9, -43, 80, -90, 70, -25), ( 18, -50, 75, -89, 89, -75, 50, -18, -18, 50, -75, 89, -89, 75, -50, 18), ( 9, -25, 43, -57, 70, -80, 87, -90, 90, -87, 80, -70, 57, -43, 25, -9));
constant c_dct8_b4 : t_rom_vector2 (0 to 3)(0 to 3)
:=(     ( 84, 74, 55, 29), ( 74, 0, -74, -74), ( 55, -74, -29, 84), ( 29, -74, 84, -55));
constant c_dct8_b8 : t_rom_vector2 (0 to 7)(0 to 7)
:=(     ( 86, 85, 78, 71, 60, 46, 32, 17), ( 85, 60, 17, -32, -71, -86, -78, -46), ( 78, 17, -60, -86, -46, 32, 85, 71), ( 71, -32, -86, -17, 78, 60, -46, -85), ( 60, -71, -46, 78, 32, -85, -17, 86), ( 46, -86, 32, 60, -85, 17, 71, -78), ( 32, -78, 85, -46, -17, 71, -86, 60), ( 17, -46, 71, -85, 86, -78, 60, -32));
constant c_dct8_b16 : t_rom_vector2 (0 to 15)(0 to 15)
:=(     ( 88, 88, 87, 85, 81, 77, 73, 68, 62, 55, 48, 40, 33, 25, 17, 8), ( 88, 81, 68, 48, 25, 0, -25, -48, -68, -81, -88, -88, -81, -68, -48, -25), ( 87, 68, 33, -8, -48, -77, -88, -81, -55, -17, 25, 62, 85, 88, 73, 40), ( 85, 48, -8, -62, -88, -77, -33, 25, 73, 88, 68, 17, -40, -81, -87, -55), ( 81, 25, -48, -88, -68, 0, 68, 88, 48, -25, -81, -81, -25, 48, 88, 68), ( 77, 0, -77, -77, 0, 77, 77, 0, -77, -77, 0, 77, 77, 0, -77, -77), ( 73, -25, -88, -33, 68, 77, -17, -88, -40, 62, 81, -8, -87, -48, 55, 85), ( 68, -48, -81, 25, 88, 0, -88, -25, 81, 48, -68, -68, 48, 81, -25, -88), ( 62, -68, -55, 73, 48, -77, -40, 81, 33, -85, -25, 87, 17, -88, -8, 88), ( 55, -81, -17, 88, -25, -77, 62, 48, -85, -8, 88, -33, -73, 68, 40, -87), ( 48, -88, 25, 68, -81, 0, 81, -68, -25, 88, -48, -48, 88, -25, -68, 81), ( 40, -88, 62, 17, -81, 77, -8, -68, 87, -33, -48, 88, -55, -25, 85, -73), ( 33, -81, 85, -40, -25, 77, -87, 48, 17, -73, 88, -55, -8, 68, -88, 62), ( 25, -68, 88, -81, 48, 0, -48, 81, -88, 68, -25, -25, 68, -88, 81, -48), ( 17, -48, 73, -87, 88, -77, 55, -25, -8, 40, -68, 85, -88, 81, -62, 33), ( 8, -25, 40, -55, 68, -77, 85, -88, 88, -87, 81, -73, 62, -48, 33, -17) );

constant c_dst7_b4 : t_rom_vector2 (0 to 3)(0 to 3)
:=(     ( 29, 55, 74, 84 ), ( 74, 74, 0, -74 ), ( 84, -29, -74, 55 ), ( 55, -84, 74, -29 ));
constant c_dst7_b8 : t_rom_vector2 (0 to 7)(0 to 7)
:=(     ( 17, 32, 46, 60, 71, 78, 85, 86), ( 46, 78, 86, 71, 32, -17, -60, -85), ( 71, 85, 32, -46, -86, -60, 17, 78), ( 85, 46, -60, -78, 17, 86, 32, -71), ( 86, -17, -85, 32, 78, -46, -71, 60), ( 78, -71, -17, 85, -60, -32, 86, -46), ( 60, -86, 71, -17, -46, 85, -78, 32), ( 32, -60, 78, -86, 85, -71, 46, -17));
constant c_dst7_b16 : t_rom_vector2 (0 to 15)(0 to 15)
:=(     ( 8, 17, 25, 33, 40, 48, 55, 62, 68, 73, 77, 81, 85, 87, 88, 88), ( 25, 48, 68, 81, 88, 88, 81, 68, 48, 25, 0, -25, -48, -68, -81, -88), ( 40, 73, 88, 85, 62, 25, -17, -55, -81, -88, -77, -48, -8, 33, 68, 87), ( 55, 87, 81, 40, -17, -68, -88, -73, -25, 33, 77, 88, 62, 8, -48, -85), ( 68, 88, 48, -25, -81, -81, -25, 48, 88, 68, 0, -68, -88, -48, 25, 81), ( 77, 77, 0, -77, -77, 0, 77, 77, 0, -77, -77, 0, 77, 77, 0, -77), ( 85, 55, -48, -87, -8, 81, 62, -40, -88, -17, 77, 68, -33, -88, -25, 73), ( 88, 25, -81, -48, 68, 68, -48, -81, 25, 88, 0, -88, -25, 81, 48, -68), ( 88, -8, -88, 17, 87, -25, -85, 33, 81, -40, -77, 48, 73, -55, -68, 62), ( 87, -40, -68, 73, 33, -88, 8, 85, -48, -62, 77, 25, -88, 17, 81, -55), ( 81, -68, -25, 88, -48, -48, 88, -25, -68, 81, 0, -81, 68, 25, -88, 48), ( 73, -85, 25, 55, -88, 48, 33, -87, 68, 8, -77, 81, -17, -62, 88, -40), ( 62, -88, 68, -8, -55, 88, -73, 17, 48, -87, 77, -25, -40, 85, -81, 33), ( 48, -81, 88, -68, 25, 25, -68, 88, -81, 48, 0, -48, 81, -88, 68, -25), ( 33, -62, 81, -88, 85, -68, 40, -8, -25, 55, -77, 88, -87, 73, -48, 17), ( 17, -33, 48, -62, 73, -81, 87, -88, 88, -85, 77, -68, 55, -40, 25, -8));

end pkg_TrCoeffMatrix;
The vhdl file using this package is as follows:
Rich (BB code):
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

library vvc_lib;
use vvc_lib.pkg_TrCoeffMatrix.all;

entity generic_multiplier is
generic (
g_coeff_width : natural := 4;
g_bl_size     : natural := 4;
-- g_bl_type     : natural := 1; --(0,1,2,3,4,5)--> bl_sz(2,4,8,16,32,64)
g_tr_type     : natural := 0 -- 0--> DCT2, 1--> DCT8, 2--> DST7
);
port (
i_data     : in  std_ulogic_vector(g_bl_size*g_bl_size*g_coeff_width-1 downto 0); -- (M--> L)SB <= (|Pix_N|...|Pix_2|Pix1|) in memory
o_data     : out std_ulogic_vector(2*g_bl_size*g_bl_size*g_bl_size*g_coeff_width-1 downto 0)
);
end entity generic_multiplier;

architecture rtl of generic_multiplier is
subtype t_dim1 is signed;
type t_dim1_vector is array (natural range <>) of t_dim1;
type t_dim2_vector is array (natural range <>) of t_dim1_vector;
-- type t_dim2_vector is array (0 to 3, 0 to 7) of std_ulogic_vector(7 downto 0);
signal s_data_in : t_dim2_vector (0 to g_bl_size-1)(0 to g_bl_size-1)(g_coeff_width-1 downto 0);
signal s_data_out : signed(2*g_bl_size*g_bl_size*g_bl_size*g_coeff_width-1 downto 0) := (others => '0');

--constant c_mult : t_rom_vector2 := c_dct2_b4;
-- The following is synthesizable but not simulatable
constant c_mult : t_rom_vector2 :=  c_dct2_b2 when (g_bl_size = 2 and g_tr_type = 0) else
c_dct2_b4 when (g_bl_size = 4 and g_tr_type = 0) else
c_dct2_b8 when (g_bl_size = 8 and g_tr_type = 0) else
c_dct2_b16 when (g_bl_size = 16 and g_tr_type = 0) else
c_dct8_b4 when (g_bl_size = 4 and g_tr_type = 1) else
c_dct8_b8 when (g_bl_size = 8 and g_tr_type = 1) else
c_dct8_b16 when (g_bl_size = 16 and g_tr_type = 1) else
c_dst7_b4 when (g_bl_size = 4 and g_tr_type = 2) else
c_dst7_b8 when (g_bl_size = 8 and g_tr_type = 2) else
c_dst7_b16 when (g_bl_size = 16 and g_tr_type = 2);

begin
-- Reshape input data -- No need to change upto 4x4 block
gen00: for i in 0 to g_bl_size-1 generate
gen01: for j in 0 to g_bl_size-1 generate
s_data_in(i)(j) <= signed(i_data(g_coeff_width*(i*g_bl_size+j+1)-1 downto g_coeff_width*(i*g_bl_size+j)));
end generate gen01;
end generate gen00;

-- Matrix Multiplication
gen02:  for i in 0 to g_bl_size-1 generate
gen03: for j in 0 to g_bl_size-1 generate
gen04: for k in 0 to g_bl_size-1 generate
s_data_out(2*g_coeff_width*(i*g_bl_size*g_bl_size+j*g_bl_size+k+1)-1 downto 2*g_coeff_width*(i*g_bl_size*g_bl_size+j*g_bl_size+k)) <= s_data_in(i)(k) * c_mult(k)(j);
end generate gen04;
end generate gen03;
end generate gen02;

-- Output Multiplications g_bl_size**3 (in number) and 2*g_coeff_width (each)
o_data(g_bl_size*g_bl_size*g_bl_size*2*g_coeff_width-1 downto 0) <= std_ulogic_vector(s_data_out(g_bl_size*g_bl_size*g_bl_size*2*g_coeff_width-1 downto 0));
end architecture rtl;
I have synthesized the design and it has been successfully synthesized... Tool used: Quartus Prime Pro and VHDL 2019
You are missing several type declarations in your code postings. Please show the whole code.

So, in general, I think you have a misunderstanding of how VHDL arrays work.

#### Attachments

• Quartus_ScreenShot.png
432.6 KB · Views: 29
• RTL_Screenshot.png
198.5 KB · Views: 27

#### TrickyDicky

So Prime Pro Has more VHDL 2019 support that I have seen listed. (I dont work with intel parts)
The documentation only lists Conditional Analysis and VHDL interfaces from VHDL 2019 as supported:

So you are obviously using undocumented/experimental supported 2019 features.

The problem is the when..else in object declaration requires VHDL 2019. The only simulator I am aware of that supports this is ActiveHDL/Riveria Pro. You dont say what simulator you are using.

So what Im trying to understand now is what the problem actually is? just tool support of VHDL 2019? You now have everything as integers, which makes things easier.
--- Updated ---

If you want to make it VHDL 2008, instead of using when..else direction, you can use a function to set the value instead, which is allowed the when..else inside of it.

Last edited:

#### rafimiet

##### Member level 5
So what Im trying to understand now is what the problem actually is? just tool support of VHDL 2019? You now have everything as integers, which makes things easier.
As seen in the thread #7, pkg_TrCoeffMatrix.vhd consist of multiple constants. These constants are used as one of the two inputs for matrix multiplications. Now as matrix sizes changes, so does the size of these constants. We need to choose an appropriate constant.
The question is: Is there a way to make a generic_multiplier.vhd file that can select among the various constants of pkg_TrCoeffMatrix.vhd?

#### TrickyDicky

Whats wrong with the code you already have? As far as I can see, you just need to change the assignment of c_mult to VHDL 2008 friendly code (ie. an initialisation function, that can mostly be a copty/paste of what is already there).
--- Updated ---

To be honest though - I think I agree with barry - your code is a mess. Why cant i_data and o_data simply be unconstrained arrays of signed (either using the generics to size them, or ), rather than one huge std_logic_vector? It seems strange you're using VHDL 2019 for the internal code when the port definitions are straight out of 1993.

#### rafimiet

##### Member level 5
To be honest though - I think I agree with barry - your code is a mess. Why cant i_data and o_data simply be unconstrained arrays of signed (either using the generics to size them, or ), rather than one huge std_logic_vector? It seems strange you're using VHDL 2019 for the internal code when the port definitions are straight out of 1993.
There is nothing wrong with i_data or o_data... I am handling my port definitions very well as per my requirements in a broader sense... I am just asking you about how to make my constant c_mult a generic one. I got the point, you don't have an answer to my question. Or let's say my question doesn't make sense. Thank you for trying to help.