Matrix Math Packages User's Guide
Matrix Math Packages User's Guide
Dependencies:
“real_matrix_pkg” is dependant only on IEEE.MATH_REAL.
“complex_matrix_pkg” is dependent on “real_matrix_pkg”, IEEE.MATH_REAL
and IEEE.MATH_COMPLEX.
“fixed_matrix_pkg” is dependent on the VHDL-2008 “numeric_std” and
“fixed_pkg”, and “real_matrix_pkg”. The VHDL-1993 version of
“fixed_matrix_pkg” is dependent on the “IEEE_PROPOSED” library which can
be downloaded at http://www.vhdl.org/fphdl/vhdl2008c.zip. It is also dependant
on the “real_matrix_pkg”
Overview
Usage model:
use ieee.real_matrix_pkg.all; -- ieee_proposed for
compatibility version
....
signal a: real_matrix (0 to 3, 0 to 1);
signal b: real_matrix (0 to 1, 0 to 2);
signal c: real_matrix (0 to 3, 0 to 2);
begin
....
c <= a * b; -- Matrix multiply
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
Note that this notation is different from the Matlab notation. In that language the first
column is column “1”, not “0”.
All matrices are assumed to be of the “X to Y” range. If a “downto” range is used when
defining a matrix or a vector then that matrix will be reversed when it is operated on.
A vector is assumed to be a matrix with one row. All functions which read in vectors
treat them in this manner. If you want a matrix with one column, then you need to
define them as follows:
signal z : real_matrix (0 to 3, 0 to 0);
One of the wonderful things about Matlab is the ability to pull a slice out of a vector or a
matrix. In Matlab you can say “(i:j)” or “(:,j)” or “(r,i:j)”. Due to the strong typing in
VHDL we do not have that ability, so we have several functions which are designed to do
this:
a) Taking a matrix apart - For this you need the “SubMatrix” command
Result := submatrix (arg, x, y, rows, columns)
where : arg – Input matrix
x – “x” or row location to start from
y – “y” or column location to start from
rows – number of rows in result
columns – number of columns in result
Examples:
Take the matrix:
variable A : real_matrix (0 to 3, 0 to 3);
A := ((1.0, 2.0, 3.0, 4.0),
(5.0, 6.0, 7.0, 8.0),
(9.0, 10.0, 11.0, 12.0),
(13.0, 14.0, 15.0, 16.0));
Examples:
variable A : real_matrix (0 to 3, 0 to 3);
variable B : real_matrix (0 to 1, 0 to 1)
B := ((7.0, 2.0), (3.0, 4.0));
A := ones (A’length(1), A’length(2));
buildmatrix (B, A, 1, 1);
Will result in:
((1.0, 1.0, 1.0, 1.0),
(1.0, 7.0, 2.0, 1.0),
(1.0, 3.0, 4.0, 1.0),
(1.0, 1.0, 1.0, 1.0));
The “reshape” function can be use to convert a vector or a matrix to one of any shape
desired. For instance:
variable M : integer_matrix (0 to 2, 0 to 2);
variable N : integer_vector (0 to 8);
…
begin
N := (1, 2, 3, 4, 5, 6, 7, 8, 9);
M := reshape (N, M’length(1), M’length(2));
This will result in the following integer matrix:
M := ((1, 2, 3),
(4, 5, 6),
(7, 8, 9));
Index:
Operators:
“*” - Matrix multiply, overloaded for the following:
real_matrix * real_matrix return real_matrix – Number of Columns in left matrix
must match number of rows in right matrix. Returns a matrix which is (left row length by
right column length)
real_matrix * real_vector return real_matrix – Matrix must have 1 column,
number of rows must match length of vector. Returns a matrix which is square (vector
length by vector length)
real_vector * real_matrix return real_vector - Matrix must have same number of
rows as length of vector. Returned vector will be number of columns in Matrix.
real_matrix * real return real_matrix
real * real_matrix return real_matrix
real_vector * real return real_vector
real * real_vector return real_vector
“+” – Matrix addition, overloaded for the following:
real_matrix + real_matrix return real_matrix – Dimensions must match
real_vector + real_vector return real_vector – Dimensions must match
“-“ – Matrix subtraction, overloaded as follows:
real_matrix - real_matrix return real_matrix – Dimensions must match
real_vector - real_vector return real_vector – Dimensions must match
unary minus (real_matrix)
“/” – Matrix division
real_matrix / real_matrix return real_matrix (= real_matrix * inv(real_matrix)),
Matrix must be square for this function to work.
real_matrix / real return real_matrix
real_vector / real return real_vector
“**”
real_matrix ** integer return real_matrix – This function is recursive. Arg**-1 =
inv(arg). Matrix must be square for this function to work.
“=”
real_vector = real_matrix – True if the matrix has one row and equal to the vector
real_matrix = real_vector
real_vector /= real_matrix
real_matrix /= real_vector
“abs” – return the absolute value (real_matrix or real_vector)
Functions:
Times – Similar to matlab “.*” function (element by element multiply, same as
real_matrix * real)
Rdivide – Similar to matlab ./ function (element by element divide)
Mrdivide – Similar to matlab mrdivide function (l * inv(r))
Mldivide – Similar to matlab mldivide function (inv(l)* r)
Pow – Similar to matlab “.^” function, (element by element l**r)
Sqrt – element by element square root function
Exp – element by element exp function
Log – element by element natural log function
submatrix (arg, x, y, rows, columns) return real_matrix – Please see above for details
submatrix (arg, x, y, rows, columns) return real_vector
buildmatrix (arg, result, x, y)
buildmatrix (arg, result, x, y) – where “arg” is assumed to be a vector
InsertColumn (arg, result, x, y) – where “arg” is assumed to be a vector
Exclude (arg, row, column) – Return a matrix with the designated row and column
removed.
All of the above functions are replicated for types “integer_matrix” and “integer_vector”
with the exception of “rdivide”, “/”, “mldivide”, “sqrt”, “log”, “exp”, “inv”, “linsolve”,
“normalize”, and “rand”. For these functions, overloads which return “real_matrix”
have been created.
Functions which mix real and integer (vector and matrices) are also defined in these
packages. The output of these functions is always a real matrix or vector. Thus you can
divide a real_matrix by an integer_matrix, with the result being a real_matrix. The
following conversion functions are defined:
Textio Functions:
To_string (arg: real_matrix) – returns a string (with LF at the end of every row) delimited
by spaces.
Read (L: line; VALUE: real_matrix) – Reads a string which may contain several lines
and reads them into matrix “VALUE”. Punctuation and LF are ignored.
Read (L: line; VALUE: real_matrix; GOOD: boolean) – Reads a string which may
contain several lines and reads them into matrix “VALUE”. Punctuation and LF are
ignored. A Boolean “good” is returned to tell you if the matrix is valid.
Write (L: line, VALUE: real_matrix) – Writes matrix “VALUE” into line “L”. The
matrix is punctuated with “(“, “,”, “)” and “LF” to delimit columns and rows.
print_matrix (arg : real_matrix; index : Boolean := false);
If index is “false” then the size of the matrix is printed out on the first line, followed by
the values of the matrix (one row/line).
If index is “true” then the index of every element is printed before that element, and the
matrix size is not printer.
print_vector (arg : real_vector; index : Boolean := false);
If index is “true” then the index of every element is printed before that element.
Complex_Matrix_pkg package:
Operators
All of the functions defined for “real_matrix” are defined for “complex_matrix” and
“complex_polar_matrix” with the exception of “pow” and “poly” (because there is no
generic “**” function in math_complex), and “rand”. These operators are also
overloaded for mixing any combination of complex or complex_polar with real.
Exceptions:
Abs(complex_matrix) – returns a real_matrix (complex_vector, complex_polar_matrix,
and complex_polar_vector are also valid input types).
Ctranspose(complex_matrix) – returns the complex conjugate of the input matrix.
(complex_polar_matrix is also a valid input type).
Textio Functions:
There are no textio functions in “math_complex”, so “to_string”, “read” and “write” are
defined in complex_matrix_pkg for the types “complex”, “complex_polar”,
“complex_vector”, “complex_polar_vector”, “complex_matrix” and
“complex_polar_matrix”.
Fixed_Matrix_pkg package:
This package depends on the IEEE “numeric_std” and “fixed_pkg” packages. The
VHDL-93 version is dependent on the “IEEE_PROPOSED” library which can be
downloaded at http://www.vhdl.org/fphdl/vhdl2008c.zip.
This package was designed to make use of package generics. Also, in VHDL-2008 it is
possible to have an unconstrained array of unconstrained arrays. However at this time
those options are not available, so we use constants instead. These constants define how
large the array types are in the matricies.
These constants are used to define the sizes of the elements of the matrices and vectors as
follows:
All of the functions which are described in the “real_matrix_pkg” documentation are
defined for the types “sfixed_matrix” and “sfixed_vector” with the exception of the
“rand” function.
For the ufixed_matrix and ufixed_vector types the functions which involve matrix
inversion (Matrix/Matrix, mrdivide, mldivide, and inv) are not defined. Also “polyval”
and “linsolve” are undefined. Copies of these functions which accept ufixed_matrix and
return sfixed_matrix are defined.