VHDL coding tips and tricks: Some tricky coding methods using VHDL Attributes

Saturday, March 13, 2010

Some tricky coding methods using VHDL Attributes

     Attributes are used to return various types of information about a signal, variable or type.Attributes consist of a quote mark (‘) followed by the name of the attribute.There are five types of attributes.They are signal attributes,scalar attributes,array attributes etc are some of them.I will explain here the usage of the most common attributes used in array access and manipulation.

If you are not familiar with basics of array declaration,initialization,manipulation etc then you can learn them here.

1)signal_name’event : This is a signal attribute.It returns the Boolean value True if an event on the signal occurred, otherwise gives a False.
if(clk'event and clk='1') then    -- to find the positive edge of the clk.
  output <= '1';
else
  output <= input;
end if;
    For negative edge use "  if(clk'event and clk='0')  " this.

2)array_name'range : This is an array attribute which returns range of an array.This attribute can be used to check whether a signal is zero or not.For long signals this attribute is very useful.

--Checking a 64 bit is zero or not.
signal lv,temp :std_logic_vector(63 downto 0):=(others =>'0');
if(lv /= lv'range => '0')) then
      temp <= lv;
end if;

--The same method can be used to check individual array elements.
type test is array (0 to 11) of std_logic_vector(63 downto 0);
signal lv,temp : test :=(others => (others =>'0'));
variable i : integer :=0;
for i in 0 to 11 loop
     if(lv(i) /= (lv(i)'range => '0')) then
           temp(i) := lv(i);
     end if;
end loop;

--Checking a two dimensional array is zero or not without 'for' loop.
if(lv = (lv'range => (lv(0)'range => '0'))) then
   temp <= lv;
end if;

--Initializing an array with 1's.
lv <= (lv'range => (lv(0)'range => '1'));

3)array_name'left : returns the left most index of the array.
Similarly array_name'right returns the right most index of the array.
These two attributes are used for accessing a part of the array.

--Initializing a part of the array to zeros or ones.
--64-bit elements with index 1 to 10 of lv are made '1' here.
lv(lv'left+1 to lv'right-1) <= (others => (others => '1'));

--Assigning part of an one dimensional array to another array.
signal temp2,temp3 : std_logic_vector(32 downto 0):=(others => '0');
temp2(temp2'left-8 downto temp2'right+8) <= temp3(temp3'left downto temp3'right+16);

--Assigning part of a two dimensional array two another one dimensional array.
temp2(temp2(0)'left-8 downto temp2(0)'right+8) <= lv(3)(lv(0)'left downto lv(0)'right+16);

    Note that we are using temp2(0)'left minus 8 and temp2(0)'right plus 8 because the std_logic_vector, 'temp' is declared as little endian format.For big endian formats you have to subtract from temp2(0)'right and add to temp2(0)'left for accessing a part of the array.

Note :- There many other attributes in VHDL.I have mentioned the important ones only.You can see the full list of attributes here.

2 comments:

  1. - I'm usually using array'high/array'low instead of array'right/array'left

    - To write general functions, array'range is also usefull: (silly example)

    function max(x, y : unsigned) returns unsigned is
    variable ret: unsigned(x'range);
    begin
    if (x > y) then
    ret := x;
    else
    ret := y;
    end if;
    return ret;
    end;

    The point is, the function can be used no matter what the range of x is (as long as x and y are of equal size)

    ReplyDelete
  2. please tell vhdl code for 3*3 multiplication to show matrix results
    on fpga board..

    ReplyDelete