Multiplier using 1 bit full adder problem

Guest
I have a problem , when I execute my code, the output is undesigned. Anyone can help me? My code is as followed
--multiplier
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity Multiplier_VHDL is
GENERIC (WIDTH:INTEGER);
PORT(a:IN STD_LOGIC_VECTOR(WIDTH-1 DOWNTO 0);
b:IN STD_LOGIC_VECTOR(WIDTH-1 DOWNTO 0);
y:OUT STD_LOGIC_VECTOR(2*WIDTH-1 DOWNTO 0));
end entity Multiplier_VHDL;

architecture Behavioral of Multiplier_VHDL is

signal a_temp:std_logic_vector(width-1 downto 0);
signal a_temp_1:std_logic_vector(width-1 downto 0);
signal a_temp_2:std_logic_vector(width-1 downto 0);
signal cout_a:std_logic_vector(width-1 downto 0);

signal b_temp:std_logic_vector(width-1 downto 0);
signal b_temp_1:std_logic_vector(width-1 downto 0);
signal b_temp_2:std_logic_vector(width-1 downto 0);
signal cout_b:std_logic_vector(width-1 downto 0);
signal y_temp:std_logic_vector(2*width-1 downto 0):=(others=>'0');
signal y_ready:std_logic_vector(2*width-1 downto 0);
signal cin:std_logic_vector(2*width downto 0);
signal cout:std_logic_vector(2*width-1 downto 0);
signal mid_temp_a:std_logic_vector(2*width-1 downto 0):=(others=>'0');
signal mid_temp:std_logic_vector(2*width-1 downto 0):=(others=>'0');

begin
--inverse calculation of a
iteration_a1:
for i in 0 to width-1 generate
a_temp_1(i)<= not a(i);
end generate iteration_a1;
a_temp_2(0)<=a_temp_1(0) xor '1';
cout_a(0)<=a_temp_1(0) and '1';
iteration_a2:
for i in 1 to width-1 generate
a_temp_2(i)<=a_temp_1(i) xor cout_a(i-1);
cout_a(i)<=a_temp_1(i) and cout_a(i-1);
end generate iteration_a2;
a_temp<=a when a(width-1)='0' else
a_temp_2;
--inverse calculation of b
iteration_b1:
for i in 0 to width-1 generate
b_temp_1(i)<= not b(i);
end generate iteration_b1;
b_temp_2(0)<=b_temp_1(0) xor '1';
cout_b(0)<=b_temp_1(0) and '1';
iteration_b2:
for i in 1 to width-1 generate
b_temp_2(i)<=b_temp_1(i) xor cout_b(i-1);
cout_b(i)<=b_temp_1(i) and cout_b(i-1);
end generate iteration_b2;
b_temp<=b when b(width-1)='0' else
b_temp_2;
mid_temp_a(width-1 downto 0)<=a_temp;

iteration_out:
for i in 0 to width-1 generate
cin(0)<='0';
mid_temp_a<=mid_temp_a(2*width-2 downto 0) & '0';
mid_temp<=mid_temp_a when b(i)='1' else
(others=>'0') when b(i)='0';
iteration_in:
--y_temp is a while mid_temp is b
for j in 0 to 2*width-1 generate
y_ready1(j)<=y_temp(j) xor mid_temp(j) xor cin(j);
cout(j)<=(y_temp(j) and mid_temp(j)) or (y_temp(j) and cin(j)) or (cin(j) and mid_temp(j));
cin(j+1)<=cout(j);
end generate iteration_in;
y_temp<=y_ready1;

end generate iteration_out;
y<=y_ready;






end architecture Behavioral;
 
On 9/24/2015 2:33 PM, zhangth1991@gmail.com wrote:
> I have a problem , when I execute my code, the output is undesigned.

Of course your output is designed. You must be looking at the output
wrong.


Anyone can help me? My code is as followed
--multiplier
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity Multiplier_VHDL is
GENERIC (WIDTH:INTEGER);
PORT(a:IN STD_LOGIC_VECTOR(WIDTH-1 DOWNTO 0);
b:IN STD_LOGIC_VECTOR(WIDTH-1 DOWNTO 0);
y:OUT STD_LOGIC_VECTOR(2*WIDTH-1 DOWNTO 0));
end entity Multiplier_VHDL;

architecture Behavioral of Multiplier_VHDL is

signal a_temp:std_logic_vector(width-1 downto 0);
signal a_temp_1:std_logic_vector(width-1 downto 0);
signal a_temp_2:std_logic_vector(width-1 downto 0);
signal cout_a:std_logic_vector(width-1 downto 0);

signal b_temp:std_logic_vector(width-1 downto 0);
signal b_temp_1:std_logic_vector(width-1 downto 0);
signal b_temp_2:std_logic_vector(width-1 downto 0);
signal cout_b:std_logic_vector(width-1 downto 0);
signal y_temp:std_logic_vector(2*width-1 downto 0):=(others=>'0');
signal y_ready:std_logic_vector(2*width-1 downto 0);
signal cin:std_logic_vector(2*width downto 0);
signal cout:std_logic_vector(2*width-1 downto 0);
signal mid_temp_a:std_logic_vector(2*width-1 downto 0):=(others=>'0');
signal mid_temp:std_logic_vector(2*width-1 downto 0):=(others=>'0');

begin
--inverse calculation of a
iteration_a1:
for i in 0 to width-1 generate
a_temp_1(i)<= not a(i);
end generate iteration_a1;
a_temp_2(0)<=a_temp_1(0) xor '1';
cout_a(0)<=a_temp_1(0) and '1';
iteration_a2:
for i in 1 to width-1 generate
a_temp_2(i)<=a_temp_1(i) xor cout_a(i-1);
cout_a(i)<=a_temp_1(i) and cout_a(i-1);
end generate iteration_a2;
a_temp<=a when a(width-1)='0' else
a_temp_2;
--inverse calculation of b
iteration_b1:
for i in 0 to width-1 generate
b_temp_1(i)<= not b(i);
end generate iteration_b1;
b_temp_2(0)<=b_temp_1(0) xor '1';
cout_b(0)<=b_temp_1(0) and '1';
iteration_b2:
for i in 1 to width-1 generate
b_temp_2(i)<=b_temp_1(i) xor cout_b(i-1);
cout_b(i)<=b_temp_1(i) and cout_b(i-1);
end generate iteration_b2;
b_temp<=b when b(width-1)='0' else
b_temp_2;
mid_temp_a(width-1 downto 0)<=a_temp;

iteration_out:
for i in 0 to width-1 generate
cin(0)<='0';
mid_temp_a<=mid_temp_a(2*width-2 downto 0) & '0';
mid_temp<=mid_temp_a when b(i)='1' else
(others=>'0') when b(i)='0';
iteration_in:
--y_temp is a while mid_temp is b
for j in 0 to 2*width-1 generate
y_ready1(j)<=y_temp(j) xor mid_temp(j) xor cin(j);
cout(j)<=(y_temp(j) and mid_temp(j)) or (y_temp(j) and cin(j)) or (cin(j) and mid_temp(j));
cin(j+1)<=cout(j);
end generate iteration_in;
y_temp<=y_ready1;

end generate iteration_out;
y<=y_ready;






end architecture Behavioral;


--

Rick
 
On 9/24/2015 4:59 PM, zhangth1991@gmail.com wrote:
> no, the output is U all the time

Have you traced it back through the logic? Where does the U originate?

--

Rick
 
I think it is caused by the iteration_in, because before I use the inner iteration, the output is generated. Now the output is U after the first change of a and b
 
On 24/09/2015 19:33, zhangth1991@gmail.com wrote:
I have a problem , when I execute my code, the output is undesigned. Anyone can help me? My code is as followed
--multiplier
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity Multiplier_VHDL is
GENERIC (WIDTH:INTEGER);
PORT(a:IN STD_LOGIC_VECTOR(WIDTH-1 DOWNTO 0);
b:IN STD_LOGIC_VECTOR(WIDTH-1 DOWNTO 0);
y:OUT STD_LOGIC_VECTOR(2*WIDTH-1 DOWNTO 0));
end entity Multiplier_VHDL;

architecture Behavioral of Multiplier_VHDL is

signal a_temp:std_logic_vector(width-1 downto 0);
signal a_temp_1:std_logic_vector(width-1 downto 0);
signal a_temp_2:std_logic_vector(width-1 downto 0);
signal cout_a:std_logic_vector(width-1 downto 0);

signal b_temp:std_logic_vector(width-1 downto 0);
signal b_temp_1:std_logic_vector(width-1 downto 0);
signal b_temp_2:std_logic_vector(width-1 downto 0);
signal cout_b:std_logic_vector(width-1 downto 0);
signal y_temp:std_logic_vector(2*width-1 downto 0):=(others=>'0');
signal y_ready:std_logic_vector(2*width-1 downto 0);
signal cin:std_logic_vector(2*width downto 0);
signal cout:std_logic_vector(2*width-1 downto 0);
signal mid_temp_a:std_logic_vector(2*width-1 downto 0):=(others=>'0');
signal mid_temp:std_logic_vector(2*width-1 downto 0):=(others=>'0');

begin
--inverse calculation of a
iteration_a1:
for i in 0 to width-1 generate
a_temp_1(i)<= not a(i);
end generate iteration_a1;
a_temp_2(0)<=a_temp_1(0) xor '1';
cout_a(0)<=a_temp_1(0) and '1';
iteration_a2:
for i in 1 to width-1 generate
a_temp_2(i)<=a_temp_1(i) xor cout_a(i-1);

As a quick guess I would say you may be hitting the longest static
prefix issue. Have a look at section 4.2.13 of the VHDL FAQ:

https://tams.informatik.uni-hamburg.de/vhdl/doc/faq/FAQ1.html

Good luck,
Hans
www.ht-lab.com



cout_a(i)<=a_temp_1(i) and cout_a(i-1);
end generate iteration_a2;
a_temp<=a when a(width-1)='0' else
a_temp_2;
--inverse calculation of b
iteration_b1:
for i in 0 to width-1 generate
b_temp_1(i)<= not b(i);
end generate iteration_b1;
b_temp_2(0)<=b_temp_1(0) xor '1';
cout_b(0)<=b_temp_1(0) and '1';
iteration_b2:
for i in 1 to width-1 generate
b_temp_2(i)<=b_temp_1(i) xor cout_b(i-1);
cout_b(i)<=b_temp_1(i) and cout_b(i-1);
end generate iteration_b2;
b_temp<=b when b(width-1)='0' else
b_temp_2;
mid_temp_a(width-1 downto 0)<=a_temp;

iteration_out:
for i in 0 to width-1 generate
cin(0)<='0';
mid_temp_a<=mid_temp_a(2*width-2 downto 0) & '0';
mid_temp<=mid_temp_a when b(i)='1' else
(others=>'0') when b(i)='0';
iteration_in:
--y_temp is a while mid_temp is b
for j in 0 to 2*width-1 generate
y_ready1(j)<=y_temp(j) xor mid_temp(j) xor cin(j);
cout(j)<=(y_temp(j) and mid_temp(j)) or (y_temp(j) and cin(j)) or (cin(j) and mid_temp(j));
cin(j+1)<=cout(j);
end generate iteration_in;
y_temp<=y_ready1;

end generate iteration_out;
y<=y_ready;

end architecture Behavioral;
 
On 9/25/2015 1:21 AM, zhangth1991@gmail.com wrote:
> I think it is caused by the iteration_in, because before I use the inner iteration, the output is generated. Now the output is U after the first change of a and b

To be honest, I've never tried debugging generated code, mainly because
I seldom write generated code. Why are you writing generated code
rather than much simpler straight VHDL?

For example, instead of four lines of generated code iteration_a1: could
just be...

a_temp_1 <= not a;

iteration_a2: could be...

a_temp_2 <= a_temp_1 xor (cout_a(width-2 downto 0) & '1');
cout_a <= a_temp_1 and (cout_a(width-2 downto 0) & '1');

Isn't this much simpler?

What is the source of information on how to construct your logic? Do
you have equations or a verbal description of how it is supposed to work?

--

Rick
 
It is a vector multiplier which use a full adder. And we should judge if a or b is positive and negative to get correct answer.
 

Welcome to EDABoard.com

Sponsor

Back
Top