Reputation: 3547
I have array:
type MATR is array(natural range 1 to N, natural range 1 to N) of natural;
signal m: MATR;
1) Is it possible to fill elements m(0, 1), m(0, 2) ... m(0, N) with some value outside of process? Something like:
m(1) <= (others => 2)
2) Is it possible assign 1D array(range 1 to N) to one row of 2D array (Also outside of process)?
Upvotes: 1
Views: 2750
Reputation: 16221
Yes you can do this by writing a procedure like this one:
procedure assign_row(signal slm : out T_SLM; slv : STD_LOGIC_VECTOR; constant RowIndex : NATURAL) is
variable temp : STD_LOGIC_VECTOR(slm'high(2) downto slm'low(2)); -- Xilinx iSIM work-around, because 'range(2) evaluates to 'range(1); tested with ISE XST/iSim 14.2
begin
temp := slv;
for i in temp'range loop
slm(RowIndex, i) <= temp(i);
end loop;
end procedure;
Where T_SLM is my matrix type defined like this:
-- STD_LOGIC_MATRIXs
type T_SLM is array(NATURAL range <>, NATURAL range <>) of STD_LOGIC;
-- ATTENTION:
-- 1. you MUST initialize your matrix signal with 'Z' to get correct simulation results (iSim, vSim, ghdl/gtkwave)
-- Example: signal myMatrix : T_SLM(3 downto 0, 7 downto 0) := (others => (others => 'Z'));
-- 2. Xilinx iSIM work-around: DON'T use myMatrix'range(n) for n >= 2
-- because: myMatrix'range(2) returns always myMatrix'range(1); tested with ISE/iSim 14.2
-- USAGE NOTES:
-- dimension 1 => rows - e.g. Words
-- dimension 2 => columns - e.g. Bits/Bytes in a word
So here is an example to use this procedure:
architecture [...]
signal myVector : STD_LOGIC_VECTOR(7 downto 0);
signal myMatrix : T_SLM(3 downto 0, myVector'range) := (others => (others => 'Z'));
[...]
begin
[...]
assign_row(myMatrix, myVector, 0);
assign_row(myMatrix, (myVector'range => '0'), 1);
assign_row(myMatrix, x"4A", 2);
[...]
end;
This code is tested with ISE XST and iSim (13.x, 14.x), vSim and GHDL. As ISE 13.x was the current release, Xilinx stated that the range-bug will not be fixed in ISE 14.x.
If you need the other way around, here is my function get_row:
-- get a matrix row
function get_row(slm : T_SLM; RowIndex : NATURAL) return STD_LOGIC_VECTOR is
variable slv : STD_LOGIC_VECTOR(slm'high(2) downto slm'low(2)); -- Xilinx iSim work-around, because 'range(2) = 'range(1); tested with ISE/iSim 14.2
begin
for i in slv'range loop
slv(i) := slm(RowIndex, i);
end loop;
return slv;
end function;
If you want to use NATURAL as the elementary type for the vectors and matrices, then exchange STD_LOGIC with NATURAL.
Upvotes: 1
Reputation:
1) Is it possible to fill elements m(0, 1), m(0, 2) ... m(0, N) with some value outside of process?
2) Is it possible assign 1D array(range 1 to N) to one row of 2D array (Also outside of process)?
Yes it's possible. I'll only give an example for loading a new row. Note this example is for N = 4, the method can be impractical for larger arrays.
Also note this only allows stactic indices.
entity foo is
constant N: natural := 4;
end entity;
architecture fum of foo is
type MATR is array(natural range 1 to N, natural range 1 to N) of natural;
type col is array (natural range 1 to N) of natural;
constant f:col := (1,2,3,4);
signal m: MATR;
begin
m <= (1 => ( 1 => f(1), 2 => f(2), 3 => f(3), 4 => f(4)),
2 => ( 1 => m(2,1), 2 => m(2,2), 3 => m(2,3), 4 => m(2,4)),
3 => ( 1 => m(3,1), 2 => m(3,2), 3 => m(3,3), 4 => m(3,4)),
4 => ( 1 => m(4,1), 2 => m(4,2), 3 => m(4,3), 4 => m(4,4)));
end architecture;
(And perhaps your question(s) should be a bit more explicit. For your purposes the answer may not be practicable.)
Upvotes: 0