user9511374
user9511374

Reputation:

Implementations of an Adder in VHDL comparison

Can someone explain me why this implementation works

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;

entity Adder is
    port(A: in std_logic_vector(3 downto 0);
    B: in std_logic_vector(3 downto 0);
    SUM: out std_logic_vector(3 downto 0);
    CO: out std_logic);
end;

architecture DescriptionAdders of Adder is

signal temp:  std_logic_vector(4 downto 0);
signal temp1: std_logic_vector(4 downto 0);
signal temp2: std_logic_vector(4 downto 0);

begin

temp1 <= '0' & A;
temp2 <= '0' & B;
temp <= std_logic_vector(unsigned(temp1) + unsigned(temp2));

SUM <= temp(3 downto 0);
CO <= temp(4);

end;

while this doesn't (the SUM is XX when it starts running, then it is always one step behind the real result, but the temps update well).

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;

entity Adder is
    port(A: in std_logic_vector(3 downto 0);
    B: in std_logic_vector(3 downto 0);
    SUM: out std_logic_vector(3 downto 0);
    CO: out std_logic);
end;

architecture DescriptionAdders of Adder is

signal temp:  std_logic_vector(4 downto 0);
signal temp1: std_logic_vector(4 downto 0);
signal temp2: std_logic_vector(4 downto 0);

begin

process(A, B) is
begin
    temp1 <= '0' & A;
    temp2 <= '0' & B;
    temp <= std_logic_vector(unsigned(temp1) + unsigned(temp2));
end process;

SUM <= temp(3 downto 0);
CO <= temp(4);

end;

Sorry if the question is too easy, I'm a begginer.

Upvotes: 0

Views: 309

Answers (1)

JHBonarius
JHBonarius

Reputation: 11261

This question seems to be based about a common misconception of how VHDL simulation works.

process(A, B)

means the process will be triggered at an event of A or B. What happens in the process are assignments to additional objects

temp1 <= '0' & A;
temp2 <= '0' & B;
temp <= std_logic_vector(unsigned(temp1) + unsigned(temp2));

This means three events will be scheduled, one to each of temp1, temp2 and temp. But the way VHDL works, the actual assignments will not occur until the next delta cycle. Which occurs after the process is evaluated. So even though the lines for assignment to temp1 and temp2 are located before the assignemnt to temp, their values have not been changed yet.

Considering values of temp1 and temp2 change after the process is finished, the assignment to temp is missed. Unless you re-enter the process, by adding the objects to the sensitivity list. E.g.

process(A, B, temp1, temp2) is
begin
    temp1 <= '0' & A;
    temp2 <= '0' & B;
    temp <= std_logic_vector(unsigned(temp1) + unsigned(temp2));
end process;

An alternative solution would be to use variables, which can change inside of the process. But please note that variables can cause difficulties in logic synthesis if not properly used. This example will work:

process(A, B) is
    variable temp1, temp2 : std_logic_vector(4 downto 0);
begin
    temp1 := '0' & A;
    temp2 := '0' & B;
    temp <= std_logic_vector(unsigned(temp1) + unsigned(temp2));
end process;

But the question is: why do you need temp1 and temp2 at all. Just write

process(A, B) is
begin
    temp <= std_logic_vector(unsigned('0' & A) + unsigned('0' & B));
end process;

Or a bit more flexible

process(A, B) is
begin
    temp <= std_logic_vector(
        resize(unsigned(A), temp'length) +
        resize(unsigned(B), temp'length));
end process;

Or even using the integer type (limited to 32 bits!)

process(A, B) is
begin
    temp <= std_logic_vector(to_unsigned(
        to_integer(unsigned(A)) + to_integer(unsigned(B))
        , temp'length));
end process;

Upvotes: 2

Related Questions