2013-12-04 2 views
3

Я почти успешно реализовал n-разрядный сумматор-вычитатель. Он отлично работает, за исключением одного.4-разрядная логика сумматора-вычитателя

Выполняйте после вычитания без знака, который не ведет себя, как я ожидал.

Here на странице 11 схема, которую я построил. По-моему, я построил правильный путь. Это 4-разрядный сумматор/вычитатель.

Чтобы понять мои проблемы с неподписанным переносом, давайте вычислим 1111 - 1111 в неподписанном виде. Хорошо 15 - 15 - 0, поэтому должно быть 0000. Что такое неподписанное ношение?

Вход:

a <= "1111"; 
b <= "1111"; 
s <= '1'; 

Единственное s делает, строит дополнение к 2-Ь. Давай сделаем это.

b = 1111 
1'st complement 
b = 0000 
2's complement 
b = 0001 

Теперь мы можем выполнить сложение 1111 + 0001.

1111 
0001 
===== 
10000 

И здесь моя (мысль) проблемой. Перенос (5-й бит) равен 1. Я вычислил 15-15 = 0 с переносом переполнения, который я вообще не понимаю.

С другой стороны, я могу рассчитать 1110 - 1111 (14-15), который должен быть -1, который не может быть представлен беззнаковыми числами. Поэтому здесь я бы ожидал бит переполнения.

b = 1111 
2's complement => 0001 

1110 
0001 
===== 
01111 

Так он говорит мне, что 14-15 15 (что не удивительно), но флаг переполнения устанавливаются в 0.

ли я понял переполнение битого вычитания, или это unsigned_cout xor sub не хватает?

Мой VHDL-код:


--full сумматор

library IEEE; 
use IEEE.STD_LOGIC_1164.ALL; 

entity fad is 
    port(
     a,b,cin : in std_logic; 
     o, cout: out std_logic); 
end fad; 



architecture behavior of fad is 
begin 
    o <= a xor b xor cin; 
    cout <= (a and b)or (cin and (a xor b)); 
end behavior; 

--adder-вычитателя

library IEEE; 
use IEEE.STD_LOGIC_1164.ALL; 

entity add_sub is 
    generic(N : natural := 4); 
    port(
     a, b : in std_logic_vector(N-1 downto 0); 
     sub : in std_logic; 
     o : out std_logic_vector(N-1 downto 0); 
     scout, ucout : out std_logic); 

end add_sub; 

architecture behavior of add_sub is 
    signal carries : std_logic_vector(N downto 0); 
    signal bXorSub : std_logic_vector(N-1 downto 0); 
    component fad is 
     port(a, b, cin : in std_logic; 
       o, cout : out std_logic 
     ); 
    end component; 
begin 
    carries(0) <= sub; 
    subtraction: for i in 0 to N-1 generate 
     bXorSub(i) <= b(i) xor sub; 
    end generate subtraction; 

    RCA: for i in 0 to N-1 generate 
     fadN: fad port map( 
      a => a(i), 
      b => bXorSub(i), 
      cin => carries(i), 
      o => o(i), 
      cout => carries(i+1)); 
    end generate RCA; 
    ucout <= carries(N); 
    scout <= carries(N) xor carries(N-1); 
end behavior; 
+0

Добро пожаловать в SO! У вас есть код, который согласуется с этим? Вы сохранили это описание довольно абстрактным, но последнее последнее предложение подразумевает, что у вас уже есть какой-то программный код, который делает большую часть этого. Если вы можете поделиться им в своем вопросе, это поможет нам ответить на ваш вопрос. – Derek

+0

добавил мой код vhdl – hr0m

ответ

2

Ок, я спал и теперь Evrything гораздо яснее; -)

После unsigned вычитание переноса должно быть «1», иначе происходит переполнение, вот почему.

Суммарная суммарная суммарная сумма состоит из более (здесь 4) полных сумматоров. Поэтому мы никогда не вычитаем. Однако в подписан дополнение, мы можем рассчитать для примера 4 + (-1).

С unsigned цифры я не могу назвать отрицательное число. На самом деле, я просто не могу рассчитать 4 - 1. У меня нет вычитателя, и я не могу представить отрицательный номер.

Так как я могу выполнить такую ​​операцию. Потому что это явно работает. 4 - 1 = 3 (0100 - 0001 = 0011).

Единственный способ, чтобы уменьшить неподписанный номер с только сумматором, должен переполнить его. Тот факт, что мы не можем представить все положительные числа, является решением (с 4-мя битами без знака максимум 15).

Например, мы вычисляем 15 - 15 с 4 битами неподписанные номера. 15 - 15 - 0. Итак, что мы добавляем на «1111», чтобы получить «0000»? Просто как раз в «0001», который IST дополнением этих двух по 15. Мы Rember:

2's complement = invert the number and add 1 
"1111" => "0000" 
"0000" + "0001" = "0001". 

А потом мы добавим этот номер на нашем 15.

1111 
0001 
===== 
10000 

А там, как вы можете видеть это (справа).

Таким образом, последний бит переноса беззнаковым вычитанием должен быть установлен в «1», если расчет выполнен правильно. В противном случае, если это «0», вычитаемое число должно быть отрицательным, так как беззнаковое число не может представлять.

+0

Мне потребовалось больше времени, чем я хотел бы признать это и полностью понять его. Хорошо сделанный на объяснении этого, спасибо, что поставил время, чтобы объяснить это, когда вы это поняли. Подписанное и неподписанное вычитание и добавление - это то, что смущает много людей, и каждый раз, когда я это делаю, мне нужно быть осторожным. Я на самом деле написал подписанный vs. неподписанный учебник на моей веб-странице здесь: http://www.nandland.com/vhdl/examples/example-signed-unsigned.html. Мне нужно перечитать мой пример, чтобы узнать, правильно ли оно было обнаружено в моем собственном ... – Russell

+0

Я думаю, что ваш пример был настолько другим, потому что вы смотрели конкретно на биты переноса, о которых я обычно не забочусь. Инструменты просто обрабатывают этот материал для меня :) – Russell

+0

Ну, моя цель - реализовать процессор mips, но это займет много времени. Это мое обучение, выполняя проект. Моя первая веха - это алу. Но сначала мне нужны эти компоненты (сумматоры, переключатели, компараторы и т. Д.). Я мог бы использовать библиотечное решение, но это не моя цель. Я действительно хочу это понять и понять. И как вы можете видеть, некоторые вопросы будут расти, чего обычно никто не спрашивает. – hr0m