What's the right way to cast a sfixed to std_logic_vector in vhdl?

what'd
what w
how to pronounce what
what's
what c
what does
what h
what p

I am trying to cast a sfixed (from ieee.fixed_pkg) to std_logic_vector and I wonder what the correct syntax is and why the following is (appearently wrong). I tried compiling the following 3 architectures:

library ieee;
    use ieee.std_logic_1164.all;
    use ieee.fixed_pkg.all;

entity test is
    port (input: in sfixed(0 downto -7) := x"00";
    output: out std_logic_vector(7 downto 0) := x"00");
end;    

Architecture a:

architecture a of test is begin 
    output <= std_logic_vector(input);
end;

Architecture b:

architecture b of test is begin 
    proc: process (input) begin 
        output <= std_logic_vector(input);
    end process;
end;

Architecture c:

architecture c of test is begin 
    proc: process (input) begin 
        if ('1' and '1') then
            output <= std_logic_vector(input);
        end if;
    end process;
end;

The compiler I've used was "ModelSim ALTERA vcom 10.3d Compiler 2014.10 Oct 7 2014". Architectures a and b don't compile with the error message:

Error: [...] Index value -7 (of type std.STANDARD.NATURAL) is out of range 0 to 2147483647.

But architecture c compiles, while still giving me the warning message:

Warning: [...] Index value -7 (of type std.STANDARD.NATURAL) is out of range 0 to 2147483647.

So my question is: what is the correct way to cast this, and why is there any difference between the three architectures posted above?

Funnily enough, this might actually be a grey area in the specification of the VHDL language itself. The same problematic conversion has been discussed as a possible "bug" against the open-source simulator, ghdl.

The essence of the problem is that input is declared as sfixed(0 downto -7) while the definition of std_logic_vector requires its index to be natural, i.e. a positive integer or 0.

Thus a type conversion to an unconstrained std_logic_vector

output <= std_logic_vector(input);

inherits the bounds of the source vector, (0 and -7) and fails because one bound is out of range.

There is a simple workaround, however : type conversion to a constrained std_logic_vector ... such as std_logic_vector (input'length-1 downto 0) ... which by using the 'length attribute is guaranteed to be the right size. The semantics of this conversion keep the indexes valid, so the conversion succeeds, transferring leftmost bit to leftmost bit, and so on.

In a bit more detail, the code looks like:

-- declarations
subtype result_type is std_logic_vector (input'length-1 downto 0);
signal output : result_type;

-- assignment
output <= result_type (arg);

I cannot guarantee Altera will accept the same workaround, but I'm reasonably confident that it will, it's more clearly valid VHDL. I also haven't tried declaring output as a port as you need.

As far as we can tell, ghdl (which is usually rigorous in its interpretation of VHDL) is correct in rejecting this construct according to the letter of the VHDL language reference manual (LRM) and the "bug" report has accordingly been closed.

However, further clarification has been sought from the VHDL standards committee - and possibly a future relaxation of the rule - IF - it can be shown to be completely proof against the sort of array bounds errors and buffer overruns that plague some other languages.

What, what definition: 1. used to ask for information about people or things: 2. used in questions that show you are…. Learn more. Quickly send and receive WhatsApp messages right from your computer.

The range issues resulting for type casting an sfixed that has negative indices to std_logic_vector that @BrianDrmmond discusses was an issue identified during the development of the standard. It is a real issue for simulators other than GHDL as well.

Hence, the package provides type conversion functions to handle this. To convert from either sfixed or ufixed to std_logic_vector use either to_slv and to_std_logic_vector:

  output <= to_slv(input);

To convert from std_logic_vector to sfixed / ufixed use one of the flavors of to_sfixed/to_ufixed. There is one that takes the indices as a parameter and another that takes the object.

  signal a_sfixed : sfixed(0 downto -7) := x"00";
  signal a_slv    : std_logic_vector(7 downto 0) := x"00";

  a_sfixed <= to_sfixed(a_slv, 0, -7);
  . . . 
  a_sfixed <= to_sfixed(a_slv, a_sfixed);

Yes, you can use a type conversion (aka casting) for an assignment instead of the above, however, if you wanted to then use the converted value in an expression, the range of the result would be incorrect since it is determined by the range of the inputs.

  signal a_sfixed : sfixed(0 downto -7) := x"00";
  signal a_slv    : std_logic_vector(7 downto 0) := x"00";
  signal y_sfixed : sfixed(1 downto -7) := x"00";

  y_sfixed <= a_sfixed + to_sfixed(a_slv, 0, -7);

Drake - Nice For What, I asked many people what they learned about themselves during this difficult period. Enlarge this image. When stationery ran out, pages with my  informal a punishment or reprimand (esp in the phrase give (a person) what for) 7. what have you someone, something, or somewhere unknown or unspecified: cars, motorcycles, or what have you. 8.

I found this post facing the same error in GHDL 0.35 (mcode, windows) using David Bishop's fixed_pkg_c (FPHDL, on github).

Note, while the answer here appears correct; I had to add to the following in fixed_pkg_c in order to get GHDL to compile and simulate:

function to_sulv (
  arg : UNRESOLVED_sfixed)            -- fixed point vector
  return STD_ULOGIC_VECTOR is
  variable result : STD_ULOGIC_VECTOR (arg'length-1 downto 0);

  -- This was added
  subtype result_type is STD_ULOGIC_VECTOR (arg'length-1 downto 0);
  begin
  if arg'length < 1 then
    return NSLV;
  end if;
  --  originally: result := STD_ULOGIC_VECTOR (arg)
  result := result_type (arg);
  return result;
end function to_sulv;

The same change was needed to the to_sulv function for ufixed types.

I'm not sure why the previous 'type conversion' using STD_ULOGIC_VECTOR did not work, and I haven't spent more thought on this.

If others find this, please update on whether the original fixed_pkg_c file works in its original implementation.

what, Usage Note: When what is the subject of a clause, it takes a singular verb if the word or phrase that completes the sentence (the complement) is singular, as in I​  noun the true nature or identity of something, or the sum of its characteristics: a lecture on the whats and hows of crop rotation.

The fixed package conversion function is not the solution to the OP's reported error, see posting of the function to convert to std_ulogic_vector below. Note that 'result' is a std_ulogic_vector and is obtained by performing a type cast of the operand 'arg', exactly the same as the OP did (except OP used std_logic_vector). The fixed point package will produce the same error as reported by the OP.

  -- Conversion functions.  These are needed for synthesis where typically
  -- the only input and output type is a std_logic_vector.
  function to_sulv (
    arg : UNRESOLVED_ufixed)            -- fixed point vector
    return STD_ULOGIC_VECTOR is
    variable result : STD_ULOGIC_VECTOR (arg'length-1 downto 0);
  begin
    if arg'length < 1 then
      return NSLV;
    end if;
    result := STD_ULOGIC_VECTOR (arg);
    return result;
  end function to_sulv;

KJ

WHAT, What stories would have defined 2020 so far? Even before the worst pandemic in a century, tectonic shifts were already under way. The news felt  WhatsApp Messenger: More than 2 billion people in over 180 countries use WhatsApp to stay in touch with friends and family, anytime and anywhere. WhatsApp is free and offers simple, secure, reliable messaging and calling, available on phones all over the world.

What I Learned From Writing Letters To Strangers Across America , The right answer is the common sense answer. If you had a human assistant and asked them “What's the time in London?” and they honestly  In current usage that refers to persons or things, which chiefly to things and rarely to subhuman entities, who chiefly to persons and sometimes to animals. The notion that that should not be used to refer to persons is without foundation; such use is entirely standard.

What, What is the World Economic Forum doing about the coronavirus outbreak? Seen a font in use and want to know what it is? Upload an image to WhatTheFont to find the closest matches in our database.

What else happened as coronavirus swept the globe, Find out what your public IPv4 and IPv6 address is revealing about you! My IP address information shows your location; city, region, country, ISP and location on a map.

Comments
  • Using a subtype for a constrained vector and then casting to the subtype does indeed work. Thanks for the answer!
  • I'm amused that (c) fooled your compiler into turning an "error" into a "warning"!
  • ah! so the problem is simply that the fixed-point package's own solution hasn't had enough publicity! I agree it's a better answer than the workaround.
  • Your function, to_sulv above, is an exact copy of the to_sulv in the fixed point package. Going further, the to_slv in the fixed point package calls to_sulv. Why is it you think that to_slv in the fixed point package will produce the same errors? It did not in my tests.