2017-02-12 12 views
0

Я довольно новый (3 недели) для VHDL, и у меня возникла проблема в моем последнем назначении, что связано с внедрением проверки переполнения в простом 4-битном сумматоре :Реализация проверки переполнения в 4-битном Adder/Subtractor (VHDL)

library IEEE; 
use IEEE.STD_LOGIC_1164.ALL; 
use IEEE.STD_LOGIC_UNSIGNED.ALL; 

entity add_sub_4bit is 
    Port (a : in STD_LOGIC_VECTOR(3 downto 0); 
      b : inout STD_LOGIC_VECTOR(3 downto 0); 
       sel: in STD_LOGIC); 
      --sum : inout STD_LOGIC_VECTOR(3 downto 0) 
end add_sub_4bit; 

architecture Behavioral of add_sub_4bit is 
signal localflow : STD_LOGIC; 
signal localsum : STD_LOGIC_VECTOR (3 downto 0); 

begin 
    localsum <= a + b when sel = '1' 
    else 
    a - b; 
process(a,b,localsum) begin 
    if a(3) = '0' AND b(3) = '0' AND localsum(3) = '1' then 
     localflow <= '1'; 
    elsif a(3) = '1' AND b(3) = '1' AND localsum(3) = '0' then 
     localflow <='1'; 
    else 
     localflow <='0'; 
    end if; 
end process; 
end Behavioral; 

Теперь, тестовые примеры как таковые: а = 5, в = -3, давая от 0 до ВЫБРАТЬ добавляет их, 1 вычитание. A = 6, B = 2, работает практически одинаково.

Теперь, учитывая, что цифры подписаны, конечно, они являются номерами дополнений двух, поэтому результат. Тем не менее, я могу только обнаружить переполнение в случае добавления 6 (0110) и 2 (0010), выдавая -8 (1000), что, очевидно, является переполнением в 4-битном. Но при выполнении 5 - (- 3) результат будет таким же, 1000, но поскольку я дал числа двух разных знаков, я не могу обнаружить переполнение с помощью моего метода.

Мой учитель предложил изменить знак B в зависимости от значения sel - я попробовал что-то вроде создания b < = b + "1000" на основе этого, но это не помогло, и я не знаю других путей, будучи очень новым для языка. Что я могу сделать, чтобы получить правильную программу? Спасибо.

+1

В HW вычитании добавляющего дополнения этих два по б (не b + 1), + 1 использует перенос. При вычитании вы должны использовать знак фактического операнда байдера для переполнения, который будет 'opb_sign <= b (3), когда sel = '1' else not b (3); '. Вы можете показать это как отдельный мультиплексор (селектор) или с помощью XOR свернуть это выражение под термином '(b (3) xor not sel)'. Также сбрасывание исходного переключателя переполнения дает 'localflow <= a (3) xor b (3) xor not sel xor localsum (3);' Круглые скобки не требуются, XOR является коммутативным. и не является более высоким приоритетом. – user1155120

+0

Привет, Ваше предложение сработало - я сохранил ту же программу с дополнительным мультиплексором. Большое спасибо! – xen20

ответ

0

Во-первых:

use IEEE.STD_LOGIC_UNSIGNED.ALL; 

Не делай этого. Особенно, если вы хотите, чтобы номера были подписаны. Нормальное использование является:

use IEEE.numeric_std.all; 

После этого, вы должны бросить std_logic_vector к типу разыскиваемого данных, например, «подписан», для правильной арифметики.

Во-вторых, не используйте inout. VHDL не так хорош с двунаправленными назначениями. Используйте либо in, либо out.

Таким образом, комбинируя выше, вы могли бы сделать (не Н.Б. лучшего кода):

library IEEE; 
use IEEE.STD_LOGIC_1164.ALL; 
use IEEE.numeric_std.ALL; 

entity add_sub_4bit is 
    Port (
     a : in STD_LOGIC_VECTOR(3 downto 0); 
     b : in STD_LOGIC_VECTOR(3 downto 0); 
     sel: in STD_LOGIC; 
     sum : out STD_LOGIC_VECTOR(3 downto 0); 
     overflow : out std_logic 
     ); 
end add_sub_4bit; 

architecture Behavioral of add_sub_4bit is 
signal localflow : STD_LOGIC; 
signal locala, localb, localsum : signed(4 downto 0); -- one bit more then input 
signal sumout : std_logic_vector(4 downto 0); 

begin 
    locala <= resize(signed(a), 5); 
    localb <= resize(signed(b), 5); 
    localsum <= locala + localb when sel = '1' else locala - localb; 
    -- overflow occurs when bit 3 is not equal to the sign bit(4) 
    localflow <= '1' when localsum(3) /= localsum(4) else '0'; 
    -- convert outputs 
    sumout <= std_logic_vector(localsum); 
    --outputs 
    sum <= sumout(4)&sumout(2 downto 0); 
    overflow <= localflow; 
end Behavioral; 

Вы можете проверить это с помощью испытательного стенда:

library IEEE; 
use IEEE.STD_LOGIC_1164.ALL; 
use IEEE.numeric_std.ALL; 

entity add_sub_4bit_tb is 
end add_sub_4bit_tb; 

architecture Behavioral of add_sub_4bit_tb is 
signal sel : std_logic_vector(0 downto 0); 
signal a, b, sum : std_logic_vector(3 downto 0); 

begin 
    uut: entity work.add_sub_4bit 
    port map (a, b, sel(0), sum); 

    test: process 
    begin 
     for sel_o in 0 to 1 loop 
      sel <= std_logic_vector(to_signed(sel_o, 1)); 
      for a_o in -8 to 7 loop 
       a <= std_logic_vector(to_signed(a_o, 4)); 
       for b_o in -8 to 7 loop 
        b <= std_logic_vector(to_signed(b_o, 4)); 
        wait for 1 ns; 
       end loop; 
      end loop; 
     end loop; 
     wait; 
    end process; 
end Behavioral; 

 Смежные вопросы

  • Нет связанных вопросов^_^