EmbDev.net

Forum: FPGA, VHDL & Verilog 32-bit adder question


Author: DSP_Arch_Student (Guest)
Posted on:

Rate this post
0 useful
not useful
Hello,

I am trying to write a code for a 32-bit adder. I am having trouble 
where the carry in signal is not be registered at all. Here is my code, 
can you guys give me some insight as what is wrong, I think I might not 
be understanding some fundamental concepts associated with VHDL. I am 
new to VHDL, so I welcome all sort of critiques.

Thanks,
D_A_S

Code:
LIBRARY ieee;
use ieee.std_logic_1164.all;

ENTITY hmk2_32bitAdder IS
  PORT(a, b : IN std_logic_vector(31 downto 0);
     c : IN std_logic;
     result : OUT std_logic_vector(31 downto 0);
     cout : OUT std_logic);
END ENTITY hmk2_32bitAdder;

ARCHITECTURE adder_32bit OF hmk2_32bitAdder IS
  SIGNAL c_internal : std_logic;
  
  BEGIN
    P1 : PROCESS (a, b, c, c_internal)
     BEGIN
       c_internal <= c;
      for i in 0 to 31 loop
        result(i) <= a(i) xor b(i) xor c_internal;
          c_internal <= (a(i) and b(i)) or (a(i) and c_internal) or (b(i) and c_internal);
      end loop;
      cout <= c_internal;
   END PROCESS P1;
END ARCHITECTURE adder_32bit;

: Edited by Moderator
Author: Lothar Miller (lkmiller) (Moderator)
Posted on:

Rate this post
0 useful
not useful
DSP_Arch_Student wrote:
> where the carry in signal is not be registered at all.
An adder is a completly registerless, combinatorial design. So is yours: 
no clock, no registers.

And now: what do you mean with "not registered"?

One major flaw in your design ist, that you don't know about how signals 
behave in a process. They keep(!!) their value throughout(!!) the whole 
process. And at the end of the process they get the last assigned value. 
Think about that.

Lets start here with c_internal='0' and c='1'. On the right side of all 
the assginments througout the process c_internal is '0':
    P1 : PROCESS (a, b, c, c_internal)
     BEGIN
       c_internal <= c; -- c_internal gets a new value that will possibly be transferred at the end of the process              
      for i in 0 to 31 loop
        result(i) <= a(i) xor b(i) xor c_internal; -- c_internal IS '0' HERE
          c_internal <= (a(i) and b(i)) or (a(i) and c_internal) or (b(i) and c_internal); -- c_internal IS '0' HERE, it may get a new value at the end of the process
      end loop;
      cout <= c_internal; -- c_internal IS '0' here, so cout is '0' also
   END PROCESS P1; -- And finally c_internal here gets the last assigned value from three lines above 

In this case here c_internal must be a variable. Variables virtually 
take over the assigned value "immediately". Lets start again with 
c_internal='0' and c='1':
ARCHITECTURE adder_32bit OF hmk2_32bitAdder IS
 
  BEGIN
    P1 : PROCESS (a, b, c, c_internal)
     variable c_internal : std_logic;
     BEGIN
       c_internal := c; -- always initialise the variable!
      for i in 0 to 31 loop -- surprise, surprise: now HERE c_internal IS '1'
        result(i) <= a(i) xor b(i) xor c_internal;
          c_internal := (a(i) and b(i)) or (a(i) and c_internal) or (b(i) and c_internal);
      end loop;
      cout <= c_internal;
   END PROCESS P1;
END ARCHITECTURE adder_32bit;
But be aware that variables in processes are not like variables in C 
programs (as VHDL is not a programming language, but a description 
language. just keep it in mind, you will find out further on)...

: Edited by Moderator
Author: Sym (Guest)
Posted on:

Rate this post
0 useful
not useful
Apart from this 'educational' implementation, one would normally use 
ieee.numeric_std, and the '+' operator. Simply because it is much more 
readable, and - this is the main reason - the compiler can map it to 
arithmetic hardware which is faster and smaller.

Author: Sigi (Guest)
Posted on:

Rate this post
0 useful
not useful
DSP_Arch_Student wrote:
> the carry in signal is not be registered at all

Registering all carries (+clock) would imply a
pipeline design, but I guess that's not
your aim.

The problem is, that you only use ONE!
signal for all carries, but incl. input Carry
you have 32 carries. Declare a new vector cy
and assign "cy[0] <= c" and in each stage
"cy[i+1] <= (a(i) and b(i)) or (a(i) and cy[i]) or (b(i) and cy[i]);

Author: Sigi (Guest)
Posted on:

Rate this post
0 useful
not useful
sorry mistake, incl cout you need 33 carries:
cout <= cy[32]

Reply

Entering an e-mail address is optional. If you want to receive reply notifications by e-mail, please log in.

Rules — please read before posting

  • Post long source code as attachment, not in the text
  • Posting advertisements is forbidden.

Formatting options

  • [c]C code[/c]
  • [avrasm]AVR assembler code[/avrasm]
  • [vhdl]VHDL code[/vhdl]
  • [code]code in other languages, ASCII drawings[/code]
  • [math]formula (LaTeX syntax)[/math]




Bild automatisch verkleinern, falls nötig
Note: the original post is older than 6 months. Please don't ask any new questions in this thread, but start a new one.