2016-12-20 1 views
-1

Я пишу код в VHDL, чтобы быть синтезированным на FPGA XilinX. Обычно я использую GHDL для моделирования моих тестовых стендов. Мне нужно использовать ядро ​​деления XilinX, чтобы разделить на переменную, но я не уверен, как это сделать, поскольку в документации XilinX нет примеров. Должен ли я использовать программное обеспечение XilinX для создания компонента VHDL для разделителя? Или XilinX неявно понимает, что делитель означает использование ядра IP? Если мой второй оператор верен, как я смогу имитировать это с помощью GHDL или мне придется использовать инструмент моделирования XilinX? Я мог бы действительно сделать с минимальным примером использования ядра делителя XilinX для реализации деления на переменную, например. что-то вроде этого:Как использовать Xilinx Division IP Core

library ieee;  
use ieee.std_logic_1164.all; 
use ieee.std_logic_1164.all; 

entity DividingExample is 
    port (
    clk : in std_logic; 
    reset : in std_logic; 
    InputSignal : in std_logic_vector(15 downto 0); 
    OutputSignal : out std_logic_vector(15 downto 0) 
    ); 
end DividingExample; 

architecture behaviour of DividingExample is 
-- declarations 
    signal numerator : integer; 
begin 
-- behaviour 
    process(clk) 
    begin 
    if(rising_edge(clk)) then 
     if(reset = '1') then 
     -- reset values 
     numerator <= 1000; 
     else 
     -- calculate value to be output 
     OutputSignal <= numerator/to_integer(signed(InputSignal)) 
    end if; 
    end if; 
end process; 
end behaviour; 

Этот пример кода, очевидно, не работает, как деление (оператор «/») не определено для целого типа данных. Как я могу это сделать?

ответ

0

В итоге я написал свой собственный код деления, который был значительно быстрее и проще реализовать, чем с использованием IP-ядра XilinX. Я использовал алгоритм двоичного деления, подробно описанный here, и написал следующий код VHDL для подписанного 32-битного деления:

function Divide(N : signed(31 downto 0); D : signed(31 downto 0)) return signed is                              
    variable Q : signed(31 downto 0) := to_signed(0, 32);              
    variable R : signed(31 downto 0) := to_signed(0, 32);              
    variable l : line;                       
    constant N_Abs : signed(31 downto 0) := abs(N);                
    constant D_Abs : signed(31 downto 0) := abs(D);                
    begin                           
    -- behaviour                         
    for i in N_Abs'high downto 0 loop                    
     R := shift_left(R, 1);                      
     R(0) := N_Abs(i);                       
     if R >= D_Abs then                       
     R := R - D;                        
     Q(i) := '1';                        
     end if;                          
    end loop;                          

    if ((N < 0 and D > 0) or (N > 0 and D < 0)) then                
     return -Q;                         
    else                           
     return Q;                         
    end if;                          
    end function; 
Смежные вопросы