2017-01-16 2 views
0

Для школы мы делаем код для ALU. Код должен выполнить расчет с 1, 2 или 3 входами и скопировать его на выход, расчет выполнен в зависимости от 4-битного номера.Bitshifting and Rotating in vhdl

код у меня будет показано ниже, и проблема у меня есть, что SSLSOLSRL и ROR операторы не найдены:

final_ex.vhd (34): не может определить, определение оператора "" SLL "" - найдено 0 возможных определений

final_ex.vhd (35): не может определить, определение оператора "" ROL "" - найдено 0 возможных определений

final_ex.vhd (36) : не может определить определение оперы тор "" SRL "" - найдено 0 возможных определений

final_ex.vhd (37): не может определить, определение оператора "" RoR "" - найдено 0 возможных определений

Мой vdhl является в 2008 году, поэтому он не может быть связан с версией. Я пробовал использовать std_logic_vector вместо unsigned, я пробовал использовать обычное 4-битное число типа «0101», но каждый раз такая же ошибка. Я пробовал разные типы данных, но он не работает.

LIBRARY ieee; 
USE ieee.std_logic_1164.all; 
USE ieee.numeric_std.all; 

ENTITY final_ex IS 
GENERIC(N: INTEGER:= 4); -- length of the inputs and output 
    PORT(
    A, B: IN STD_LOGIC_VECTOR(N-1 DOWNTO 0); 
    functions: IN STD_LOGIC_VECTOR(3 DOWNTO 0); 
    clock, Setflag, Zeroflag: IN STD_LOGIC; 
    C: OUT STD_LOGIC_VECTOR(N-1 DOWNTO 0) 
); 
END ENTITY; 

ARCHITECTURE alu OF final_ex IS 
    SIGNAL a_sig, b_sig: SIGNED(N-1 DOWNTO 0); 
    SIGNAL c_sig: SIGNED(N-1 DOWNTO 0); 
    SIGNAL c_unsig: STD_LOGIC_VECTOR(N-1 DOWNTO 0); 
    SIGNAL carry: INTEGER RANGE 0 TO 1; 
    SIGNAL a_unsig: UNSIGNED(N-1 DOWNTO 0); 

BEGIN 
    a_unsig <= UNSIGNED(A); 
    ---------Logic Unit----------- (with unsigned output for logic, bitwise operators) 
    WITH functions(2 DOWNTO 0) SELECT 
    c_unsig <= A AND B  WHEN "000", 
        A OR B WHEN "001", 
        A XOR B  WHEN "010", 
         NOT A  WHEN "011", 
        a_unsig SLL 1 WHEN "100", 
        a_unsig ROL 1 WHEN "101", 
        a_unsig SRL 1 WHEN "110", 
        a_unsig ROR 1 WHEN OTHERS; 

    ---------- Arithmetic Unic:---------- (signed for calcualtions with integers) 
    a_sig <= SIGNED(A); 
    b_sig <= SIGNED(B); 
    carry <= 1 WHEN Setflag = '1' Else 0; 

    WITH functions(2 DOWNTO 0) SELECT 
    c_sig <=  "0000"   WHEN "000", 
       a_sig   WHEN "001", 
       a_sig + 1 WHEN "010", 
       a_sig - 1 WHEN "011", 
       a_sig + b_sig WHEN "100", 
       a_sig + b_sig + carry WHEN "101", 
       a_sig - b_sig  WHEN "110", 
       a_sig - b_sig - carry WHEN OTHERS; 

    ----------------------------------------------------------------------------- 
    WITH functions(3) SELECT 
     c <= c_unsig WHEN '1', 
       STD_LOGIC_VECTOR(c_sig) WHEN OTHERS; 

END ARCHITECTURE; 

ответ

2

Если приглядеться тип c_unsig является std_logic_vector. Нет предопределенных операторов «sll», «rol», «srl» и «ror» с сигнатурой [unsigned, integer return std_logic_vector] (где в пакете -2008 numeric_std, который без знака будет базовым типом UNRESOLVED_UNSIGNED).

Существует три способа исправить это.

с преобразованием типа:

WITH functions(2 DOWNTO 0) SELECT 
    c_unsig <= A AND B  WHEN "000", 
        A OR B WHEN "001", 
        A XOR B  WHEN "010", 
         NOT A  WHEN "011", 
        std_logic_vector(a_unsig SLL 1) WHEN "100", 
        std_logic_vector(a_unsig ROL 1) WHEN "101", 
        std_logic_vector(a_unsig SRL 1) WHEN "110", 
        std_logic_vector(a_unsig ROR 1) WHEN OTHERS; 

Это зависит от подписи функций, объявленных в пакете numeric_std.

Изменение типа c_unsig:

SIGNAL c_unsig: unsigned(N-1 DOWNTO 0); 
    SIGNAL carry: INTEGER RANGE 0 TO 1; 
    SIGNAL a_unsig: UNSIGNED(N-1 DOWNTO 0); 

BEGIN 
    a_unsig <= UNSIGNED(A); 
    ---------Logic Unit----------- (with unsigned output for logic, bitwise operators) 
    WITH functions(2 DOWNTO 0) SELECT 
    c_unsig <=  unsigned (A AND B) WHEN "000", 
        unsigned (A OR B)  WHEN "001", 
        unsigned (A XOR B)  WHEN "010", 
        unsigned ( NOT A) WHEN "011", 
        a_unsig SLL 1   WHEN "100", 
        a_unsig ROL 1   WHEN "101", 
        a_unsig SRL 1   WHEN "110", 
        a_unsig ROR 1   WHEN OTHERS; 

    ---------- Arithmetic Unic:---------- (signed for calcualtions with integers) 
    a_sig <= SIGNED(A); 
    b_sig <= SIGNED(B); 
    carry <= 1 WHEN Setflag = '1' Else 0; 

    WITH functions(2 DOWNTO 0) SELECT 
    c_sig <=  "0000"   WHEN "000", 
       a_sig   WHEN "001", 
       a_sig + 1 WHEN "010", 
       a_sig - 1 WHEN "011", 
       a_sig + b_sig WHEN "100", 
       a_sig + b_sig + carry WHEN "101", 
       a_sig - b_sig  WHEN "110", 
       a_sig - b_sig - carry WHEN OTHERS; 

    ----------------------------------------------------------------------------- 
    WITH functions(3) SELECT 
     c <= std_logic_vector(c_unsig) WHEN '1', 
       STD_LOGIC_VECTOR(c_sig) WHEN OTHERS; 

END ARCHITECTURE; 

И это влечет за собой еще один тип преобразования.

Изменения типа c_unsig и добавления b_unsig:

SIGNAL c_unsig: unsigned(n-1 downto 0); -- STD_LOGIC_VECTOR(N-1 DOWNTO 0); 
    SIGNAL carry: INTEGER RANGE 0 TO 1; 
    SIGNAL a_unsig: UNSIGNED(N-1 DOWNTO 0); 
    signal b_unsig: unsigned(n-1 downto 0); 

BEGIN 
    a_unsig <= UNSIGNED(A); 
    b_unsig <= unsigned(B); 

    ---------Logic Unit----------- (with unsigned output for logic, bitwise operators) 
    WITH functions(2 DOWNTO 0) SELECT 
    c_unsig <=  a_unsig AND b_unsig  WHEN "000", 
        a_unsig OR b_unsig  WHEN "001", 
        a_unsig XOR b_unsig  WHEN "010", 
         NOT a_unsig   WHEN "011", 
        a_unsig SLL 1   WHEN "100", 
        a_unsig ROL 1   WHEN "101", 
        a_unsig SRL 1   WHEN "110", 
        a_unsig ROR 1   WHEN OTHERS; 

    ---------- Arithmetic Unic:---------- (signed for calcualtions with integers) 
    a_sig <= SIGNED(A); 
    b_sig <= SIGNED(B); 
    carry <= 1 WHEN Setflag = '1' Else 0; 

    WITH functions(2 DOWNTO 0) SELECT 
    c_sig <=  "0000"   WHEN "000", 
       a_sig   WHEN "001", 
       a_sig + 1 WHEN "010", 
       a_sig - 1 WHEN "011", 
       a_sig + b_sig WHEN "100", 
       a_sig + b_sig + carry WHEN "101", 
       a_sig - b_sig  WHEN "110", 
       a_sig - b_sig - carry WHEN OTHERS; 

    ----------------------------------------------------------------------------- 
    WITH functions(3) SELECT 
     c <= std_logic_vector(c_unsig) WHEN '1', 
       STD_LOGIC_VECTOR(c_sig) WHEN OTHERS; 

Это соответствует вашему использованию для знаковых операций.

Все три изменения анализируются и разрабатываются. Без тестового стенда для генерации clock и различных других входов проверка границ не была проверена.

Этот код не зависит от -2008.

VHDL - это строго типизированный язык, и функции, реализующие операторы, имеют право на перегрузку оператора на основе сигнатур, определяющих оба типа ввода и типа возврата.

См. IEEE Std 1076-2008 4.5.2 Перегрузка оператора, 4.5.3 Подписи, 9.2 Операторы, 9.3.6 Преобразования типов и 12.5 Контекст разрешения перегрузки.