0

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. enter image description here

The image above is my main BDF.

enter image description here

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:

enter image description here

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:

enter image description here

  • An attractive question but [Some questions are still off-topic, even if they fit into one of the categories listed above](http://stackoverflow.com/help/on-topic): 1. Questions seeking debugging help ("why isn't this code working?") must include the desired behavior, a specific problem or error and the shortest code necessary to reproduce it in the question itself. Questions without a clear problem statement are not useful to other readers. See: [How to create a Minimal, Complete, and Verifiable example](http://stackoverflow.com/help/mcve). –  Jun 02 '16 at 22:40
  • 1
    The summing in the process in your adder doesn't appear to match Frank Vahid's Slide 63. –  Jun 02 '16 at 22:44
  • No, Vahid's slide shows a 4 bit multiplier with 3 adders, what I'm trying To do is a 8 bit multiplier using only 1 adder(abstracating all the others inside this one), that's why I think the error is on the adder, but I didn't find where it is. –  Jun 03 '16 at 03:20
  • That should be "value for this product is 42875". You incorrectly calculate the carry in a product bit column where the column sum is the [Hamming weight](https://en.wikipedia.org/wiki/Hamming_weight) for the number of '1's (popcount). Hamming weight can be simulated with loop statements while a synthesized result would be much slower and larger than the 7 additions for 8 bit operands implied by Vahid requiring 14 different weighting network sizes. –  Jun 04 '16 at 20:09
  • I noticed that the carry is wrong, my solution for this was use 1 half adder and 6 full adder by one product, totally was used 8 half adders and 48 full adders to solve my problem! –  Jun 05 '16 at 15:48

2 Answers2

0

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:

enter image description here

Totally were used:

64 AND gates; 8 Half Adders; 48 full adders.

0

I think the primary problem lies in the bitwise code meant to do the summing:

        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;

c here is just one bit, which is rather inadequate as carry for nine terms (eight aux bits and the carry in, so this feeds back to produce more terms when we expand the carry sufficiently). If we were to assume those nine bits were enough, you'd still be getting values up to 9 which requires four bits in binary, thus at least three carries. This happens as soon as you have more than three terms; a full adder sums from 1+1+1 to 2+1 (one bit having higher weight), using all values of its output. Since that's a reduction they can be chained in layers, but a larger adder must use more output bits (for instance, a 5 input adder could produce 2+2+1, a 7 bit adder could be fashioned to produce 4+2+1); we see this if we count the carry lines between columns in your array multiplier schematic. There are as many carries around the middle column as there are bits in the factors.

Yann Vernier
  • 15,414
  • 2
  • 28
  • 26