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

Subversion Repositories lxp32

[/] [lxp32/] [trunk/] [rtl/] [lxp32_divider.vhd] - Blame information for rev 2

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 ring0_mipt
---------------------------------------------------------------------
2
-- Divider
3
--
4
-- Part of the LXP32 CPU
5
--
6
-- Copyright (c) 2016 by Alex I. Kuznetsov
7
--
8
-- Based on the NRD (Non Restoring Division) algorithm. One division
9
-- takes 37 cycles.
10
---------------------------------------------------------------------
11
 
12
library ieee;
13
use ieee.std_logic_1164.all;
14
use ieee.numeric_std.all;
15
 
16
entity lxp32_divider is
17
        port(
18
                clk_i: in std_logic;
19
                rst_i: in std_logic;
20
                ce_i: in std_logic;
21
                op1_i: in std_logic_vector(31 downto 0);
22
                op2_i: in std_logic_vector(31 downto 0);
23
                signed_i: in std_logic;
24
                ce_o: out std_logic;
25
                quotient_o: out std_logic_vector(31 downto 0);
26
                remainder_o: out std_logic_vector(31 downto 0)
27
        );
28
end entity;
29
 
30
architecture rtl of lxp32_divider is
31
 
32
-- Complementor signals
33
 
34
signal compl1_inv: std_logic;
35
signal compl2_inv: std_logic;
36
signal compl1_mux: std_logic_vector(31 downto 0);
37
signal compl2_mux: std_logic_vector(31 downto 0);
38
signal compl1_out: std_logic_vector(31 downto 0);
39
signal compl2_out: std_logic_vector(31 downto 0);
40
 
41
signal inv_q: std_logic;
42
signal inv_r: std_logic;
43
 
44
-- Divider FSM signals
45
 
46
signal fsm_ce: std_logic:='0';
47
 
48
signal dividend: unsigned(31 downto 0);
49
signal divisor: unsigned(32 downto 0);
50
 
51
signal partial_remainder: unsigned(32 downto 0);
52
signal addend: unsigned(32 downto 0);
53
signal sum: unsigned(32 downto 0);
54
signal sum_positive: std_logic;
55
signal sum_subtract: std_logic;
56
 
57
signal cnt: integer range 0 to 34:=0;
58
 
59
signal ceo: std_logic:='0';
60
 
61
-- Output restoration signals
62
 
63
signal remainder_corrector: unsigned(31 downto 0);
64
signal remainder_res: unsigned(31 downto 0);
65
signal quotient_res: unsigned(31 downto 0);
66
 
67
begin
68
 
69
compl1_inv<=op1_i(31) and signed_i when ce_i='1' else inv_q;
70
compl2_inv<=op2_i(31) and signed_i when ce_i='1' else inv_r;
71
 
72
compl1_mux<=op1_i when ce_i='1' else std_logic_vector(quotient_res);
73
compl2_mux<=op2_i when ce_i='1' else std_logic_vector(remainder_res);
74
 
75
compl_op1_inst: entity work.lxp32_compl(rtl)
76
        port map(
77
                clk_i=>clk_i,
78
                compl_i=>compl1_inv,
79
                d_i=>compl1_mux,
80
                d_o=>compl1_out
81
        );
82
 
83
compl_op2_inst: entity work.lxp32_compl(rtl)
84
        port map(
85
                clk_i=>clk_i,
86
                compl_i=>compl2_inv,
87
                d_i=>compl2_mux,
88
                d_o=>compl2_out
89
        );
90
 
91
process (clk_i) is
92
begin
93
        if rising_edge(clk_i) then
94
                if rst_i='1' then
95
                        fsm_ce<='0';
96
                else
97
                        fsm_ce<=ce_i;
98
                        if ce_i='1' then
99
                                inv_q<=(op1_i(31) xor op2_i(31)) and signed_i;
100
                                inv_r<=op1_i(31) and signed_i;
101
                        end if;
102
                end if;
103
        end if;
104
end process;
105
 
106
-- Main adder/subtractor
107
 
108
addend_gen: for i in addend'range generate
109
        addend(i)<=divisor(i) xor sum_subtract;
110
end generate;
111
 
112
sum<=partial_remainder+addend+(to_unsigned(0,32)&sum_subtract);
113
sum_positive<=not sum(32);
114
 
115
-- Divisor state machine
116
 
117
process (clk_i) is
118
begin
119
        if rising_edge(clk_i) then
120
                if rst_i='1' then
121
                        cnt<=0;
122
                        ceo<='0';
123
                else
124
                        ceo<='0';
125
                        if fsm_ce='1' then
126
                                dividend<=unsigned(compl1_out(30 downto 0)&"0");
127
                                divisor<=unsigned("0"&compl2_out);
128
                                partial_remainder<=to_unsigned(0,32)&compl1_out(31);
129
                                sum_subtract<='1';
130
                                cnt<=34;
131
                        elsif cnt>0 then
132
                                partial_remainder<=sum(31 downto 0)&dividend(31);
133
                                sum_subtract<=sum_positive;
134
                                dividend<=dividend(30 downto 0)&sum_positive;
135
                                if cnt=1 then
136
                                        ceo<='1';
137
                                end if;
138
                                cnt<=cnt-1;
139
                        else
140
                                dividend<=(others=>'-');
141
                                divisor<=(others=>'-');
142
                                partial_remainder<=(others=>'-');
143
                        end if;
144
                end if;
145
        end if;
146
end process;
147
 
148
-- Output restoration circuit
149
 
150
process (clk_i) is
151
begin
152
        if rising_edge(clk_i) then
153
                for i in remainder_corrector'range loop
154
                        remainder_corrector(i)<=divisor(i) and not sum_positive;
155
                end loop;
156
                quotient_res<=dividend;
157
                remainder_res<=partial_remainder(32 downto 1)+remainder_corrector;
158
        end if;
159
end process;
160
 
161
quotient_o<=compl1_out;
162
remainder_o<=compl2_out;
163
ce_o<=ceo;
164
 
165
end architecture;

powered by: WebSVN 2.1.0

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