I'm trying to make a 8 bits Array Multiplier in VHDL, I am using the standard architecture of the array multiplier to do this, i have a BDF file receiving the A(multiplicand) and B(multiplier), and in this BDF file have a block named "adder" that makes the sums from the products of A and B. I'm having problems with the sum output, its showing a much lower number from the correct value.
The image above is my main BDF.
The image above shows de connections from and_arrays to the adder.
Adder code:
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE IEEE.std_logic_unsigned.ALL;
use IEEE.std_logic_arith.ALL;
use IEEE.numeric_std.ALL;
ENTITY adder IS
PORT (i_IN0 : IN STD_LOGIC_VECTOR(7 downto 0);-- data input
i_IN1 : IN STD_LOGIC_VECTOR(7 downto 0);-- data input
i_IN2 : IN STD_LOGIC_VECTOR(7 downto 0);-- data input
i_IN3 : IN STD_LOGIC_VECTOR(7 downto 0);-- data input
i_IN4 : IN STD_LOGIC_VECTOR(7 downto 0);-- data input
i_IN5 : IN STD_LOGIC_VECTOR(7 downto 0);-- data input
i_IN6 : IN STD_LOGIC_VECTOR(7 downto 0);-- data input
i_IN7 : IN STD_LOGIC_VECTOR(7 downto 0);-- data input
o_Q : OUT STD_LOGIC_VECTOR(15 DOWNTO 0);
o_COUT : OUT STD_LOGIC);-- data output
END adder;
architecture arch1 of adder is
begin
process(i_IN0, i_IN1, i_IN2, i_IN3, i_IN4, i_IN5, i_IN6, i_IN7)
variable soma:std_logic_vector(14 downto 0);
variable aux0:std_logic_vector(14 downto 0);
variable aux1:std_logic_vector(14 downto 0);
variable aux2:std_logic_vector(14 downto 0);
variable aux3:std_logic_vector(14 downto 0);
variable aux4:std_logic_vector(14 downto 0);
variable aux5:std_logic_vector(14 downto 0);
variable aux6:std_logic_vector(14 downto 0);
variable aux7:std_logic_vector(14 downto 0);
variable c:std_logic; -- carry in
BEGIN
aux0(7 downto 0) := i_IN0; aux0(14 downto 8) := "0000000"; -- here i'm trying to shift the 8 nbit input value
aux1(0) := '0'; aux1(8 downto 1) := i_IN1; aux1(14 downto 9) := "000000"; -- to a 15 bit value to the sums
aux2(1 downto 0) := "00";aux2(9 downto 2) := i_IN2; aux2(14 downto 10) := "00000"; -- looking to the array multiplier
aux3(2 downto 0) := "000";aux3(10 downto 3) := i_IN3; aux3(14 downto 11) := "0000"; -- architecture, it seem to be
aux4(3 downto 0) := "0000";aux4(11 downto 4) := i_IN4; aux4(14 downto 12) := "000"; -- correct
aux5(4 downto 0) := "00000";aux5(12 downto 5) := i_IN5; aux5(14 downto 13) := "00";
aux6(5 downto 0) := "000000"; aux6(13 downto 6) := i_IN6; aux6(14) := '0';
aux7(6 downto 0) := "0000000"; aux7(14 downto 7) := i_IN7;
-- below the loop that make the sums bit-in-bit, i've addapted this code from a 8 bit adder
c := '0';
for i in 0 to 14 loop
soma(i) := aux0(1) xor aux1(i) xor aux2(i) xor aux3(i) xor aux4(i) xor aux5(i) xor aux6(i) xor aux7(i) xor c;
c := (aux0(i) and aux1(i) and aux2(i) and aux3(i) and aux4(i) and aux5(i) and aux6(i) and aux7(i)) or ((aux0(i) xor aux1(i) xor aux2(i) xor aux3(i) xor aux4(i) xor aux5(i) xor aux6(i) xor aux7(i)) and c);
end loop;
o_COUT <= c;
o_Q(15) <= c; -- carry out atribuition to the last bit of the vector
o_Q(14 downto 0) <= soma;
end process;
end arch1;
AND ARRAY CODE:
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE IEEE.std_logic_unsigned.ALL;
use IEEE.std_logic_arith.ALL;
ENTITY and_array IS
PORT (i_MULTIPLICANDO : IN STD_LOGIC_VECTOR(7 downto 0);-- data input
i_MULTIPLICADOR : IN STD_LOGIC;-- data input
o_Q : OUT STD_LOGIC_VECTOR(7 DOWNTO 0));-- data output
END and_array;
ARCHITECTURE arch_1 OF and_array IS
BEGIN
GEN_REG:
FOR i IN 0 TO 7 GENERATE
o_Q(i) <= i_MULTIPLICADOR and i_MULTIPLICANDO(i);
END GENERATE GEN_REG;
END arch_1;
I've made simulation for this two blocks, the and array blocks works perfectly, but the error appears in the adder simulation, below the imagem from the simulation:
I'am simulating the following inputs:
Multiplicand = 1 1 1 1 0 1 0 1 (245 dec)
Multiplier = 1 0 1 0 1 1 1 1 (175 dec)
The correct value for this product is 42785, in my simulation appears 24899
I am using the following logic to the sums in adder:
1 1 1 1 0 1 0 1
1 0 1 0 1 1 1 1
-----------------
x x x x x x x 1 1 1 1 0 1 0 1 p1
x x x x x x 1 1 1 1 0 1 0 1 x p2
x x x x x 1 1 1 1 0 1 0 1 x x p3
x x x x 1 1 1 1 0 1 0 1 x x x p4
x x x 0 0 0 0 0 0 0 0 x x x x p5
x x 1 1 1 1 0 1 0 1 x x x x x p6
x 0 0 0 0 0 0 0 0 x x x x x x p7
1 0 1 0 1 1 1 1 x x x x x x x p8
_________________________________________
In the adder block i've changed all the "X's" for 0 to the sum (Like a shift). In the loop of the adder block the sums of p1 to p8, is made bit-in-bit. Probably the error it's in this loop or in the carry, but i've tried to do this from many forms and always goes wrong.
Someone have any idea how to fix this?
Below it's the main circuit abstraction image:
The solution for this problem was use half adders and full adders in the place of the adder shown above in the question.
It was used the logic below:
Totally were used:
64 AND gates; 8 Half Adders; 48 full adders.