RE: [vhdl-200x] Please Review Matrix Math Package

From: Paul Butler <paul.butler@ni.com>
Date: Mon Jun 30 2014 - 13:48:25 PDT
I agree with Ryan's interpretation, and I think Ryan's simulator is 
compliant with the LRM (hurray!). In 1076-2002, the relevant section is in 
7.3.2.2:
An aggregate of an n-dimensional array type, where n is greater than 1, is 
written as a one-dimensional aggregate in which the index subtype of the 
aggregate is given by the first index position of the array type, and the 
expression specified for each element association is an (n–1)-dimensional 
array or array aggregate, which is called a subaggregate.

My interpretation of that statement is that a 2-dimensional array should 
be written as an array of arrays in which the outer array's index 
corresponds to the 2-dimensional array's first index. In our case, that 
means the aggregate is written as an array of rows, in which each row is 
written as a 1-dimensional array. That is a convenient definition because 
a VHDL object that is literally declared as an array of arrays could be 
initialized by the same aggregate as the 2-dimensional array and would use 
its indices in the same order (although the syntax is slightly different). 
For example, the VHDL below prints:
# ** Note: M1(0)(2) = 3
#    Time: 0 ns  Iteration: 0  Instance: /matrix
# ** Note: M2(0,2) = 3
#    Time: 0 ns  Iteration: 0  Instance: /matrix

Paul

Paul.Butler@ni.com | (512) 683-8743 | National Instruments | Austin, TX

entity matrix is
end entity matrix;
architecture RTL of matrix is
begin

  process is
    type integer_vector is array (natural range<>) of integer;
    subtype Row is integer_vector ( 0 to 2 );
    type Matrix is array ( natural range<>) of Row;

    type Matrix2 is array (natural range<>, natural range<>) of integer;

    constant M1 : Matrix ( 0 to 2 ) :=
      ((1, 2, 3),
       (4, 5, 6),
       (7, 8, 9));

    constant M2 : Matrix2 ( 0 to 2, 0 to 2 ) :=
      ((1, 2, 3),
       (4, 5, 6),
       (7, 8, 9));

  begin
    report "M1(0)(2) = " & integer'image(M1(0)(2));
    report "M2(0,2) = " & integer'image(M2(0,2));

    wait;
  end process;

end RTL;




From:   <ryan.w.hinton@L-3com.com>
To:     <vhdl-200x@eda.org>, 
Date:   06/30/2014 01:32 PM
Subject:        RE: [vhdl-200x] Please Review Matrix Math Package
Sent by:        owner-vhdl-200x@eda.org



Forgot to paste the code at the end of the email.  Here it is. 




use std.textio.all;

entity multidim_index_order is
end entity multidim_index_order;
architecture a of multidim_index_order is
begin

  p: process is
    variable ln : line;
    type REAL_MATRIX is array (natural range <>, natural range <>) of 
real;
    constant mat : REAL_MATRIX := ((1.0, 2.0, 3.0),
                                   (4.0, 5.0, 6.0),
                                   (7.0, 8.0, 9.0));
  begin
    for ii in mat'range(1) loop
      for jj in mat'range(2) loop
        write(ln, real'image(mat(ii,jj)) & " ");
      end loop;
      writeline(output, ln);
    end loop;
 
    writeline(output, ln);  -- blank line
    write(ln, "Element (0,2) is "&real'image(mat(0,2)));
    writeline(output, ln);
    wait;
  end process p;

end architecture a;


-----Original Message-----
From: Hinton, Ryan W @ CSG - CSW 
Sent: Monday, June 30, 2014 12:15 PM
To: vhdl-200x@eda.org
Subject: RE: [vhdl-200x] Please Review Matrix Math Package

On Friday, June 27, 2014 10:39 AM David Bishop wrote:
>On 06/26/2014 10:09 PM, tgingold@free.fr wrote:
>> I am slightly confused by the representation.  In the ug:
>>
>> As a concession to C, all matrices are assumed to be in column, row 
format, and starting at index 0. Thus for the matrix:
>> Z := ((1.0, 2.0, 3.0),
>>        (4.0, 5.0, 6.0),
>>        (7.0, 8.0, 9.0));
>> Z (0,2) = 7.0
>>
>>
>> I suppose we all agree that Z should be:
>> [ 1 2 3
>>    4 5 6
>>    7 8 9 ]
>>
>> So the first dimension is the number of lines and the second dimension 
is the number of columns.
>> This is natural both from a point of view of the VHDL language and from 
classical math style.
>>
>> But in that case and following the above excerpt, Z (0, 2) is 3.0 !
>
>When I create a matrix, I do it as:
>   type real_matrix is array (NATURAL range <>, NATURAL range <>) of 
REAL;  -- real matrix Which follows from:
>   type real_vector is array (NATURAL range <>) of REAL; Which is part of 
VHDL-2008.
>
>So what you really have is array of arrays.   In order to load the 
>array, I have to do:
>
>Z := ((1.0, 2.0, 3.0),
>       (4.0, 5.0, 6.0),
>       (7.0, 8.0, 9.0));
>
>which reversed rows and columns as it loads.....

I strongly agree with Tristan that we want to keep the (row, column) index 
semantics.  I can imagine the reverse making the package too confusing to 
be useful to me.  (I would probably write an auxiliary package to somehow 
make the natural ordering convenient for me.)  I also agree with Tristan's 
assessment that both mathematics and VHDL syntax match this convention. So 
in the array he defines, Z(0,2) is 3.0.  In fact, I tried it (code at the 
end of the email).  My simulator prints:

Element (0,2) is 3.000000e+00

So, David, I'm confused by your conclusion that the aggregate "[reverses] 
rows and columns as it loads." 

>> BTW, I am not sure that starting at index "0" is the best choice. 
>> This is neither the matlab conversion (which is heavily used) nor the 
math choice.

I still like the 0-based index.  Since this is VHDL, you can define your 
objects 1-based if you like.  Matlab's 1-based types make my life harder. 
I write my VHDL and math to used 0-based indices.

- Ryan

-- 
This message has been scanned for viruses and
dangerous content by MailScanner, and is
believed to be clean.






-- 
This message has been scanned for viruses and
dangerous content by MailScanner, and is
believed to be clean.
Received on Mon Jun 30 13:48:36 2014

This archive was generated by hypermail 2.1.8 : Mon Jun 30 2014 - 13:48:46 PDT