0
votes

I'm trying to build and synthesize an ALU in VHDL but I get a problem as soon as I synthesize. I'd like my ALU to have a op-code for adding my two N-bits inputs and a carry that may be set by an input or by a sum that was calculated earlier. The part of the code I'm interested in is as follow:

process (a, b, op) -- a and b are n bits input en op is the op-code
    case op is
        when "011" => -- add a + b + c (with c as carry)
            y <= ('0' & a) + ('0' & b) + c; -- y is the N-bit output
...
end process;

process (clk)
   if (clk'event and clk = '1') then
       if (op = "011" and (to_integer(a)+to_integer(b)+to_integer(c)) > (2**N)) then --basically I'm testing if there is an overflow during the calculation
           c <= '1';
       elsif (op = "011" and (to_integer(a)+to_integer(b)+to_integer(c)) < ((2**N)+1))
           c <= '0';
...
end process;

I'm not sure if the code will work here because I didn't define the signal types, but basically it comes down to what I've written above. The problem with this is that when I simulate my VHDL with an appropriate testbench, it works as it should but when I synthesize this code and simulate the synthesized code with the same testbench, it doesn't work properly because then somehow the first process is repeated again even if a, b or op didn't change. So when the outcome of the sum has a carry, the calculation is done again with this new carry and the outcome is incremented by one even if a, b or op aren't changed!

Later on I found this article saying that the sensitivity list is "ignored" by the compiler how thinks he knows the program better than you and makes its own sensitivity list. If this is true, I guest the compiler adds clk in the sensitivity list of the first process so the calculation is ran on every clk period when the op = "011".

My question comes now: what can I do about this problem so that the calculation is run once and that the carry is changed after it?

Kind regards

1
Stop writing code. Draw a picture first. Code your picture. Did you intend to connect carry out to carry in?Jim Lewis
Can you clarify what you mean when you say I'd like my ALU to have a op-code for adding my two N-bits inputs and a carry that may be set by an input or by a sum that was calculated earlier. It seems you are confused between carryin and carryout. Generally these are two separate things. Why do you want to add the carry generated by the adder (carryout) to the input numbers again ?shrm

1 Answers

0
votes

As others have pointed out, there are a few problems with your code. I'll try to suggest some improvements, and then show a possible way for calculating the carry flag:

  1. Make a distinction between the carry in and carry out signals. Use communicative names for your signals, such as carry_in and carry_out. This will remove much of the confusion.

  2. Define a constant or an enumerated type for your ALU operations. For instance:

    subtype opcode_type is std_logic_vector(2 downto 0);
    constant ADC: opcode_type := "011";  -- ADC: add with carry
    
  3. Finally, if you are using VHDL 2008, you can generate your carry out using an aggregate as the assignment target:

    (carry_out, y) <= ('0' & a) + ('0' & b) + carry_in;
    

Your code would end up looking like this:

process (all)
    case op is
        when ADC => -- add a + b + c (with c as carry)
            (carry_out, y) <= ('0' & a) + ('0' & b) + carry_in;
    ...
end process;

process (clk)
    if rising_edge(clk) then
        carry_flag <= carry_out;
    ...
end process;