0 / 0 / 0
Регистрация: 13.09.2020
Сообщений: 6
|
|
1 | |
Сдвиг множимого вправо15.05.2021, 14:11. Показов 1088. Ответов 7
Всем привет!
Дали задачку в Университете: Опеpация выполняется по алгоpитму умножения чисел в дополнительном коде со стаpших pазpядов множителя и сдвигом суммы частичных пpоизведений влево с одним коppектиpующим шагом. Я с ней справился, но вот со второй уже нет: Опеpация выполняется по алгоpитму умножения чисел в дополнительном коде со старших pазpядов множителя и сдвигом множимого впpаво с одним коppектиpующим шагом. Сколько не пытался, нормально реализовать сдвиг множимого вправо не получилось. Ниже листинг кода для первой задачи: Код
library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; entity Multiply is generic (n:integer:=5); -- n параметр, задает разрядность операндов Port(a:in std_logic_vector(n-1 downto 0); -- множимое b: in std_logic_vector(n-1 downto 0); -- множитель c: out std_logic_vector(2*n-2 downto 0)); -- произведение end Multiply; architecture Behavioral of Multiply is begin process(a,b) variable rb: std_logic_vector (n-1 downto 0); -- для хранения множителя variable ra: std_logic_vector (2*n-2 downto 0);-- для хранения множимого variable rc: std_logic_vector(2*n-2 downto 0); -- для формирования суммы ЧП begin ra(n-1 downto 0):=a; -- присваиваем ra значение множимого ra(2*n-2 downto n):=(others =>a(n-1)); -- заполняем старшие разряды ra знаковым rb:=b; -- присваиваем rb значение множителя rc:=(others=>'0'); -- обнулям сумму ЧП for i in 1 to n loop -- выполняем в цикле n раз if (rb(n-1)='1') then if i=1 then rc:= rc+not(ra)+1; -- корректирующий шаг[-A]д else rc:= rc+ra; -- прибавляем множимое +[A]д end if; end if; if i=n then exit; -- если последний шаг, то выходим из цикла end if; rc(2*n-2 downto 0):=rc(2*n-3 downto 0)&'0'; -- сдиг суммы ЧП влево rb:=rb(n-2 downto 0)&'0'; -- сдвиг множителя влево end loop; c<=rc(2*n-2 downto 0); -- передача результата на выход устройства end process; end Behavioral; Помогите, пожалуйста, переделать этот код для второй задачи, буду очень благодарен!
0
|
|
15.05.2021, 14:11 | |
Ответы с готовыми решениями:
7
Сдвиг на 2 разряда вправо
Запишите число в 8-разрядном двоичном коде. Примените к нему логический сдвиг вправо и арифметический сдвиг вправо |
3081 / 2253 / 521
Регистрация: 11.09.2009
Сообщений: 8,303
|
|
15.05.2021, 22:52 | 2 |
Ай-яй-яй! Обманывать нехорошо. С первой задачей справились не вы, а Н.В. Ефремов, автор методички "Проектирование операционных устройств в кристалле ПЛИС с использованием языка VHDL в САПР QUARTUSII", ещё в 2019 году, откуда со стр. 21 вы и списали этот "листинг".
0
|
3081 / 2253 / 521
Регистрация: 11.09.2009
Сообщений: 8,303
|
|
15.05.2021, 22:59 | 3 |
Теперь слабо в это верится, но нельзя же совсем лишать шанса...
Выкладывайте ваши попытки, укажите, где и что не получилось.
0
|
0 / 0 / 0
Регистрация: 17.06.2022
Сообщений: 3
|
|
17.06.2022, 12:19 | 4 |
Добрый день. Столкнулся с такой же проблемой. Написал код, но ответ получается неверный. Подскажите, пожалуйста, что может быть не так?
0
|
ValeryS
|
||||||
17.06.2022, 19:50
#5
|
||||||
0
|
0 / 0 / 0
Регистрация: 17.06.2022
Сообщений: 3
|
|
18.06.2022, 09:56 | 6 |
Вот код, который мне удалось в итоге сделать. Он работает так, как нужно, но для этого я в конце сдвигаю вправо получившийся результат, что не по алгоритму умножения в дополнительном коде со сдвигом множимого вправо и одним корректирующим шагом. Если этого не делать, то все результаты тестирования получаются в два раза больше правильного
![]() Код
library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; entity testMultiply is generic (n:integer:=4); -- n параметр, задает разрядность операндов Port(x:in std_logic_vector(n-1 downto 0); -- множимое y: in std_logic_vector(n-1 downto 0); -- множитель c: out std_logic_vector(2*n-1 downto 0)); -- произведение end testMultiply; architecture Behavioral of testMultiply is begin process(x,y) variable rb: std_logic_vector (n-1 downto 0); -- для хранения множителя variable ra: std_logic_vector (2*n-1 downto 0); -- для хранения множимого variable rc: std_logic_vector (2*n-1 downto 0); -- для формирования суммы ЧП begin ra(2*n-1 downto n):=x; -- присваиваем ra значение множимого (А) ra(n-1 downto 0):=(others=>'0'); -- заполняем младшие разряды ra нулями rb:=y; -- присваиваем rb значение множителя (В) rc:=(others=>'0'); -- обнуляем сумму ЧП (S0) for i in 1 to n loop -- выполняем в цикле n раз if (rb(n-1)='1') then if i=1 then -- если это первый шаг rc:= rc+not(ra)+1; -- корректирующий шаг[-A]д else rc:= rc+ra; -- прибавляем множимое +[A]д end if; end if; ra(2*n-1 downto 0):=ra(2*n-1) & ra(2*n-1 downto 1); -- сдвиг множимого вправо rb:=rb(n-2 downto 0)&'0'; -- сдвиг множителя влево if i=n then exit; -- если последний шаг - выходим из цикла end if; end loop; rc(2*n-1 downto 0):=rc(2*n-1) & rc(2*n-1 downto 1); c<=rc(2*n-1 downto 0); -- передача результата на выход устройства end process; end Behavioral;
0
|
5 / 5 / 0
Регистрация: 23.03.2021
Сообщений: 36
|
|
18.06.2022, 15:11 | 7 |
Darkuss в первом посте пишет:
"Опеpация выполняется по алгоpитму умножения чисел в дополнительном коде со старших pазpядов множителя и сдвигом множимого впpаво с одним коppектиpующим шагом. Сколько не пытался, нормально реализовать сдвиг множимого вправо не получилось." Посторонним не понятно, что должно строиться - последовательное многоактное устройство умножения или однотактное (матричное). И то и другое реализуется достаточно просто, и в дополнительном коде это не сложно. И старайтесь правильно задавать вопросы. В первом случае начинают хотя бы с блок схемы, далее отдельно строят управляющее устройство на основе конечного автомата (КА), а рядом (или вместе с ним) операционное устройство, которое этим КА управляется и где выполняются суммирования и сдвиги. Оба эти компонента составляют операционный автомат. А при сдвигах право в дополнительном коде не забывайте о расширения знака. Во втором - все действия разворачиваются в пространстве, причем каждое на своих элементах. Попробуйте сначала все действия сделать и записать на листочке в клетку для небольшой разрядности, например, в четыре бита. А потом каждое действие переведите в VHDL, если это делать по быстрому (и если имеется опыт). Отступление от темы: Я когда-то давно строил матричный умножитель/делитель в дополнительных кодах, где множитель на ходу преобразовывался в двоичную систему счисления (-1, 1), и где также в конце было одно действие с коррекцией. Потом за патентовала его и имею авторское свидетельство на изобретение. Это было целесообразным потому, что такой алгоритм умножения сочетался с алгоритмом деления, где также промежуточный результат был в системе (-1,1), а оба процесса строились на сумматорах и элементах ИСКЛЮЧАЮЩЕЕ ИЛИ (то есть без всеми любимой при умножениях операции И). И мне всегда помогал листочек в клетку, так как правильное понятое условие это уже половина решения задачи. Этот умножитель/делитель исправно работал в первом моем спец.вычислителе.
0
|
0 / 0 / 0
Регистрация: 17.06.2022
Сообщений: 3
|
|
18.06.2022, 18:39 | 8 |
В итоге всё сделал, тему можно закрывать
![]() Код
library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; entity Multiply2 is generic (n:integer:=4); -- n параметр, задает разрядность операндов Port(a:in std_logic_vector(n-1 downto 0); -- множимое b: in std_logic_vector(n-1 downto 0); -- множитель c: out std_logic_vector(2*n-1 downto 0)); -- произведение end Multiply2; architecture Behavioral of Multiply2 is begin process(a,b) variable rb: std_logic_vector (n-1 downto 0); -- для хранения множителя variable ra: std_logic_vector (2*n-1 downto 0); -- для хранения множимого variable rc: std_logic_vector (2*n-1 downto 0); -- для формирования суммы ЧП begin ra(2*n-1 downto n):=a; -- присваиваем ra значение множимого (А) ra(n-1 downto 0):=(others=>'0'); -- заполняем младшие разряды ra нулями rb:=b; -- присваиваем rb значение множителя (В) rc:=(others=>'0'); -- обнуляем сумму ЧП (S0) for i in 1 to n loop -- выполняем в цикле n раз if (rb(n-1)='1') then if i=1 then -- если это первый шаг ra(2*n-1 downto 0):=ra(2*n-1) & ra(2*n-1 downto 1); -- сдвиг множимого вправо rc:= rc+not(ra)+1; -- корректирующий шаг[-A]д else rc:= rc+ra; -- прибавляем множимое +[A]д end if; end if; if (rb(n-1)='0') then if i=1 then ra(2*n-1 downto 0):=ra(2*n-1) & ra(2*n-1 downto 1); end if; end if; ra(2*n-1 downto 0):=ra(2*n-1) & ra(2*n-1 downto 1); -- сдвиг множимого вправо rb:=rb(n-2 downto 0)&'0'; -- сдвиг множителя влево if i=n then exit; -- если последний шаг - выходим из цикла end if; end loop; --rc(2*n-1 downto 0):=rc(2*n-1) & rc(2*n-1 downto 1); c<=rc(2*n-1 downto 0); -- передача результата на выход устройства end process; end Behavioral;
0
|
18.06.2022, 18:39 | |
Помогаю со студенческими работами здесь
8
Логический сдвиг влево,логический сдвиг вправо,алгоритм обмена двух переменных,циклический сдвиг Показать движение столбцов вправо в циклической форме (циклический сдвиг вправо) Где и когда уместно применять операции << (сдвиг влево) и >> (сдвиг вправо)? сдвиг вправо сдвиг вправо
Сдвиг вправо Edit2 Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |