c2b040193a777c09bdc595c95492b57a2521db87
Stefan Schuermans added file headers

Stefan Schuermans authored 12 years ago

1) -- MIPS I system
2) -- Copyright 2011-2012 Stefan Schuermans <stefan@schuermans.info>
3) -- Copyleft GNU public license V2 or later
4) --          http://www.gnu.org/copyleft/gpl.html
5) 
Stefan Schuermans implemented divider

Stefan Schuermans authored 12 years ago

6) LIBRARY ieee;
7) USE ieee.std_logic_1164.all;
8) USE ieee.numeric_std.all;
9) USE work.mips_types.all;
10) 
11) ENTITY e_mips_div IS
12)     PORT (
13)         rst:      IN  std_logic;
14)         clk:      IN  std_logic;
15)         i_num:    IN  std_logic_vector(31 DOWNTO 0);
16)         i_denom:  IN  std_logic_vector(31 DOWNTO 0);
17)         i_signed: IN  std_logic;
18)         i_start:  IN  std_logic;
19)         o_busy:   OUT std_logic;
20)         o_res:    OUT std_logic_vector(31 DOWNTO 0);
21)         o_rem:    OUT std_logic_vector(31 DOWNTO 0)
22)     );
23) END ENTITY e_mips_div;
24) 
25) ARCHITECTURE a_mips_div OF e_mips_div IS
26) 
27)     SUBTYPE t_state IS natural RANGE 0 TO 33;
28)     SIGNAL n_state: t_state;
Stefan Schuermans add initial values for regi...

Stefan Schuermans authored 12 years ago

29)     SIGNAL r_state: t_state := 0;
Stefan Schuermans implemented divider

Stefan Schuermans authored 12 years ago

30) 
31)     SIGNAL n_num:   signed(63 DOWNTO 0);
32)     SIGNAL n_denom: signed(63 DOWNTO 0);
33)     SIGNAL n_neg:   boolean;
34)     SIGNAL n_res:   signed(31 DOWNTO 0);
Stefan Schuermans add initial values for regi...

Stefan Schuermans authored 12 years ago

35)     SIGNAL r_num:   signed(63 DOWNTO 0) := (OTHERS => '0');
36)     SIGNAL r_denom: signed(63 DOWNTO 0) := (OTHERS => '0');
37)     SIGNAL r_neg:   boolean             := false;
38)     SIGNAL r_res:   signed(31 DOWNTO 0) := (OTHERS => '0');
39)     SIGNAL s_rem:   signed(31 DOWNTO 0) := (OTHERS => '0');
Stefan Schuermans implemented divider

Stefan Schuermans authored 12 years ago

40) 
41) BEGIN
42) 
43)     p_div: PROCESS(r_state, r_num, r_denom, r_neg, r_res,
44)                    i_num, i_denom, i_signed, i_start)
45)         VARIABLE v_num:   signed(31 DOWNTO 0);
46)         VARIABLE v_denom: signed(31 DOWNTO 0);
47)         VARIABLE v_diff:  signed(63 DOWNTO 0);
48)     BEGIN
49)         o_busy  <= '0';
50)         n_state <= r_state;
51)         n_num   <= r_num;
52)         n_denom <= r_denom;
53)         n_neg   <= r_neg;
54)         n_res   <= r_res;
55)         s_rem   <= (OTHERS => '0');
56)         CASE r_state IS
57)             WHEN 0 =>
58)                 IF i_start = '1' THEN
59)                     o_busy  <= '1';
60)                     n_state <= 1;
61)                     IF i_signed = '1' THEN
62)                         IF i_num(31) = '1' THEN
63)                             v_num := -signed(i_num);
64)                         ELSE
65)                             v_num := signed(i_num);
66)                         END IF;
67)                         IF i_denom(31) = '1' THEN
68)                             v_denom := -signed(i_denom);
69)                         ELSE
70)                             v_denom := signed(i_denom);
71)                         END IF;
72)                         n_neg <= i_num(31) = '1' XOR i_denom(31) = '1';
73)                     ELSE
74)                         v_num   := signed(i_num);
75)                         v_denom := signed(i_denom);
76)                         n_neg   <= false;
77)                     END IF;
78)                     n_num   <= X"00000000" & v_num;
79)                     n_denom <= "0" & v_denom & X"0000000" & "000";
80)                 END IF;
81)             WHEN 33 =>
82)                 o_busy  <= '0';
83)                 n_state <= 0;
84)                 IF r_neg THEN
85)                     n_res <= -r_res;
86)                     s_rem <= -n_num(31 DOWNTO 0);
87)                 ELSE
88)                     n_res <= r_res;
89)                     s_rem <= n_num(31 DOWNTO 0);
90)                 END IF;
91)             WHEN OTHERS =>
92)                 o_busy  <= '1';
93)                 n_state <= r_state + 1;
94)                 v_diff := r_num - r_denom;
95)                 IF (v_diff(63) = '0') THEN
96)                     n_num <= v_diff;
97)                     n_res <= r_res(30 DOWNTO 0) & "1";
98)                 ELSE
99)                     n_num <= r_num;
Stefan Schuermans fix divider (result)

Stefan Schuermans authored 12 years ago

100)                     n_res <= r_res(30 DOWNTO 0) & "0";