0
votes

Trying to build a full adder using the theory found on wikipedia.

ie.

Sum = A XOR B XOR Cin Cout = A AND B OR C AND (A XOR B)

A and B are 32 bit

Here's my code

--Addition
        for i in 0 to 31 loop
            temp(i) <= a(i) XOR b(i) XOR cin;   
            if (((a(i) AND b(i)) OR (cin AND (a(i) XOR b(i)))) = '1') then
                cin <= '1';
                else
                cin <= '0';
            end if;
    end loop;
    cout <= cin;

When I simulate this, the cin is ignored. For example, 1011 + 0100 will give the right answer but 0001+0001 = 0.

Full CODE:

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_arith.ALL;
USE ieee.std_logic_unsigned.ALL;

ENTITY alu IS

PORT(
a: IN STD_LOGIC_VECTOR(31 DOWNTO 0);
b : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
op : IN STD_LOGIC_VECTOR( 2 DOWNTO 0);
result : OUT STD_LOGIC_VECTOR(31 DOWNTO 0);
cout : OUT STD_LOGIC;
zero : OUT STD_LOGIC);


END alu;
 --CIN is being inored for some reason. Must figure that out, and then code will start working. 

ARCHITECTURE description OF alu IS 
signal temp,cin :STD_LOGIC_VECTOR(31 DOWNTO 0);
 BEGIN
process(a,b,op)
    begin
    if (op = "000") then
        temp <= (a AND b);
    elsif (op = "001") then
        temp <= (a OR b);
    elsif (op = "010") then
    --Addition
    for i in 0 to 31 loop
                temp(i) <= a(i) XOR b(i) XOR cin(i);    
                cin(i+1) <= (  (a(i) AND b(i)) OR (cin AND (a(i) XOR b(i)))  ) 
            end loop;
    cout <= cin(31);

    elsif (op = "110") then
    --Subtraction   
    elsif (op = "100") then
        temp <= to_stdlogicvector(to_bitvector(a) sll 1);
    elsif (op = "101") then
        temp <= to_stdlogicvector(to_bitvector(a) srl 1);
    end if;

end process;
result <= temp;
END description;
1
This will only work if cin is a variable and your code snippet is hosted in a process. Can you past the complete source code incl. declarations and ports? - Paebbels
The code does other stuff, which is why I didn't include it in the beginning, but it's up now - The Muffin Boy
Your corrected code still has errors in it (and it's useful to note corrections or changes in your question). What happens with i = 31 in the loop and you try to assign cin(32) (i+1)? (It's a rhetorical question, VHDL will generate a run time error ). You also don't have cin in the sensitivity list. - user1155120
Thanks for pointing that out. I made it range from 0 to 32 and added it to the sensitivity - The Muffin Boy

1 Answers

1
votes

cin needs to be unique for each value of i:

library ieee;
use ieee.std_logic_1164.all;

entity loopy is
end entity;

architecture foo of loopy is

    signal a:       std_logic_vector (31 downto 0) := x"00000001";
    signal b:       std_logic_vector (31 downto 0) := x"00000001";
    signal sum:     std_logic_vector (31 downto 0);
    signal cout:    std_logic := '0';
    signal cin:     std_logic_vector (32 downto 0) := (others => '0');

    function slv_image(constant inp: std_logic_vector) return string is
        variable image_str: string (1 to inp'length);
        alias input_str:  std_logic_vector (1 to inp'length) is inp;
    begin
        for i in input_str'range loop
            image_str(i) := character'VALUE(std_ulogic'IMAGE(input_str(i)));
        end loop;
        return image_str;
    end function;
begin

LOOPER:
    process (a,b,cin)
    begin
        for i in 0 to 31 loop
            sum(i) <= a(i) XOR b(i) XOR cin(i);
            cin(i+1) <= (a(i) and b(i))  or  ( cin(i) and ( a(i)  xor b(i) ) );
        end loop;
    end process;

   cout <= cin(32);

MONITOR:
    process (sum)
    begin
        report "sum = "    & slv_image(sum(31 downto 0));
    end process;

end architecture;

And that gives:

adderloop.vhdl:40:9:@0ms:(report note): sum = uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
adderloop.vhdl:40:9:@0ms:(report note): sum = 00000000000000000000000000000000
adderloop.vhdl:40:9:@0ms:(report note): sum = 00000000000000000000000000000010

And the reason the first value wasn't affected is it doesn't use carry.

This shows three delta cycles, the last report is the correct value.