Jean-Luc Nacif Coelho
Jean-Luc Nacif Coelho

Reputation: 1022

How to separate bits into different signals in vhdl?

I have the following line of verilog code that i want to convert to vhdl:

assign   {cout,sum} = ( add ) ? ( in_a + in_b + cin ) : ( in_a - in_b - cin );

How would i do this in vhdl?

Upvotes: 1

Views: 798

Answers (1)

zennehoy
zennehoy

Reputation: 6846

Effectively you do it the same way, you just have to remember to increase the width of the input values in order to "make room" for the output carry.

(cout, sum) <= ('0'&in_a) + ('0'&in_b) + cin when(add='1') else ('0'&in_a) - ('0'&in_b) - cin;

Since that line is very, very ugly and hard to understand, I'd suggest converting the whole thing to a process:

process(in_a, in_b, cin) begin
    if(add='1') then
        (cout, sum) <= ('0'&in_a) + ('0'&in_b) + cin;
    else
        (cout, sum) <= ('0'&in_a) - ('0'&in_b) - cin;
    end if;
end process;

which is at least a bit more legible.

Edit:

Note that this only works in VHDL 2008. With earlier versions you'll have to create an intermediary signal one wider than your input, assign the result to that, and then extract cout and sum.

process(in_a, in_b, cin)
    -- Assumes in_a and in_b have the same width, otherwise
    -- use the wider of the two.
    variable result : unsigned(in_a'length downto 0);
begin
    if(add='1') then
        result := ('0'&in_a) + ('0'&in_b) + cin;
    else
        result := ('0'&in_a) - ('0'&in_b) - cin;
    end if;
    cout <= result(result'high);
    sum  <= result(result'high-1 downto 0);
end process;

Upvotes: 6

Related Questions