Question

The problem
I'm writing a function in a package which converts some values for a testbench. I want to check the if the output exceeds a maximum value, if it does I want to set it to that maximum value. What I tired was the following:

  -- vec_in: 0...1023, returns -14...23.5 dB
  function conv_dac602_scale (
    vec_in : std_logic_vector)
    return real is
    variable val_in, dB : real := 0.0;
    constant lower : real := -14.0;
    constant upper : real := 23.5;
  begin  -- function conv_dac602_scale
    val_in := real(to_integer(unsigned(vec_in)));
    dB := (lower+(val_in*((upper-lower)/1024.0)));
    return dB when dB <= upper else upper;  -- this is the important line! (129)
  end function conv_dac602_scale;

When I try to compile this I got the following errors:

** Error: myfile.vhd(129): near "when": expecting ';'
** Error: myfile.vhd(260): VHDL Compiler exiting

I then tried assigning it to a variable r first:

  ...
    r := dB when dB <= upper else upper;  -- this is the important line! (129)
    return r;
  end function conv_dac602_scale;

Which did not change the outcome. I know that I can use a simple if/else clause instead, but my question is why I can't use the when clause.

System
Modelsim SE 10.0b, VHDL 2008

Was it helpful?

Solution

The target <= signal when x is a so called concurrent statement, which is designed for easy creation of signal assignments outside a process. You can use it within an architecture, but not inside a process. If and else are designed for sequential statements within a process. In your case, you'll have to use if/else.

Edit: Seems this only holds true for Vhdl pre 2008. As fru1tbat pointet out, this is valid vhdl 2008 code and the problem is a not supported feature by the Modelsim compiler.

OTHER TIPS

I would reconsider changing the way you call your return, as it looks like your syntax using WHEN is incorrect.

Clarify what you're trying to do with:

return dB when dB <= upper else upper;

That essentially is "return dB when dB is less than or equal to upper, else upper" where upper will not be returned due to the way you make the return statement. You may want to say: ... else return upper

I would prefer an if statement in this case:

if ( dB <= upper) then
     return dB;
else
     return upper;
end if;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top