Adnan86
Full Member level 2
- Joined
- Apr 4, 2013
- Messages
- 121
- Helped
- 26
- Reputation
- 52
- Reaction score
- 26
- Trophy points
- 1,308
- Activity points
- 2,153
LIBRARY IEEE;
--USE ieee.std_logic_1164.all;
USE ieee.numeric_std.all;
PACKAGE matrix_pkg IS
type matrix_08 is array (integer range <>, integer range <>) of signed( 7 downto 0);
type matrix_16 is array (integer range <>, integer range <>) of signed(15 downto 0);
type matrix_32 is array (integer range <>, integer range <>) of signed(31 downto 0);
type matrix_64 is array (integer range <>, integer range <>) of signed(63 downto 0);
END PACKAGE ;
LIBRARY IEEE;
USE work.matrix_pkg.all ;
USE ieee.std_logic_1164.all;
USE ieee.numeric_std.all;
ENTITY MAC_matrix IS
GENERIC (M : integer:=3;
K : integer:=1;
N : integer:=2);
PORT (
a: IN matrix_16(1 to M, 1 to N); -- MxN matrix ;
b: IN matrix_16(1 to N, 1 to K); -- NxK matrix ;
clk: IN STD_LOGIC;
reset: IN STD_LOGIC;
--flag : IN std_logic := '0' ;
c: OUT matrix_32(1 to M, 1 to K)
) ;
END MAC_matrix;
ARCHITECTURE rtl OF MAC_matrix IS
SIGNAL x_a: matrix_16(1 to M, 1 to N);
SIGNAL x_b: matrix_16(1 to N, 1 to K);
SIGNAL x_c, x_reg: matrix_32(1 to M, 1 to K);
SIGNAL flag : std_logic := '0' ;
SIGNAL ii,jj,kk : integer := 1 ;
SIGNAL sum : signed(31 downto 0) ;
BEGIN
PROCESS (clk)
BEGIN
IF (clk'event and clk = '1') THEN
IF (reset = '1' and flag = '0') then
x_a <= (others=>(others => x"0000"));
x_b <= (others=>(others => x"0000"));
x_reg <= (others=>(others => x"00000000"));
x_c <= (others=>(others => x"00000000"));
sum <= x"00000000";
ELSIF (reset = '0' and flag = '0') THEN
x_a <= a;
x_b <= b;
flag <= '1' ;
-- END IF;
-- END IF ;
-- END process ;
-- PROCESS (clk)
-- BEGIN
-- IF (clk'event and clk = '1') THEN
ELSIF (reset = '0' and flag = '1') then
IF (ii <= M and jj <= N and kk <= K) then
x_reg(ii,kk) <= x_a(ii,jj) * x_b(jj,kk);
sum <= sum + x_reg(ii,kk);
jj <= jj + 1 ;
IF (jj > N) THEN
x_c(ii,kk) <= sum ;
END IF ;
ELSIF (ii <= M and jj > N and kk <= K) then
--ii <= ii + 1;
kk <= kk + 1 ;
jj <= 1 ;
sum <= x"00000000" ;
ELSIF (ii <= M and jj > N and kk > K) then
ii <= ii + 1;
kk <= 1 ;
jj <= 1 ;
sum <= x"00000000" ;
ELSE
c <= x_c ;
END IF ;
END IF ;
END IF;
END process;
c <= x_c ;
END rtl;
LIBRARY IEEE;
USE IEEE.std_logic_1164.all;
USE IEEE.numeric_std.all ;
USE work.matrix_pkg.all ;
ENTITY Mac_matrix_tb IS
END Mac_matrix_tb;
ARCHITECTURE test_mac_behav OF Mac_matrix_tb IS
constant M : integer := 3;
constant K : integer := 1;
constant N : integer := 2;
COMPONENT MAC_matrix IS
-- GENERIC (M : integer:=M;
-- K : integer:=K;
-- N : integer:=N);
PORT (
a: IN matrix_16(1 to M, 1 to N); -- MxN matrix ;
b: IN matrix_16(1 to N, 1 to K); -- NxK matrix ;
clk: IN STD_LOGIC;
reset: IN STD_LOGIC;
-- ready: IN STD_LOGIC;
c: OUT matrix_32(1 to M, 1 to K)
) ;
END COMPONENT;
SIGNAL a: matrix_16(1 to M, 1 to N); -- MxN matrix ;
SIGNAL b: matrix_16(1 to N, 1 to K); -- NxK matrix ;
SIGNAL clk : std_logic := '0' ;
--SIGNAL ready : std_logic := '0' ;
SIGNAL reset: STD_LOGIC := '1';
SIGNAL c: matrix_32(1 to M, 1 to K);
BEGIN
UUT : MAC_matrix
--generic map(M=>M,
-- N=>N,
-- K=>K);
PORT MAP (
a => a,
b => b,
clk=>clk,
reset => reset,
-- ready => ready,
c => c
);
clk <= NOT clk AFTER 10 NS ;
reset <= '0' AFTER 15 NS ;
--END ;
PROCESS --(clk)
BEGIN
WAIT FOR 20 NS;
a(1,1) <=x"0001";
a(1,2) <=x"0001";
a(2,1) <=x"0010";
a(2,2) <=x"0011";
a(3,1) <=x"0010";
a(3,2) <=x"0001";
b(1,1) <=x"0010";
b(2,1) <=x"0001";
WAIT FOR 10000 NS;
a(1,1) <=x"0001";
a(1,2) <=x"0001";
a(2,1) <=x"0010";
a(2,2) <=x"0011";
a(3,1) <=x"0010";
a(3,2) <=x"0001";
b(1,1) <=x"0010";
b(2,1) <=x"0001";
WAIT;
END PROCESS;
END ;
Hi
i want to implement , multiplication of 2 matrix. A[MxN]*B[Nxk]=C[MxK] .
I want this for implementation on FPGA with xilinx , before all i have no error with the code (on MODELSIM) .
but my output, get wrong answer , i don't where is my code wrong , so need help , plzzz
here my code :
output always wrong , i don't know why ?
I'll be so appreciate for help me .
thanks
IF (ii <= M and jj <= N and kk <= K) then
x_reg(ii,kk) <= x_a(ii,jj) * x_b(jj,kk);
sum <= sum + x_reg(ii,kk);
jj <= jj + 1 ;
IF (jj > N) THEN
x_c(ii,kk) <= sum ;
END IF ;
ELSIF (ii <= M and jj > N and kk < K) then
--ii <= ii + 1;
kk <= kk + 1 ;
jj <= 1 ;
sum <= x"00000000" ;
ELSIF (ii <= M and jj > N and kk > K) then
ii <= ii + 1;
kk <= 1 ;
jj <= 1 ;
sum <= x"00000000" ;
no i checked it , for example in this case K = 1 ; after the first pass of jj ; kk will be increment, but after that because of kk > K
Am i wright ?
just as a last question if i want use this program (code ) as COMPONENT , in another program , but need twice , it means one time AxB=C ,
and then use the answer of previews for second time such CxD=E ,how can i delay for second time till answer (C) be complete and then used it for second time .
thank you again , i really for 2 days ,couldn't find my problem but your guidance gave me clue to fix my problem .
ok thank you ...Don't think of your VHDL code as a program. VHDL doesn't execute on a microprocessor it doesn't execute in an FPGA or ASIC. It gets synthesized into gates and flip-flops (i.e. hardware).
To use the output of the first matrix multiplier for a second add a signal from the first that says the output of the C array is valid. That would load the input registers that feed the C and D inputs of the CXD=E matrix multiplier. Other options are add an enable signal to the matrix multiplier, make a top level FSM/sequencer that counts out clock cycles and enables (removes reset) from the matrix multipiers
This is why I originally commented on the flag logic...It's not a good way to disable the matrix multiplier or start it up.
You should have a reset (that's all it does is reset the design not for holding off startup) and you should have an enable/start signal along with a valid data output signal (which can be the start signal for the next module).
Regards
Understood , i really appreciate for giving your time , thanks so muchThe code you wrote will produce sequential logic, there's nothing inherently wrong with it. The indexing if it grows too large will be an issue as you are using registers (flip-flops) to implement the arrays. If you want more efficient code that can deal with much larger matrices then you need to implement this using a RAM.
Regards.
I did all you said and worked , but just one problem, as you see in my code for multiplication A,B as input are 16 bit and C as a output 32 bit .Don't think of your VHDL code as a program. VHDL doesn't execute on a microprocessor it doesn't execute in an FPGA or ASIC. It gets synthesized into gates and flip-flops (i.e. hardware).
To use the output of the first matrix multiplier for a second add a signal from the first that says the output of the C array is valid. That would load the input registers that feed the C and D inputs of the CXD=E matrix multiplier. Other options are add an enable signal to the matrix multiplier, make a top level FSM/sequencer that counts out clock cycles and enables (removes reset) from the matrix multipiers
This is why I originally commented on the flag logic...It's not a good way to disable the matrix multiplier or start it up.
You should have a reset (that's all it does is reset the design not for holding off startup) and you should have an enable/start signal along with a valid data output signal (which can be the start signal for the next module).
Regards
I really search for your suggestions , but not matrics , see i f it's not matrics i easyly could used this for resize :either make the widths generics and increase the bit widths or scale the values at the output.
x_a(15) <= C(31);
x_a(14 downto 0) <= C(14 downto 0);
I'm not really sure how to add a generic vector width to a 2D array that is defined in a package. I'm not a big fan of VHDL as I find I'm usually always trying to find a way around some seemingly restrictive aspect of the language. I feel Verilog is much more straight forward in how you code something.I really search for your suggestions , but not matrics , see i f it's not matrics i easyly could used this for resize :
but as you know C and x_a it's matrics , and we show any part of matrics with this for example C(mm,nn) , and if i used C(14 downto 0) , give me error because C it's 2D . for using Generic , i don't know how used it in PACKAGE !!!!Code:x_a(15) <= C(31); x_a(14 downto 0) <= C(14 downto 0);
sorry for asking too many questions ...
I have limited time for finish of this project and not expert in vhdl for that asked too many question.
- - - Updated - - -
I'm not really sure how to add a generic vector width to a 2D array that is defined in a package. I'm not a big fan of VHDL as I find I'm usually always trying to find a way around some seemingly restrictive aspect of the language. I feel Verilog is much more straight forward in how you code something.
Regards
- - - Updated - - -
I saw this on another post but I'm not sure it will work with Xilinx. I suspect they haven't added enough support for even this part of VHDL 2008
https://www.edaboard.com/threads/266446/
- - - Updated - - -
BTW Verilog doesn't support arrays passed through ports so I typically just make my ports like this input [mm*nn*width-1:0] a_port, and later in the code I use a for loop to assign the values to an actual array variable. It seems to me the added value (headaches) of having VHDL support for array in ports is not worth it.
My problem solved Thank you ads-ee .let's see what happen , i'll try to solve it .
Thanks for your help .
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?