1
votes

I am trying to implement a generic (parameterizable) matrix adder.

So far I just have a matrix adder for two 3x3 matrices. Here is matrix_add:

LIBRARY IEEE;
USE IEEE.std_logic_1164.all;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.std_logic_UNSIGNED.all;
USE ieee.numeric_std.all;

LIBRARY work;
USE work.matrix_pack.all;

ENTITY matrix_add  is
  PORT (
    t_clk_i          : IN    STD_LOGIC;  -- System Clock (66.6667 MHz) (
    s_rst_l_i        : IN    STD_LOGIC;  -- Reset input
    d_mat1_i         : IN    matrix_t; -- Matrix 1 
    d_mat2_i         : IN    matrix_t; -- Matrix 2 
    d_result_o       : OUT   matrix_t  -- Addition Result  
  );
END matrix_add;

ARCHITECTURE rtl_matrix_add OF matrix_add IS

BEGIN
  p_add : PROCESS(t_clk_i, s_rst_l_i)
  BEGIN
    IF s_rst_l_i = '0' THEN
      d_result_o <= (OTHERS => (OTHERS => (OTHERS => '1')));
    ELSIF RISING_EDGE(t_clk_i) THEN
      FOR i IN 0 TO (d_mat1_i'LENGTH(1)-1) LOOP
        FOR j IN 0 TO (d_mat1_i'LENGTH(2)-1) LOOP
          d_result_o(i, j) <= d_mat1_i(i, j) + d_mat2_i(i, j);
        END LOOP;
      END LOOP;
    END IF;
  END PROCESS p_add;

END rtl_matrix_add;

and here is the package:

LIBRARY IEEE;
USE IEEE.std_logic_1164.all;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.std_logic_UNSIGNED.all;
USE ieee.numeric_std.all;

PACKAGE matrix_pack IS
  TYPE matrix_t is ARRAY (0 TO 2, 0 TO 2) OF STD_LOGIC_VECTOR(7 DOWNTO 0);
END matrix_pack;

How can I make the size of the matrix generic? Unfortunately I have to use a package because Quartus will not accept ARRAY (0 TO 2, 0 TO 2) OF STD_LOGIC_VECTOR(7 DOWNTO 0) as a signal input type otherwise I wouldn't need a package and my problem would be solved.

I've heard this can be done in VHDL 2008, but how so and will Quartus or Modelsim even accept this?

Thanks

1
Why don't you use constants either declared in matrix_pack or part of another package containing all constants, and use that in your array declaration. - fpga_magik
Interesting answer, the only drawback is if I need in the same design to instantiate two matrix adders with different dimensions. - Renato
I wonder if the following notation would work... type typename is array(natural range <>) of type ... try it and let us know. There's a good example here. If you can use the type as input then you can use generics for bounding the array. - fpga_magik
The example cited by @fpga_magik is a great answer. If it is not supported, I would not expect your tool to support package generics. For examples of package generics, see the ScoreboardGenericPkg and ScoreboardPkg_int at: github.com/osvvm/osvvm - Jim Lewis
Yes, great. Thanks, fpga_magik! Please see answer with modified code!! :) - Renato

1 Answers

1
votes

Thank you fpga_magik for your answer. It worked. The code turned out as follows:

LIBRARY IEEE;
USE IEEE.std_logic_1164.all;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.std_logic_UNSIGNED.all;
USE ieee.numeric_std.all;

LIBRARY work;
USE work.matrix_pack.all;

ENTITY matrix_add is
  GENERIC (
    M : INTEGER := 3;
    N : INTEGER := 2
    );
  PORT (
    t_clk_i          : IN    STD_LOGIC;                    -- System Clock (66.6667 MHz) (
    s_rst_l_i        : IN    STD_LOGIC;                    -- Reset input
    d_mat1_i         : IN    matrix_t(0 TO M-1, 0 TO N-1); -- Matrix 1 
    d_mat2_i         : IN    matrix_t(0 TO M-1, 0 TO N-1); -- Matrix 2 
    d_result_o       : OUT   matrix_t(0 TO M-1, 0 TO N-1)  -- Addition Result  
  );
END matrix_add;

ARCHITECTURE rtl_matrix_add OF matrix_add IS

BEGIN
  p_add : PROCESS(t_clk_i, s_rst_l_i)
  BEGIN
    IF s_rst_l_i = '0' THEN
      d_result_o <= (OTHERS => (OTHERS => (OTHERS => '1')));
    ELSIF RISING_EDGE(t_clk_i) THEN
      FOR i IN 0 TO (d_mat1_i'LENGTH(1)-1) LOOP
        FOR j IN 0 TO (d_mat1_i'LENGTH(2)-1) LOOP
          d_result_o(i, j) <= d_mat1_i(i, j) + d_mat2_i(i, j);
        END LOOP;
      END LOOP;
    END IF;
  END PROCESS p_add;

END rtl_matrix_add;

and the package as follows:

LIBRARY IEEE;
USE IEEE.std_logic_1164.all;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.std_logic_UNSIGNED.all;
USE ieee.numeric_std.all;

PACKAGE matrix_pack IS
  TYPE matrix_t is ARRAY (natural range <>, natural range <>) OF STD_LOGIC_VECTOR(7 DOWNTO 0);
END matrix_pack;

Thanks a lot!! :)