Перейти к содержанию
    

параметризируемый модуль целочисленного деления

Просто решил поделиться... :)

 

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;

ENTITY DIVISION IS
GENERIC(SIZE: INTEGER := 64);
PORT(RESET: IN STD_LOGIC;
EN: IN STD_LOGIC;
CLK: IN STD_LOGIC;
NUM: IN STD_LOGIC_VECTOR((SIZE - 1) DOWNTO 0);
DEN: IN STD_LOGIC_VECTOR((SIZE - 1) DOWNTO 0);
RES: OUT STD_LOGIC_VECTOR((SIZE - 1) DOWNTO 0);
RM: OUT STD_LOGIC_VECTOR((SIZE - 1) DOWNTO 0)  );
END DIVISION;

ARCHITECTURE BEHAV OF DIVISION IS
SIGNAL BUF: STD_LOGIC_VECTOR((2 * SIZE - 1) DOWNTO 0);
SIGNAL DBUF: STD_LOGIC_VECTOR((SIZE - 1) DOWNTO 0);
SIGNAL SM: INTEGER RANGE 0 TO SIZE;

ALIAS BUF1 IS BUF((2 * SIZE - 1) DOWNTO SIZE);
ALIAS BUF2 IS BUF((SIZE - 1) DOWNTO 0);

BEGIN
PROCESS(RESET, EN, CLK)
BEGIN
IF RESET = '1' THEN
RES <= (OTHERS => '0');
RM <= (OTHERS => '0');
SM <= 0;
ELSIF RISING_EDGE(CLK) THEN
IF EN = '1' THEN
CASE SM IS
WHEN 0 =>
BUF1 <= (OTHERS => '0');
BUF2 <= NUM;
DBUF <= DEN;
RES <= BUF2;
RM <= BUF1;
SM <= SM + 1;
WHEN OTHERS=>
IF BUF((2 * SIZE - 2) DOWNTO (SIZE - 1)) >= DBUF THEN
BUF1 <= '0' & (BUF((2 * SIZE - 3) DOWNTO (SIZE - 1)) - DBUF((SIZE - 2) DOWNTO 0));
BUF2 <= BUF2((SIZE - 2) DOWNTO 0) & '1';
ELSE
BUF <= BUF((2 * SIZE - 2) DOWNTO 0) & '0';
END IF;
IF SM /= SIZE THEN
SM <= SM + 1;
ELSE
SM <= 0;
END IF;
END CASE;
END IF;
END IF;
END PROCESS;
END BEHAV;

 

простой тестбенч для проверки

 

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;

ENTITY test_div IS
END test_div;

ARCHITECTURE behavior OF test_div IS 

    COMPONENT DIVISION
    PORT(
         RESET : IN  std_logic;
         EN : IN  std_logic;
         CLK : IN  std_logic;
         NUM : IN  std_logic_vector(63 downto 0);
         DEN : IN  std_logic_vector(63 downto 0);
         RES : OUT  std_logic_vector(63 downto 0);
         RM : OUT  std_logic_vector(63 downto 0)
        );
    END COMPONENT;
    

    signal RESET : std_logic := '0';
   signal EN : std_logic := '0';
   signal CLK : std_logic := '0';
   signal NUM : std_logic_vector(63 downto 0) := (others => '0');
   signal DEN : std_logic_vector(63 downto 0) := (others => '0');
   signal RES : std_logic_vector(63 downto 0);
   signal RM : std_logic_vector(63 downto 0);

   -- Clock period definitions
   constant CLK_period : time := 10 ns;

BEGIN

    -- Instantiate the Unit Under Test (UUT)
   uut: DIVISION PORT MAP (
          RESET => RESET,
          EN => EN,
          CLK => CLK,
          NUM => NUM,
          DEN => DEN,
          RES => RES,
          RM => RM
        );

   -- Clock process definitions
   CLK_process :process
   begin
        CLK <= '0';
        wait for CLK_period/2;
        CLK <= '1';
        wait for CLK_period/2;
   end process;


   -- Stimulus process
start_gen: process
begin
en <= '0'; wait for 120 ns;
en <= '1';
wait;
end process;

reset_gen: process
begin
RESET <= '1'; wait for 20 ns;
RESET <= '0';
wait;
end process;

data_gen: process
begin
NUM <= "0000000000000000000000000000000001000100000000000000000000000000";
DEN <= "0000000000000000000000000000000000000000101010100000000000000000";
wait;
end process;

END;

 

PS Может кому-то пригодиться... ;)

PS PS Будут идеи/алгоритмы как реализовать лучше, быстрее и оптимальней - пишите...

PS PS PS Найдете баги - тоже пишите...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

а может кто-то поделиться параметризируемым делением с фиксированной запятой? :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

PS PS Будут идеи/алгоритмы как реализовать лучше, быстрее и оптимальней - пишите...

Хорошо бы еще словами объяснять в чем именно идея и в чем отличие от.. Мне VHDL честно скажу непонятен - если после С-С++ довольно спокойно стал работать с Verilog, без проблем с m-скриптами Матлаба (жаль что индексы с 1 а не с нуля), Phyton тоже нормуль, то вот в VHDL въехать не могу никак глядя на исходники (да и не очень понимаю зачем, когда баловство пройдет и нужен будет ASIC - понадобятся Verilog сурцы. Кстати скоспилировал тут конвертор VHDL2Verilog - ничего вроде так..

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Мне VHDL честно скажу непонятен - если после С-С++ довольно спокойно стал работать с Verilog, без проблем с m-скриптами Матлаба (жаль что индексы с 1 а не с нуля), Phyton тоже нормуль, то вот в VHDL въехать не могу никак глядя на исходники (да и не очень понимаю зачем, когда баловство пройдет и нужен будет ASIC - понадобятся Verilog сурцы. Кстати скоспилировал тут конвертор VHDL2Verilog - ничего вроде так..

не для холивара...

я пишу на VHDL, Verilog читаю (но мне он не нравится, есть на то свои причины, но если очень нужно будет буду писать и на Verilog) :)

Как говориться на вкус и цвет товарищей нет... ;)

Есть довольно неплохая книга у Полякова "языки VHDL, Verilog в проектировании цифровой аппаратуры". Там приводятся все базовые конструкции для этих двух языков... Посмотрите возможно хотя бы будете читать описания на VHDL.

Кстати я по этой книге Verilog научился читать...

 

Хорошо бы еще словами объяснять в чем именно идея и в чем отличие от..

у меня здесь в принципе ничего нового, это просто по другому переписанный стандартный RestoreDiv.

Количество тактов деления равна разрядности делимого/делителя, в данном алгоритме они равны...

 

Может у Вас реализация которая быстрее выполняется (в тактах) или есть реализация, которая еще меньше кушает логики... или имеются таковые алгоритмы...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Есть целочисленная делилка, выдающая два бита за такт. По поводу деления, посмотрите патенты компании Intel, там предложены несколько очень интересных методов. Еще попадалось что-то интересное в патентах компании Mitsubishi, если сейчас правильно помню, просто этим вопросом задавался довольно давно.

Изменено пользователем smoke_111

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Есть целочисленная делилка, выдающая два бита за такт. По поводу деления, посмотрите патенты компании Intel, там предложены несколько очень интересных методов. Еще попадалось что-то интересное в патентах компании Mitsubishi, если сейчас правильно помню, просто этим вопросом задавался довольно давно.

А Вы можете поделиться?

Пожалуйста, постарайтесь вспомнить :)

 

Очень интересно посмотреть....

 

upd

вот ссылка на документ от интела - вроде то, о чем писал smoke_111

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

погуглить можно по словам

 

SRT division

 

Radix 4 division

 

и т.п.

вроде то же самое, только несколько бит за такт - сколько бит зависит от размера таблицы (look-up-table)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

а может кто-то поделиться параметризируемым делением с фиксированной запятой? :)

А какие в итоге требование к разрядности, быстродейтсвию, аппаратурным затратам, ну и семейству ПЛИС?

Это для проекта или чисто теория?

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А какие в итоге требование к разрядности, быстродейтсвию, аппаратурным затратам, ну и семейству ПЛИС?

Это для проекта или чисто теория?

целая часть - 32 разряда (но хотелось бы чтобы была возможность увеличения до 64 бит - возможно оно и никогда не понадобиться)

дробная часть - 16 разряда (но хотелось бы чтобы была возможность увеличения до 32 бит - возможно оно и никогда не понадобиться)

 

есть планы вставить в проект - для увеличения точности расчетов...

 

ПЛИС spartan6. Сейчас используется ПЛИС 6slx16csg324-3

Быстродействие хотелось бы иметь выше 150 МГц (для модуля с целой части 32 разряда и 16 разрядов дробной части).

Затраты чем меньше, тем лучше...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Прошу прощения, однако тот компонент оказался для нормализованных чисел с плавающей точкой, я посмотрел коды. Коды я выложить не могу, но принцип мне рассказать никто не мешает, для целочисленного деления он будет тем же. Если интересно, то напишу.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 smoke_111

пишите конечно B)

Долго я собирался с духом. В целом, концепция деления в столбик это алгоритм двоичного поиска, возможно это очевидно, но на всякий случай подчеркну, каждый раз вычитая мы проверяем принадлежность результата деления к той или иной стороне.

Что отсюда следует, можно организовать поиск, деля область не на две части, а на 4, 8 , ну или на сколько вам позволит ваша совесть, требования к ресурсоемкости и скорости (это даст вам соответсвенно 2, 3 и т.д. разрядов за одну операцию ).

 

Как это сделать? Приведу пример для разбиения на 4 части, для положительных чисел :

Пусть N(15:0) - делимое, D(15:0) - делитель, R_i(15:0) - остаток i -й итерации

 

Берем старшие два бита N(15:14) в параллель вычисляем следующие выражения (1)"расширяем нулями"&N(15:14) - 3*D(15:0); (2)"расширяем нулями"&N(15:14) - 2*D(15:0);(3)"расширяем нулями"&N(15:14) - D(15:0)

Если (1) больше или равно нулю, то первые два бита результат деления равны "11"; если (1) меньше нуля, но (2) >=0 то первые два бита результата деления соответсвенно равны 10; Если (1) <0; (2)<0 (3)>=0, то первый два бита равны 01, если все три меньше нуля, то значит первые два бита равны нулю, Выбираем соответсвующий остаток прилепляем к нему сбоку следующие два бита делимого N(13:12) повторять описанные выше действия, до полного удовлетворения :-)

Изменено пользователем smoke_111

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...