EmbDev.net

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


von DSP_Arch_Student (Guest)


Rate this post
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:
1
LIBRARY ieee;
2
use ieee.std_logic_1164.all;
3
4
ENTITY hmk2_32bitAdder IS
5
  PORT(a, b : IN std_logic_vector(31 downto 0);
6
     c : IN std_logic;
7
     result : OUT std_logic_vector(31 downto 0);
8
     cout : OUT std_logic);
9
END ENTITY hmk2_32bitAdder;
10
11
ARCHITECTURE adder_32bit OF hmk2_32bitAdder IS
12
  SIGNAL c_internal : std_logic;
13
  
14
  BEGIN
15
    P1 : PROCESS (a, b, c, c_internal)
16
     BEGIN
17
       c_internal <= c;
18
      for i in 0 to 31 loop
19
        result(i) <= a(i) xor b(i) xor c_internal;
20
          c_internal <= (a(i) and b(i)) or (a(i) and c_internal) or (b(i) and c_internal);
21
      end loop;
22
      cout <= c_internal;
23
   END PROCESS P1;
24
END ARCHITECTURE adder_32bit;

von Lothar M. (Company: Titel) (lkmiller) (Moderator)


Rate this post
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':
1
    P1 : PROCESS (a, b, c, c_internal)
2
     BEGIN
3
       c_internal <= c; -- c_internal gets a new value that will possibly be transferred at the end of the process              
4
      for i in 0 to 31 loop
5
        result(i) <= a(i) xor b(i) xor c_internal; -- c_internal IS '0' HERE
6
          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
7
      end loop;
8
      cout <= c_internal; -- c_internal IS '0' here, so cout is '0' also
9
   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':
1
ARCHITECTURE adder_32bit OF hmk2_32bitAdder IS
2
 
3
  BEGIN
4
    P1 : PROCESS (a, b, c, c_internal)
5
     variable c_internal : std_logic;
6
     BEGIN
7
       c_internal := c; -- always initialise the variable!
8
      for i in 0 to 31 loop -- surprise, surprise: now HERE c_internal IS '1'
9
        result(i) <= a(i) xor b(i) xor c_internal;
10
          c_internal := (a(i) and b(i)) or (a(i) and c_internal) or (b(i) and c_internal);
11
      end loop;
12
      cout <= c_internal;
13
   END PROCESS P1;
14
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)...

von Sym (Guest)


Rate this post
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.

von Sigi (Guest)


Rate this post
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]);

von Sigi (Guest)


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

von DSP_Arch_Student (Guest)


Rate this post
useful
not useful
@Sigi, @lkmiller,

I know this is a little late on the reply, but thanks you guys for the 
help! I know what I did wrong now, a semester after the class is over! 
:D

As long as I know what I did wrong, I'm happy. So, thanks for the help 
again!!!

Please log in before posting. Registration is free and takes only a minute.
Existing account
Do you have a Google/GoogleMail account? No registration required!
Log in with Google account
No account? Register here.