Initial Commit (steal code from https://github.com/jop-devel/jop)
[ipdf/vfpu.git] / src / serial_div.vhd
1 -------------------------------------------------------------------------------
2 --
3 -- Project:     <Floating Point Unit Core>
4 --      
5 -- Description: division entity for the division unit
6 -------------------------------------------------------------------------------
7 --
8 --                              100101011010011100100
9 --                              110000111011100100000
10 --                              100000111011000101101
11 --                              100010111100101111001
12 --                              110000111011101101001
13 --                              010000001011101001010
14 --                              110100111001001100001
15 --                              110111010000001100111
16 --                              110110111110001011101
17 --                              101110110010111101000
18 --                              100000010111000000000
19 --
20 --      Author:          Jidan Al-eryani 
21 --      E-mail:          [email protected]
22 --
23 --  Copyright (C) 2006
24 --
25 --      This source file may be used and distributed without        
26 --      restriction provided that this copyright statement is not   
27 --      removed from the file and that any derivative work contains 
28 --      the original copyright notice and the associated disclaimer.
29 --                                                           
30 --              THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY     
31 --      EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED   
32 --      TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS   
33 --      FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR      
34 --      OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,         
35 --      INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    
36 --      (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE   
37 --      GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR        
38 --      BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF  
39 --      LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT  
40 --      (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT  
41 --      OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE         
42 --      POSSIBILITY OF SUCH DAMAGE. 
43 --
44
45 library ieee ;
46 use ieee.std_logic_1164.all;
47 use ieee.std_logic_unsigned.all;
48 use ieee.std_logic_misc.all;
49
50 library work;
51 use work.fpupack.all;
52
53
54 entity serial_div is
55         port(
56                          clk_i                          : in std_logic;
57                          dvdnd_i                        : in std_logic_vector(2*(FRAC_WIDTH+2)-1 downto 0); -- hidden(1) & fraction(23)
58                          dvsor_i                        : in std_logic_vector(FRAC_WIDTH+3 downto 0);
59                          sign_dvd_i             : in std_logic;
60                          sign_div_i             : in std_logic;
61                          start_i                        : in std_logic;
62                          ready_o                        : out std_logic;
63                          qutnt_o                        : out std_logic_vector(FRAC_WIDTH+3 downto 0);
64                          rmndr_o                        : out std_logic_vector(FRAC_WIDTH+3 downto 0);
65                          sign_o                         : out std_logic;
66                          div_zero_o                     : out std_logic
67                 );
68 end serial_div;
69
70 architecture rtl of serial_div is
71
72 type t_state is (waiting,busy);
73
74 signal s_qutnt_o, s_rmndr_o : std_logic_vector(FRAC_WIDTH+3 downto 0);
75
76 signal s_dvdnd_i : std_logic_vector(2*(FRAC_WIDTH+2)-1 downto 0);
77 signal s_dvsor_i : std_logic_vector(FRAC_WIDTH+3 downto 0);
78 signal s_sign_dvd_i, s_sign_div_i, s_sign_o : std_logic;
79 signal s_div_zero_o : std_logic;
80 signal s_start_i, s_ready_o : std_logic;
81 signal s_state : t_state;
82 signal s_count : integer range 0 to FRAC_WIDTH+3;
83 signal s_dvd : std_logic_vector(FRAC_WIDTH+3 downto 0);
84
85 begin
86
87
88 -- Input Register
89 process(clk_i)
90 begin
91         if rising_edge(clk_i) then      
92                 s_dvdnd_i <= dvdnd_i;
93                 s_dvsor_i <= dvsor_i;
94                 s_sign_dvd_i<= sign_dvd_i;
95                 s_sign_div_i<= sign_div_i;
96                 s_start_i <= start_i;
97         end if;
98 end process;    
99
100 -- Output Register
101 --process(clk_i)
102 --begin
103 --      if rising_edge(clk_i) then      
104                 qutnt_o <= s_qutnt_o;
105                 rmndr_o <= s_rmndr_o;
106                 sign_o <= s_sign_o;     
107                 ready_o <= s_ready_o;
108                 div_zero_o <= s_div_zero_o;
109 --      end if;
110 --end process;
111
112 s_sign_o <= sign_dvd_i xor sign_div_i;
113 s_div_zero_o <= '1' when or_reduce(s_dvsor_i)='0' and or_reduce(s_dvdnd_i)='1' else '0';
114
115 -- FSM
116 process(clk_i)
117 begin
118         if rising_edge(clk_i) then
119                 if s_start_i ='1' then
120                         s_state <= busy;
121                         s_count <= 26; 
122                 elsif s_count=0 and s_state=busy then
123                         s_state <= waiting;
124                         s_ready_o <= '1';
125                         s_count <=26; 
126                 elsif s_state=busy then
127                         s_count <= s_count - 1;
128                 else
129                         s_state <= waiting;
130                         s_ready_o <= '0';
131                 end if;
132         end if; 
133 end process;
134
135
136 process(clk_i)
137 variable v_div : std_logic_vector(26 downto 0);
138 begin
139         if rising_edge(clk_i) then
140                 --Reset
141                 if s_start_i ='1' then
142                         s_qutnt_o <= (others =>'0');
143                         s_rmndr_o <= (others =>'0');
144                 elsif s_state=busy then
145                         if s_count=26 then
146                                 v_div := "000" & s_dvdnd_i(49 downto 26);
147                         else    
148                                 v_div:= s_dvd;
149                         end if;
150                         if v_div < s_dvsor_i then 
151                                 s_qutnt_o(s_count) <= '0';
152                         else
153                                 s_qutnt_o(s_count) <= '1';
154                                 v_div:=v_div-s_dvsor_i; 
155                         end if; 
156                         s_rmndr_o <= v_div;
157                         s_dvd <= v_div(25 downto 0)&'0';                        
158                 end if;
159         end if; 
160 end process;
161
162 end rtl;
163

UCC git Repository :: git.ucc.asn.au