OpenCores
URL https://opencores.org/ocsvn/lxp32/lxp32/trunk

Subversion Repositories lxp32

[/] [lxp32/] [trunk/] [rtl/] [lxp32_divider.vhd] - Diff between revs 2 and 6

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 2 Rev 6
Line 3... Line 3...
--
--
-- Part of the LXP32 CPU
-- Part of the LXP32 CPU
--
--
-- Copyright (c) 2016 by Alex I. Kuznetsov
-- Copyright (c) 2016 by Alex I. Kuznetsov
--
--
-- Based on the NRD (Non Restoring Division) algorithm. One division
-- Based on the NRD (Non Restoring Division) algorithm. Takes
-- takes 37 cycles.
-- 36 cycles to calculate quotient (37 for remainder).
---------------------------------------------------------------------
---------------------------------------------------------------------
 
 
library ieee;
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.numeric_std.all;
Line 19... Line 19...
                rst_i: in std_logic;
                rst_i: in std_logic;
                ce_i: in std_logic;
                ce_i: in std_logic;
                op1_i: in std_logic_vector(31 downto 0);
                op1_i: in std_logic_vector(31 downto 0);
                op2_i: in std_logic_vector(31 downto 0);
                op2_i: in std_logic_vector(31 downto 0);
                signed_i: in std_logic;
                signed_i: in std_logic;
 
                rem_i: in std_logic;
                ce_o: out std_logic;
                ce_o: out std_logic;
                quotient_o: out std_logic_vector(31 downto 0);
                result_o: out std_logic_vector(31 downto 0)
                remainder_o: out std_logic_vector(31 downto 0)
 
        );
        );
end entity;
end entity;
 
 
architecture rtl of lxp32_divider is
architecture rtl of lxp32_divider is
 
 
-- Complementor signals
-- Complementor signals
 
 
signal compl1_inv: std_logic;
signal compl_inv: std_logic;
signal compl2_inv: std_logic;
signal compl_mux: std_logic_vector(31 downto 0);
signal compl1_mux: std_logic_vector(31 downto 0);
signal compl_out: std_logic_vector(31 downto 0);
signal compl2_mux: std_logic_vector(31 downto 0);
 
signal compl1_out: std_logic_vector(31 downto 0);
 
signal compl2_out: std_logic_vector(31 downto 0);
 
 
 
signal inv_q: std_logic;
signal inv_res: std_logic;
signal inv_r: std_logic;
 
 
 
-- Divider FSM signals
-- Divider FSM signals
 
 
signal fsm_ce: std_logic:='0';
signal fsm_ce: std_logic:='0';
 
 
signal dividend: unsigned(31 downto 0);
signal dividend: unsigned(31 downto 0);
signal divisor: unsigned(32 downto 0);
signal divisor: unsigned(32 downto 0);
 
signal want_remainder: std_logic;
 
 
signal partial_remainder: unsigned(32 downto 0);
signal partial_remainder: unsigned(32 downto 0);
signal addend: unsigned(32 downto 0);
signal addend: unsigned(32 downto 0);
signal sum: unsigned(32 downto 0);
signal sum: unsigned(32 downto 0);
signal sum_positive: std_logic;
signal sum_positive: std_logic;
Line 59... Line 56...
signal ceo: std_logic:='0';
signal ceo: std_logic:='0';
 
 
-- Output restoration signals
-- Output restoration signals
 
 
signal remainder_corrector: unsigned(31 downto 0);
signal remainder_corrector: unsigned(31 downto 0);
signal remainder_res: unsigned(31 downto 0);
signal remainder_corrector_1: std_logic;
signal quotient_res: unsigned(31 downto 0);
signal remainder_pos: unsigned(31 downto 0);
 
signal result_pos: unsigned(31 downto 0);
 
 
begin
begin
 
 
compl1_inv<=op1_i(31) and signed_i when ce_i='1' else inv_q;
compl_inv<=op1_i(31) and signed_i when ce_i='1' else inv_res;
compl2_inv<=op2_i(31) and signed_i when ce_i='1' else inv_r;
compl_mux<=op1_i when ce_i='1' else std_logic_vector(result_pos);
 
 
compl1_mux<=op1_i when ce_i='1' else std_logic_vector(quotient_res);
 
compl2_mux<=op2_i when ce_i='1' else std_logic_vector(remainder_res);
 
 
 
compl_op1_inst: entity work.lxp32_compl(rtl)
compl_op1_inst: entity work.lxp32_compl(rtl)
        port map(
        port map(
                clk_i=>clk_i,
                clk_i=>clk_i,
                compl_i=>compl1_inv,
                compl_i=>compl_inv,
                d_i=>compl1_mux,
                d_i=>compl_mux,
                d_o=>compl1_out
                d_o=>compl_out
        );
 
 
 
compl_op2_inst: entity work.lxp32_compl(rtl)
 
        port map(
 
                clk_i=>clk_i,
 
                compl_i=>compl2_inv,
 
                d_i=>compl2_mux,
 
                d_o=>compl2_out
 
        );
        );
 
 
process (clk_i) is
process (clk_i) is
begin
begin
        if rising_edge(clk_i) then
        if rising_edge(clk_i) then
                if rst_i='1' then
                if rst_i='1' then
                        fsm_ce<='0';
                        fsm_ce<='0';
 
                        want_remainder<='-';
 
                        inv_res<='-';
                else
                else
                        fsm_ce<=ce_i;
                        fsm_ce<=ce_i;
                        if ce_i='1' then
                        if ce_i='1' then
                                inv_q<=(op1_i(31) xor op2_i(31)) and signed_i;
                                want_remainder<=rem_i;
                                inv_r<=op1_i(31) and signed_i;
                                if rem_i='1' then
 
                                        inv_res<=op1_i(31) and signed_i;
 
                                else
 
                                        inv_res<=(op1_i(31) xor op2_i(31)) and signed_i;
 
                                end if;
                        end if;
                        end if;
                end if;
                end if;
        end if;
        end if;
end process;
end process;
 
 
Line 110... Line 103...
end generate;
end generate;
 
 
sum<=partial_remainder+addend+(to_unsigned(0,32)&sum_subtract);
sum<=partial_remainder+addend+(to_unsigned(0,32)&sum_subtract);
sum_positive<=not sum(32);
sum_positive<=not sum(32);
 
 
-- Divisor state machine
-- Divider state machine
 
 
process (clk_i) is
process (clk_i) is
begin
begin
        if rising_edge(clk_i) then
        if rising_edge(clk_i) then
                if rst_i='1' then
                if rst_i='1' then
                        cnt<=0;
                        cnt<=0;
                        ceo<='0';
                        ceo<='0';
 
                        divisor<=(others=>'-');
 
                        dividend<=(others=>'-');
 
                        partial_remainder<=(others=>'-');
 
                        sum_subtract<='-';
 
                else
 
                        if cnt=1 then
 
                                ceo<='1';
                else
                else
                        ceo<='0';
                        ceo<='0';
 
                        end if;
 
 
 
                        if ce_i='1' then
 
                                divisor(31 downto 0)<=unsigned(op2_i);
 
                                divisor(32)<=op2_i(31) and signed_i;
 
                        end if;
 
 
                        if fsm_ce='1' then
                        if fsm_ce='1' then
                                dividend<=unsigned(compl1_out(30 downto 0)&"0");
                                dividend<=unsigned(compl_out(30 downto 0)&"0");
                                divisor<=unsigned("0"&compl2_out);
                                partial_remainder<=to_unsigned(0,32)&compl_out(31);
                                partial_remainder<=to_unsigned(0,32)&compl1_out(31);
                                sum_subtract<=not divisor(32);
                                sum_subtract<='1';
                                if want_remainder='1' then
                                cnt<=34;
                                cnt<=34;
                        elsif cnt>0 then
                                else
 
                                        cnt<=33;
 
                                end if;
 
                        else
                                partial_remainder<=sum(31 downto 0)&dividend(31);
                                partial_remainder<=sum(31 downto 0)&dividend(31);
                                sum_subtract<=sum_positive;
                                sum_subtract<=sum_positive xor divisor(32);
                                dividend<=dividend(30 downto 0)&sum_positive;
                                dividend<=dividend(30 downto 0)&sum_positive;
                                if cnt=1 then
                                if cnt>0 then
                                        ceo<='1';
 
                                end if;
 
                                cnt<=cnt-1;
                                cnt<=cnt-1;
                        else
                                end if;
                                dividend<=(others=>'-');
 
                                divisor<=(others=>'-');
 
                                partial_remainder<=(others=>'-');
 
                        end if;
                        end if;
                end if;
                end if;
        end if;
        end if;
end process;
end process;
 
 
Line 149... Line 154...
 
 
process (clk_i) is
process (clk_i) is
begin
begin
        if rising_edge(clk_i) then
        if rising_edge(clk_i) then
                for i in remainder_corrector'range loop
                for i in remainder_corrector'range loop
                        remainder_corrector(i)<=divisor(i) and not sum_positive;
                        remainder_corrector(i)<=(divisor(i) xor divisor(32)) and not sum_positive;
                end loop;
                end loop;
                quotient_res<=dividend;
                remainder_corrector_1<=divisor(32) and not sum_positive;
                remainder_res<=partial_remainder(32 downto 1)+remainder_corrector;
                remainder_pos<=partial_remainder(32 downto 1)+remainder_corrector+
 
                        (to_unsigned(0,31)&remainder_corrector_1);
        end if;
        end if;
end process;
end process;
 
 
quotient_o<=compl1_out;
result_pos<=remainder_pos when want_remainder='1' else dividend;
remainder_o<=compl2_out;
 
 
result_o<=compl_out;
ce_o<=ceo;
ce_o<=ceo;
 
 
end architecture;
end architecture;
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.