-- +---------------------------+ -- | designer : Tim Pagden | -- | opened: 30 Sep 1993 | -- +---------------------------+ library maths; package body matrix_class is use maths.maths_class.all; -- sum over k-1 of (a(k-1)-i) * b(i) function sum_of_products ( lower_limit : integer; upper_limit : integer; a_in : single_vector; b_in : single_vector ) return single is variable partial_sum, running_total, sum : single; variable a : single_vector(a_in'length-1 downto 0); variable b : single_vector(b_in'length-1 downto 0); begin a := a_in(upper_limit downto lower_limit); b := b_in(upper_limit downto lower_limit); running_total := 0.0; for i in lower_limit to upper_limit loop partial_sum := a(i) * b(i); running_total := running_total + partial_sum; end loop; sum := running_total; return sum ; end sum_of_products; -- a(I-1) -> out | a(i-1) -> a(i) | data_in -> a(0) function shift_fifo ( fifo : single_vector; data_in : single ) return single_vector is variable fifo_out : single; variable fifo_queue : single_vector(fifo'length-1 downto 0); variable fifo_element : single; begin fifo_queue := fifo(fifo'length-1 downto 0); fifo_element := data_in; fifo_out := fifo_queue(fifo_queue'length-1); for i in fifo_queue'length-1 downto 1 loop fifo_queue(i) := fifo_queue(i-1); end loop; fifo_queue(0) := fifo_element; return fifo_queue ; end shift_fifo; -- a(i) -> a((I-1)-i) function reverse_order ( table : single_vector ) return single_vector is variable original_table : single_vector(table'length-1 downto 0); variable reversed_table : single_vector(table'length-1 downto 0); begin original_table := table(table'length-1 downto 0); for i in 0 to original_table'length-1 loop reversed_table(i) := original_table((original_table'length-1)-i); end loop; return reversed_table ; end reverse_order; function "*" ( multiplicand : single_matrix; multiplier : single_matrix ) return single_matrix is -- declarations variable a : single_matrix(0 to multiplicand'LENGTH(1)-1, 0 to multiplicand'LENGTH(2)-1); variable b : single_matrix(0 to multiplier'LENGTH(1)-1, 0 to multiplier'LENGTH(2)-1); variable result : single_matrix(0 to multiplicand'LENGTH(1)-1, 0 to multiplier'LENGTH(2)-1); variable partial_sum : single_matrix(0 to multiplicand'LENGTH(1)-1, 0 to multiplier'LENGTH(2)-1); begin a := multiplicand; b := multiplier; -- first of all check that matrix multiplication is possible -- also allow vector * vector, vector * matrix and -- matrix * vector multiplication if (a'LENGTH(2) = b'LENGTH(1)) then for row in 0 to a'LENGTH(2)-1 loop -- num_rows for column in 0 to b'LENGTH(1)-1 loop -- num_columns result(row,column) := 0.0; for i in 0 to a'LENGTH(2)-1 loop partial_sum(row,column) := a(row,i) * b(i,column); result(row,column) := result(row,column) + partial_sum(row,column); end loop; end loop; end loop; else report "In function *, multiplicand column and multiplier row"; report "lengths are not matched. This is not a VHDL error but"; report "a mathematical requirement for matrix multiplication." severity WARNING; end if; return result; end "*"; -- partial_sum(row,column) := a(row,column) * b(row,column); -- sum(row,column) := sum(row,column) + partial_sum(row,column); -- sum_of_products(a(row,column), b(column)); end matrix_class;