VHDL coding tips and tricks: VHDL: Concatenation Operator

Friday, March 26, 2010

VHDL: Concatenation Operator

       Many VHDL programmers doesnt know that there is an operator available in VHDL for doing concatenation. But there is one. It is written as &.

Lets explore this operator through a lot of practical examples...

Example 1:


signal x, y : std_logic := '0';
signal var1 : unsigned(1 downto 0); 
signal var2 : unsigned(0 to 1);
var1 <= x & y;
var2 <= x & y;

--the above statements are the same as:
var1(1) <= w and x; --this is the MSB
var1(0) <= y and z; --this is the LSB
var2(0) <= w and x; --this is the MSB
var2(1) <= y and z; --this is the LSB

Note how the variable on the left side of the concatenation operator is assigned to the MSB of the result.

Example 2:


    Integers cannot be concatenated directly, but they can be converted to signed or unsigned type first and then concatenate. But you should make sure that the integers doesn't overflow when you convert them to binary format. Otherwise your design won't work as expected.

signal x, y : integer;  --two integers
signal var1 : unsigned(15 downto 0);  --16 bit
signal var2 : unsigned(7 downto 0);   --8 bit
--Lets do the type conversions and concatenations as follows:
var1 <= to_unsigned(x,8) & to_unsigned(y,8);
var2 <= to_unsigned(x,4) & to_unsigned(y,4);

Tests:

--For:
x <= 100;  y <= 20;  --x is "64" in hex and y is "14" in hex.
--The result is 
var1 <= x"6414";  --x takes MSB 8 bits and y takes LSB 8 bits.
var2 <= x"44";  --Note how the MSB 4 bits from x and y are removed here. 
--That is because x and y are converted to 4 bit binary first before assigning to var2.

--For:
x <= 10;  y <= 5;  --x is "0A" in hex and y is "05" in hex.
--The result is 
var1 <= x"0A05";  --x takes MSB 8 bits and y takes LSB 8 bits.
var2 <= x"A5";  --Here we didnt loose any bits.

--For:
x <= 10;  y <= 17;  --x is "0A" in hex and y is "11" in hex.
--The result is 
var1 <= x"0A11";  --x takes MSB 8 bits and y takes LSB 8 bits.
var2 <= x"A1"; --Again, MSB bits from y was lost because it had more than 4 bits.
    

Example 3:


    This helps to set some bits zero in a longer vector of bits. An example would be:

--var1 is initialized with hexadecimal value of "ff" here
signal var1 : unsigned(7 downto 0) := x"ff";  

--after the below statement, var2 will become "0000_0001" 
var1 <= x"0" & x"1";

Example 4:


    This operator is very useful when it comes to checking a group of bits inside a case statement. The following example illustrates this concept:

signal var : integer;
process(bit0,bit1,bit2,bit3)
    variable bitcat : std_logic_vector(3 downto 0);
begin
    bitcat := bit0 & bit1 & bit2 & bit3; --concatenation
    case bitcat is
        when "0001" => var <= 1; --when bit3 is '1' and all else is '0'.
        when "0010" => var <= 3; --when bit2 is '1' and all else is '0'.
        when others => var <= 4; --for all other combinations.
    end case;
end process;

    These are some of the situations where the & operator can be used to achieve a more readable friendly code.
Let me know if I have missed some interesting use cases.

7 comments:

  1. I think in cancatation t<= (x and w) & (y and z). result of y and z is assigned to LSB of t and result of x and w is assigned to MSM i.e.t(1)

    ReplyDelete
  2. @Ravindar : yeah.. you are right.Sorry for the typing mistake.I have corrected it.Some more examples are here...

    signal a : unsigned(1 downto 0);
    signal b : unsigned(0 to 1);
    a <= '1' & '0';
    b <= '1' & '0';
    --this is same as:
    a(1) <= '1';
    a(0) <= '0';
    b(1) <= '0';
    b(0) <= '1';

    thanks for the comment.

    ReplyDelete
  3. A useful tip -- watch out for operator order. eg "x & y and z & w" is the same as (x&y) and (z&w). Its easy to accidently read it as x & (y and z) & w. This usually results in a synthesis error, as its unlikely the dimensions will match.

    ReplyDelete
  4. Hi I have a problem abd I am not sure what is wrong.

    entity LOOP is
    Port ( S1 : in STD_LOGIC;
    S2 : in STD_LOGIC;
    S3 : in STD_LOGIC;
    S4 : in STD_LOGIC;
    OUT1 : out STD_LOGIC;
    OUT2 : out STD_LOGIC;
    OUT3 : out STD_LOGIC);
    end LOOP;


    architecture Behavioral of LOOP is


    Signal input: std_logic_vector (1downto 0);


    begin


    input <= S1 & S2;


    begin


    if (input= '00') then


    OUT1='0';
    elsif (input = '01') then
    OUT1='1';
    elsif (input = '10') then


    OUT2='0';


    else


    OUT2='1';
    end if;


    OUT3= S3 AND S4;


    Please help!






    end Behavioral;

    ReplyDelete
    Replies
    1. you cant use reserved word as a entity name..(loop).
      you must use process declaration part in between two begin comments.
      And another fault is "".if the binary elements are in array, you must declare double quotations like input = "01".
      And finally declare end process statement before on end behavioral..

      Delete
  5. Please tellme some one?
    when the combine two VHDL Together, what is the name of that?

    ReplyDelete
  6. IN the following code what if 'signal b' is defined as std_logic_vector(0 to 5),will 'b' hold the last six bits?
    -----------------------------------------------------------------------------
    signal a: std_logic_vector(0 to 3):="1111";
    signal b: std_logic_vector (0 to 7):= (others => '0');
    --this statement will make the MSB 4 bits to zero and LSB 4 bits to one.
    b<="0000" & a;
    -------------------------------------------------------------------------------------

    ReplyDelete