0

here is a generic code of a cascade full adder.

the problem is that the result of the fulladder appears with one event delay(I mean that when I change inputs1 & inputs2 the result of the previous inputs appears). I know that if I write the code without a process this delay wouldn't occur but I need to write a generic fulladder and there is no way to write a generic code without a process and a for loop.

so I'm asking if anyone could help me to fix the code so that the output would show the results with no delay!!!

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;

entity adders is
    generic(
        numberOfInputs : Integer := 4
    ); port(
        enable  : in std_logic;
        cin     : in std_logic;
        inputs1 : in std_logic_vector(numberOfInputs-1 downto 0);
        inputs2 : in std_logic_vector(numberOfInputs-1 downto 0);
        outputs : out std_logic_vector(numberOfInputs downto 0)
    );
end entity adders;

architecture Generic_Adder of adders is
    signal Couts:std_logic_vector(numberOfInputs downto 0);
    signal temp1:std_logic_vector(numberOfInputs-1 downto 0);
    signal temp2:std_logic_vector(numberOfInputs-1 downto 0);
    signal temp3:std_logic_vector(numberOfInputs-1 downto 0);

begin

    temp2<=inputs1;
    temp3<=inputs2;  
    couts(0)<= cin;

    Sum:process(temp2,temp3,cin,enable,Couts) is
    begin
        for count in 0 to numberOfInputs-1 loop
            temp1(count) <= (temp2(count) xor temp3(count));
            outputs(count) <= Couts(count) xor temp1(count);
            Couts(count+1) <= (temp2(count) and temp3(count)) or(couts(count) and temp1(count));--cout(count) is the previuos cout becuase the first cout is cin
        end loop;
    end process;

    outputs(numberOfInputs) <= Couts(numberOfInputs);
end Generic_Adder;

2 Answers 2

3

The temp1 signal is used in the process, but it is missing in the sensitivity list.

Changes in temp1 will therefore not trigger reevaluation of the process, and the a new value of temp1 is not reflected in other driven signals until another signal trigger reevaluation, hence you are likely to experience a "delay".

Fix this by adding temp1 to the sensitivity list, or rewrite as suggested by Bill Lynch or if you are using VHDL-2008 and compatible compiler, then the sensitivity list can be process (all) ....

In addition, a VHDL issue related to "longest static prefix" is encountered due to the drive of outputs by loop in the process and outputs(numberOfInputs) outside the process. The result is that outputs(numberOfInputs) has a driver as 'U' from the process and a driver as Couts(numberOfInputs) outside the process. The resulting value, based on the std_logic resolution function, is a value of ´'U'´.

One way to fix this issue, when keeping the process, is to move the outputs(numberOfInputs) inside the process, like:

        ...
    end loop;
    outputs(numberOfInputs) <= Couts(numberOfInputs);
end process;

This answer https://stackoverflow.com/a/18248941/2352082 has more information about VHDL longest static prefix.

Sign up to request clarification or add additional context in comments.

5 Comments

or if they are using a new enough compiler: process (all). Additionally cin and enable are not needed in the sensitivity list. And I'm not sure how they are going to write this without a latch if they want to actually use the enable bit and have the output be held.
You can also have temp1 be a variable instead of a signal. In that case, it doesn't have to be a vector, in simple std_logic would be fine.
the was no delay in the output but the outputs(1) and outputs(2) are unknown(u)!!??how do I fix that??
If outputs(1) or outputs(2) are unknown 'X' it is probably due to unknown 'X' input data. But the MSB outputs(4) will actually become unknown 'X' due to an VHDL issue called "longest static prefix"; please see update in the answer.
Btw. the carry generation by Couts looks wrong; see Bill Lynch answer for carry generation.
1

You can use a generate statement to write iterative code outside of a process statement. It would probably look something like this:

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;

entity adders is
    generic(
        numberOfInputs : Integer := 4
    ); port(
        enable  : in std_logic;
        cin     : in std_logic;
        inputs1 : in std_logic_vector(numberOfInputs-1 downto 0);
        inputs2 : in std_logic_vector(numberOfInputs-1 downto 0);
        outputs : out std_logic_vector(numberOfInputs downto 0)
    );
end entity adders;

architecture Generic_Adder of adders is
    signal carry  : std_logic_vector(numberOfInputs     downto 0);
    signal result : std_logic_vector(numberOfInputs - 1 downto 0);
begin

    carry(0) <= cin;

    for I in 0 to numberOfInputs-1 generate
    begin
        result(I) <= inputs1(I) xor inputs2(I) xor carry(I);
        carry(I+1) <= 
            (inputs1(I) and inputs2(I)) or 
            (inputs1(I) and carry(I))   or
            (inputs2(I) and carry(I));
    end generate;

    outputs <= carry(numberOfInputs) & result;

end Generic_Adder;

1 Comment

@BillLynch: In result(I) the + should be xor.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.