VHDL: ошибка параметра conv_std_logic_vector

У меня проблемы с функцией conv_std_logic_vector в Quartus. Я использую функцию для преобразования целочисленной переменной в std_logic_vector. Когда я компилирую приведенный ниже код, Quartus показывает следующее сообщение об ошибке:

Ошибка (10344): ошибка выражения VHDL в counter_Wbits.vhd(32): выражение содержит 3 элемента, но должно содержать 4 элемента.

Я искал эту функцию в Интернете, и люди всегда используют 2 параметра, что происходит?

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;

person Community    schedule 30.04.2016    source источник
comment
W=4, поэтому W-1=3. Вы не можете уместить (диапазон от 0 до 15) в 3 бита, что и было сказано в сообщении об ошибке в первую очередь. (Также обратите внимание, что если вы создадите экземпляр этой сущности с любым другим значением универсального, она будет сломана. Это тоже исправьте)   -  person user_1818839    schedule 01.05.2016
comment
Спасибо, чувак, я думал, что это ошибка параметра! Теперь работает!   -  person    schedule 01.05.2016
comment
Меня постоянно удивляет количество примеров на SO, в которых используется std_logic_arith. The numeric_std библиотека доступна уже более десяти лет, и наш внутренний стандарт кодирования требует ее с 2002 года. Все синтезаторы, о которых я могу думать с 2002 года, поддерживают ее. Кто преподает этот материал?   -  person PlayDough    schedule 04.05.2016


Ответы (1)


Последний параметр функции conv_std_logic_vector определяет длину возвращаемого std_logic_vector из этой функции. Указав здесь W-1, запросите, чтобы функция возвращала 3-битный вектор. Но целевой сигнал q имеет 4 бита, пронумерованных от W-1 downto 0. Вот на что жалуется сообщение об ошибке.

Вы можете исправить это, передав только W в качестве последнего параметра. Лучше указать длину целевого сигнала вместо использования q'length:

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

Таким образом, результат функции всегда будет иметь правильную длину.

Это не проблема как таковая, если возможный диапазон первого аргумента больше, чем то, что может быть представлено количеством битов, заданным во втором аргументе. Конечно, произойдет усечение.


Пожалуйста, не используйте больше нестандартные пакеты std_logic_arith и std_logic_unsigned от Synopsys. Проблемы возникнут, когда вам придется использовать числа со знаком и без знака в одном и том же объекте позже. Вместо этого используйте стандартный пакет ieee.numeric_std:

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;

Преобразование из integer в std_logic_vector теперь требует 2 шагов. Сначала вам нужно будет преобразовать его в unsigned длины q'length, как указано во втором аргументе to_unsigned. unsigned также является вектором из std_logic элементов, но соответствующие функции угрожают этой "последовательности битов" как беззнаковому числу. Второй (внешний) шаг — преобразование типа в std_logic_vector.

person Martin Zabel    schedule 01.05.2016