Jump to content
    

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

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

 

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 Найдете баги - тоже пишите...

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

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

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

 

Share this post


Link to post
Share on other sites

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

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

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

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

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

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

 

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

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

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

 

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

Share this post


Link to post
Share on other sites

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

Edited by smoke_111

Share this post


Link to post
Share on other sites

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

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

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

 

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

 

upd

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

Share this post


Link to post
Share on other sites

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

 

SRT division

 

Radix 4 division

 

и т.п.

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

Share this post


Link to post
Share on other sites

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

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

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

 

Share this post


Link to post
Share on other sites

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

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

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

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

 

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

 

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

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

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

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

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) повторять описанные выше действия, до полного удовлетворения :-)

Edited by smoke_111

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...