-- +---------------------------+ -- | designer : Tim Pagden | -- | opened: 30 Sep 1993 | -- +---------------------------+ -- library ieee; library vfp; library maths; package body matrix_class is use maths.maths_class.all; use vfp.strings.all; use vfp.AWK_functions.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)); procedure split ( input_string : STRING; output_array : out integer_vector; separator : STRING; num_fields : out INTEGER ) is variable array_as_string : string_list(0 to input_string'LENGTH); -- ideally LENGTH-1, but what happens when the input_string is a single character -- you need 0 for the input_str and 1 for the char itself variable num_fields_in_string : INTEGER; -- variable integer_as_string : string(1 to 11); -- 32 bit number = sign + 10 digits, = 11 begin split(input_string, array_as_string, separator, num_fields_in_string); num_fields := num_fields_in_string; for i in 1 to num_fields_in_string loop -- integer_as_string := array_as_string(i).all; output_array(i-1) := integer'VALUE(array_as_string(i).all); end loop; end split; end matrix_class;