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.
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;