Не удается определить определение оператора + при разработке 16-битного ALU.

Я разрабатываю 16-битный ALU, который выполняет несколько операций. У меня есть синтаксическая ошибка:

Не удается определить определение оператора +.

Следующий код выполняет сложение со знаком и без знака, а также операцию вычитания и сдвига. Он выполняет несколько других операций, таких как ИЛИ, XOR и т. д., которые я не показываю, так как у них нет никаких проблем.

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

 entity ALU16 is port
 ( A: in std_logic_vector (15 downto 0);
 B: in std_logic_vector (15 downto 0);
 AluOp: in std_logic_vector (4 downto 0);
 shamt: in std_logic_vector (2 downto 0);
 Zero: out std_logic;
 Overflow: out std_logic;
 R: out std_logic_vector (15 downto 0)
 );
 end ALU16;


 architecture RTL of ALU16 is
 signal  temp : std_logic_vector( 16 downto 0);
 signal usgnA, usgnB, Reg1 : unsigned(15 downto 0);
 signal sgnA, sgnB, Reg2 : signed(15 downto 0);

 begin

 process(AluOp)
 variable p : integer range 0 to 15;
 begin

--usgnA <= unsigned(A);
--usgnB <= unsigned(B);

sgnA <= signed(A);
sgnB <= signed(B);


 case AluOp is

    when "00000" =>
        --Reg1 <= usgnA + usgnB; 
        temp <= ('0' & A) + ('0' & B);
        Overflow <= temp(16);
        --temp <= A + B;
        R<=temp(15 downto 0);
        --Overflow <= A(15) and B(15);

--  when "00001" =>
--      --Reg1 <= usgnA - usgnB;
--      R<=A-B;
--      if (A < B) then Overflow<= '1';
--      else Overflow<= '0';
--      end if;
--      
--  when "00010" =>
--      Reg2 <= sgnA + sgnB;
--      R<=std_logic(Reg2);
--      Overflow <= A(14) and B(14);
--      
--  when "00011" =>
--      R <= sgnA - sgnB;
--      R<=std_logic(Reg2);
--      if (sgnA < sgnB) then Overflow<= '1';
--      else Overflow<= '0';
--      end if;
--      
--      when "01011" =>
--              temp <= A;
--              temp <= shift_right(A,to_integer(shamt));
--              p :=to_integer(shamt);
--              for i in 1 to 3 loop
--              temp(i-1) <= '0';
--              end loop; 
--              R<= temp;
--          

    when others =>
        NULL;

--  if( R = "0000000000000000" ) then
--          Zero <= '1';
--      else Zero <='0';
--      end if;


 end case;
 end process;
end RTL; 

person user3053647    schedule 03.03.2014    source источник


Ответы (2)


Поскольку вы используете numeric_std (что и должно быть), вам нужно будет либо изменить тип temp на unsigned, либо привести результат сложения к std_logic_vector. Для подписанного добавления вы можете обнаружить переполнение, сравнив входные знаки с выходным знаком. Если входные знаки совпадают, а выходные знаки отличаются, возникает переполнение. В противном случае вы этого не сделаете. Я также могу порекомендовать использовать переменные вместо сигналов для всех промежуточных результатов (чтобы у вас не возникло проблем с последовательным назначением сигналов):

process (AluOp)
  variable Temp : std_logic_vector(15 downto 0);
begin

...

when "00010" =>
  Temp := std_logic_vector(sgnA + sgnB);
  R <= Temp;
  Overflow <= (sgnA(15) xnor sgnB(15)) and (sgnA(15) xor Temp(15));
person fru1tbat    schedule 03.03.2014

Вы делаете сумму std_logic_vector. и вы не использовали ieee.std_logic_arith.all, поэтому он показывает ошибку. но в одном файле hdl нельзя использовать use IEEE.NUMERIC_STD.ALL и ieee.std_logic_arith.all. Это запутает компилятор.

так что лучше попробовать temp ‹= std_logic_vector(unsigned(A) + unsigned(B)); Это может решить вашу проблему. попробуйте различные комбинации, как это.

person user3217310    schedule 03.03.2014
comment
Благодарю за ваш ответ. Он работал нормально после того, как я перешел на неподписанное дополнение. Но мне интересно, как я могу проверить переполнение с двумя числами со знаком? - person user3053647; 03.03.2014