0 / 0 / 0
Регистрация: 13.09.2020
Сообщений: 6
1

Сдвиг множимого вправо

15.05.2021, 14:11. Показов 759. Ответов 7
Метки vhdl (Все метки)

Всем привет!
Дали задачку в Университете:

Опе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
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
15.05.2021, 14:11
Ответы с готовыми решениями:

Сдвиг на 2 разряда вправо
Добрый день, задание гласит следующим образом: Синтезировать регистр сдвига на 2 разряда вправо на...

Произвести циклический сдвиг вправо 8-байтового кода
Доброго времени суток! Дали вот такое задание &quot;Произвести циклический сдвиг вправо 8-байтового...

Как реализовать сдвиг вправо 16-разрядного числа?
Нужно сдвинуть 16-разрядное число на один разряд вправо. На бумаге это одна строчка. 1010 1111...

Логический сдвиг влево,логический сдвиг вправо,алгоритм обмена двух переменных,циклический сдвиг
Битовые сдвиги.FW4,msstudio 13,на C# 1)Реализовать быстрое умножение на 2(логический сдвиг влево)...

7
2782 / 2020 / 451
Регистрация: 11.09.2009
Сообщений: 7,518
15.05.2021, 22:52 2
Цитата Сообщение от Darkuss Посмотреть сообщение
Я с ней справился ... Ниже листинг кода для первой задачи ... Помогите, пожалуйста, переделать этот код для второй задачи
Ай-яй-яй! Обманывать нехорошо. С первой задачей справились не вы, а Н.В. Ефремов, автор методички "Проектирование операционных устройств в кристалле ПЛИС с использованием языка VHDL в САПР QUARTUSII", ещё в 2019 году, откуда со стр. 21 вы и списали этот "листинг".
Миниатюры
Сдвиг множимого вправо  
0
2782 / 2020 / 451
Регистрация: 11.09.2009
Сообщений: 7,518
15.05.2021, 22:59 3
Цитата Сообщение от Darkuss Посмотреть сообщение
Сколько ни пытался, нормально реализовать сдвиг множимого вправо не получилось.
Теперь слабо в это верится, но нельзя же совсем лишать шанса...
Выкладывайте ваши попытки, укажите, где и что не получилось.
0
0 / 0 / 0
Регистрация: 17.06.2022
Сообщений: 3
17.06.2022, 12:19 4
Добрый день. Столкнулся с такой же проблемой. Написал код, но ответ получается неверный. Подскажите, пожалуйста, что может быть не так?
Миниатюры
Сдвиг множимого вправо   Сдвиг множимого вправо  
0
ValeryS
17.06.2022, 19:50
  #5
 Комментарий модератора 
Noswell, правила п 5.18
Запрещено размещать задания и решения в виде картинок (кроме формул и блок-схем) и других файлов с их текстом.
приведите код обрамленный соответствующими тэгами
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
3 / 3 / 0
Регистрация: 23.03.2021
Сообщений: 35
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
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
18.06.2022, 18:39
Помогаю со студенческими работами здесь

Показать движение столбцов вправо в циклической форме (циклический сдвиг вправо)
Нужно вывести матрицу (где элементы целые числа) на экран. Создать программу, которая на той же...

Где и когда уместно применять операции << (сдвиг влево) и >> (сдвиг вправо)?
Кто может привести пример , когда нужно использовать операции: 1) &lt;&lt; сдвиг влево 2) &gt;&gt; сдвиг...

сдвиг вправо
A = dac493a2; если сдвинуть в калькуляторе rsh на 1 получится 6d6249d1 А если сделать так в...

сдвиг вправо
помогите написать команды, которые сдвигают три байта на 1 бит вправо.

Циклический сдвиг вправо
Нужно написать программу, которая производит циклический сдвиг десятичного числа со знаком вправо...

Циклический сдвиг вправо
Не понимаю,как мне сделать циклический сдвиг вправо сразу восьми байт?=(


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2022, CyberForum.ru