4
logic index : unsigned(9 downto 0) ;  
type fft_data  is array (3 downto 0) of unsigned(16 downto 0);  
signal tmp,signal fmax_data :fft_data;  
tmp = fmax_data(to_integer(index(9)));

Above part of the code gives following compilation error; "subprogram call or operator argument type mismatch 87"

if I do following modification it works.

logic index : unsigned(9 downto 0) ;  
type fft_data  is array (3 downto 0) of unsigned(16 downto 0);  
signal tmp,signal fmax_data :fft_data;;  
tmp = fmax_data(to_integer(index(**9 downto 9**)));

Can anyone please explain what is the difference between above two implementation? I am using vhdl-93 std and ncvhdl. Thank you

  • One is an indexed name representing an element of an array which in this case is type std_ulogic. The other is a slice name representing an array of the same type as the array containing one element and having the type unsigned. index(9) and index(9 downto 9) are different types. See IEEE 1076-2008 8. Names and 9. Expressions, 9.1 the EBNF for primary - names (including indexed names and sliced names) are expressions. The prefix is the same, the values of the expressions are of different types. –  Jul 03 '17 at 09:14

1 Answers1

4

In numeric_std, the to_integer function is only defined for unsigned and signed type.

Unsigned is derived from std_logic as type UNSIGNED is array ( NATURAL range <> ) of STD_LOGIC;

When you use to_integer(index(9)) you are passing index(9) which is of type std_logic .

When you use to_integer(index(9 downto 9)) you are passing a range of index which is of size 1, however, it is an unsigned type.

You can also create your custom function if you want. To convert std_logic to integer.

function to_integer (ARG : std_logic)
  return integer is
begin
  if ARG = '1' OR ARG = 'H' then
    return 1;
  else
    return 0;
  end if;
end function to_integer;`

OR wrap around to_integer

function to_integer (ARG : std_logic)
    return integer is
    variable t : unsigned(0 downto 0) := "0";
begin
    t(0) := ARG;
    return to_integer(t);
end function to_integer;
Parth Parikh
  • 166
  • 1
  • 8
  • 1
    This function is not correct. The `std_logic` values 'U', 'X', 'Z', 'W', 'L' and 'H' ('-' is never an output) are all converted to 0. `std_logic` is not the same as `bit`. – JHBonarius Jul 03 '17 at 08:25
  • @JHBonarius Oh yeah, `ARG = '1' OR ARG='H' ` would be rather perfect. If you look at `numeric_std-body.vhd` It essentially interprests the rest as 0 only. – Parth Parikh Jul 03 '17 at 08:34
  • Is it allowed to have a single bit as a unsigned? What I mean is, `to_integer(unsigned(index(9)))`. Is it necessary to have it an array for unsigned conversion ? – user2624915 Jul 03 '17 at 08:44
  • 1
    @ParthParikh no, that's not fully true. the functions `TO_01` only convert '0'/'L' and '1'/'H'. All others values are marked as "bad elements". They are "fixed" by getting the value set in the variable `XMAP`, which is default set to '0'. But that does not mean setting them to 0 is correct. It is just a fix... – JHBonarius Jul 03 '17 at 08:48
  • @JHBonarius yeah I looked at it and I proposed it as a fix-up function. How about, `return to_integer("" & ARG)` ? – Parth Parikh Jul 03 '17 at 09:04
  • 2
    *In numeric_std, the to_integer function is only defined for unsigned type.*, `function TO_INTEGER (ARG : UNRESOLVED_SIGNED) return INTEGER;` is listed in package numeric_std immediately following the declaration `function TO_INTEGER (ARG : UNRESOLVED_UNSIGNED) return NATURAL;`. You should be careful trying to make blanket assertions. –  Jul 03 '17 at 09:08
  • 1
    @ParthParikh Then you would use the default function. But I would not create a function `std_logic`->`integer` _at all_. `std_logic_arith` was not deprecated for nothing. The casting should be in the code: `tmp = fmax_data(to_integer(unsigned(index(9))));`. Or just use `tmp = fmax_data(to_integer(index(9 downto 9)));`. There's nothing wrong with that. – JHBonarius Jul 03 '17 at 09:08