Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
11 years ago

Simple Signed Adder is complex to understand

Hi guys, still asking beginner questions, sorry. I have this code and cant figure out what the '0' in ('0' & cin) is doing. This is what I think:

Lets say we we need to do add two to negative four:

(2)0010 + (-4)1101 where the answer is (-2)11110 (last bit '1' indicates the negative sign) so,

(a_sig(n-1) & a_sig) 00010

+ (b_sig(n-1) & b_sig) 11101

+ ('0' & cin) 00

ans 11111 (which is incorrect)

What am I getting wrong?http://www.alteraforum.com/forum//images/icons/icon8.png

Also is this signed adder actually efficient cause lots of examples suggest loads of other ways to do it and I can't figure out which one to stick to or it depends on the application?

library ieee;

use ieee.std_logic_1164.all;

use ieee.numeric_std.all;

entity examples is

generic(n : integer := 4); -- number of input bits

port(a, b: in std_logic_vector(n-1 downto 0);

cin: in std_LOGIC := '0';

sum: out std_LOGIC_VECTOR(n downto 0));

end examples;

architecture add_sub of examples is

signal a_sig, b_sig: signed(n-1 downto 0);

signal sum_sig: signed(n downto 0);

begin

--convert to signed

a_sig <= signed(a);

b_sig <= signed(b);

--add

sum_sig <= (a_sig(n-1) & a_sig) + (b_sig(n-1) & b_sig) + ('0' & cin);

sum <= std_logic_vector(sum_sig);

end add_sub;

18 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I should say that actually all operations (add/subtract/mult/div) are basically similar for signed and unsigned (using two's complement) but some care is needed with carry bits and result width.

    But all these details are not relevant to me as the functions in libraries look after it. I will add one bit to result of +/- and for multiplying 5 bits x 5 bits the result should be 10 bits.

    The compiler tells you but not always.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Great tip. Thanks. Is there a way I can improve and get better with VHDL other than books? There's so many interesting projects done with FPGAs but not much information when things start to get complex.

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    Great tip. Thanks. Is there a way I can improve and get better with VHDL other than books? There's so many interesting projects done with FPGAs but not much information when things start to get complex.

    --- Quote End ---

    practice then practice. and use higher level design than lower level, don't read too much into books examples.

    By the way I should correct my thoughts on that cin:

    it does not need 4 bits but two is enough since the addition always gives it weight as lsb, and that zero is just to pretend it is signed positive.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    well I'm on the right track then I guess cause I try something new every day, so thanks for that and for the correction too. :)

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Hii guys,good work.I'm quite new to FPGA and vhdl,So I created a forum on (help..FPGA based led lighting using de2 board where d LEDs come on at night and goes off during d day using ldr as sensor.pls I need u guys to put me try.im kind of confused how to convert the analog signal from d ldr into digital form for the fpga

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    Oppps, thanks kaz. it's late and I'm a bit tired. So actually it is working correctly. So why is the '0' in ('0' & cin) needed for?

    --- Quote End ---

    It's a sign extension. (Actually, it is zero-extension if the word is unsigned.) You need it because:

    a) adding two n-bit vectors gives you an n+1-bit sum (a carry is generated),

    b) VHDL requires that assignments have the same length vectors on both sides of the <= (or := ), and

    c) VHDL neither auto-extends operands nor truncates results to make the vector lengths match (unlike Verilog).

    As noted in this thread, it is better to use the resize() function (from numeric_std) on signed or unsigned types than to explicitly use the '0' & foo.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    It's a sign extension. (Actually, it is zero-extension if the word is unsigned.) You need it because:

    b) VHDL requires that assignments have the same length vectors on both sides of the <= (or := ), and

    c) VHDL neither auto-extends operands nor truncates results to make the vector lengths match (unlike Verilog).

    --- Quote End ---

    are you sure? try multiply 8 bits value by 8 bits value onto 16 bits result

    --- Quote Start ---

    As noted in this thread, it is better to use the resize() function (from numeric_std) on signed or unsigned types than to explicitly use the '0' & foo.

    --- Quote End ---

    why? what is the resize doing anyway?
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    are you sure? try multiply 8 bits value by 8 bits value onto 16 bits result

    --- Quote End ---

    The multiply and divide functions in numeric_std return a result that is N+M bits long. But addition/subtraction returns a result that is as long as the largest operand.

    --- Quote Start ---

    why? what is the resize doing anyway?

    --- Quote End ---

    The resize function does 0 extension for unsigned and sign extension for signed. It extends (or shrinks) the value the specified length.