2

I'm having some problems with the conv_std_logic_vector function in Quartus. I'm using the function to convert a integer variable into a std_logic_vector. When i compile the code below, Quartus shows the following error message:

Error (10344): VHDL expression error at counter_Wbits.vhd(32): expression has 3 elements, but must have 4 elements.

I have searched this function on the internet and people always use 2 parameters, what is happening?

LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE IEEE.std_logic_unsigned.ALL;
use IEEE.std_logic_arith.ALL;

ENTITY counter_Wbits IS
  GENERIC(W : NATURAL := 4);
  PORT (portae   : IN  BIT;-- data input
        portas   : IN  BIT;-- data input
        clk : IN  BIT;  -- clock
        clrn: IN  BIT;  -- clear
        ena : IN  BIT;  -- enable
        q   : BUFFER STD_LOGIC_VECTOR(W-1 DOWNTO 0));-- data output
END counter_Wbits;

ARCHITECTURE arch_1 OF counter_Wbits IS
BEGIN
  PROCESS(clk,clrn)
  variable cont : integer range 0 to 15;
  BEGIN
    IF (clrn='0') THEN
      q <= (OTHERS => '0');
    ELSIF (clk'EVENT AND clk='1') THEN
      IF (ena='1') THEN
        IF(portae='1') THEN
          cont := cont+1;
        ELSIF (portas='1') THEN
          cont := cont-1;
        END IF;
      END IF;
    END IF;
    q <= conv_std_logic_vector(cont, W-1);  -- LINE 32
  END PROCESS;
END arch_1;
Martin Zabel
  • 3,589
  • 3
  • 19
  • 34
  • W=4 so W-1=3. You can't fit (range 0 to 15) in 3 bits, which is exactly what the error message said in the first place. (Note also if you instantiate this entity with any other value of the generic, it will be broken. Fix that too) –  Apr 30 '16 at 21:04
  • Thanks man, i was thinking that was a parameter error! It's working now! –  Apr 30 '16 at 21:06
  • 1
    I'm constantly surprised by the number of examples on SO that use `std_logic_arith`. `The numeric_std` library has been available for more than a decade, and our internal coding standard has required it since 2002. Every synthesizer I can think of since 2002 has supported it. Who's teaching this stuff? – PlayDough May 04 '16 at 13:56

1 Answers1

3

The last parameter of the function conv_std_logic_vector defines the length of the returned std_logic_vector from this function. Specifying W-1 here, request that the function returns a 3 bit vector. But, the target signal q has 4 bits, numbered from W-1 downto 0. That's what the error message complains about.

You can fix this, by passing just W as the last parameter. A better way is, to the specify the length of the target signal instead using q'length:

q <= conv_std_logic_vector(cont, q'length);

This way, the function result will always have the correct length.

It is no problem as such, if the possible range of the first argument is greater than what can be represented by the number of bits given in the second argument. Of course, truncation will occur.


Please do not use, the non-standard std_logic_arith and std_logic_unsigned packages from Synopsys anymore. Problems will arise, when you have to use signed and unsigned numbers in the same entity later one. Use the standard ieee.numeric_std package instead:

LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
use IEEE.numeric_std.all;   -- CHANGED THIS

ENTITY counter_Wbits IS
  GENERIC(W : NATURAL := 4);
  PORT (portae   : IN  BIT;-- data input
        portas   : IN  BIT;-- data input
        clk : IN  BIT;  -- clock
        clrn: IN  BIT;  -- clear
        ena : IN  BIT;  -- enable
        q   : BUFFER STD_LOGIC_VECTOR(W-1 DOWNTO 0));-- data output
END counter_Wbits;

ARCHITECTURE arch_1 OF counter_Wbits IS
BEGIN
  PROCESS(clk,clrn)
  variable cont : integer range 0 to 31;
  BEGIN
    IF (clrn='0') THEN
      q <= (OTHERS => '0');
    ELSIF (clk'EVENT AND clk='1') THEN
      IF (ena='1') THEN
        IF(portae='1') THEN
          cont := cont+1;
        ELSIF (portas='1') THEN
          cont := cont-1;
        END IF;
      END IF;
    END IF;
    q <= std_logic_vector(to_unsigned(cont, q'length));  -- CHANGED THIS
  END PROCESS;
END arch_1;

The conversion from integer to std_logic_vector requires 2 steps now. At first you will have to convert it to an unsigned of length q'length as specified in the second argument of to_unsigned An unsigned is also a vector of std_logic elements, but the respective functions threats this "bit sequence" as an unsigned number. The second (outer) step, is a type conversion to std_logic_vector.

Martin Zabel
  • 3,589
  • 3
  • 19
  • 34