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

Subversion Repositories mips32r1

[/] [mips32r1/] [trunk/] [Hardware/] [MIPS32_Standalone/] [Divide.v] - Blame information for rev 10

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 10 ayersg
`timescale 1ns / 1ns
2
/*
3
 * File         : Divide.v
4
 * Project      : University of Utah, XUM Project MIPS32 core
5
 * Creator(s)   : Neil Russell
6
 *
7
 * Modification History:
8
 *  Rev   Date         Initials  Description of Change
9
 *  1.0   6-Nov-2012   NJR       Initial design.
10
 *
11
 * Description:
12
 *  A multi-cycle 32-bit divider.
13
 *
14
 *  On any cycle that one of OP_div or OP_divu are true, the Dividend and
15
 *  Divisor will be captured and a multi-cycle divide operation initiated.
16
 *  Stall will go true on the next cycle and the first cycle of the divide
17
 *  operation completed.  After some time (about 32 cycles), Stall will go
18
 *  false on the same cycle that the result becomes valid.  OP_div or OP_divu
19
 *  will abort any currently running divide operation and initiate a new one.
20
 */
21
module Divide(
22
    input           clock,
23
    input           reset,
24
    input           OP_div,     // True to initiate a signed divide
25
    input           OP_divu,    // True to initiate an unsigned divide
26
    input  [31:0]   Dividend,
27
    input  [31:0]   Divisor,
28
    output [31:0]   Quotient,
29
    output [31:0]   Remainder,
30
    output          Stall       // True while calculating
31
    );
32
 
33
 
34
    reg             active;     // True if the divider is running
35
    reg             neg;        // True if the result will be negative
36
    reg [4:0]       cycle;      // Number of cycles to go
37
 
38
    reg [31:0]      result;     // Begin with dividend, end with quotient
39
    reg [31:0]      denom;      // Divisor
40
    reg [31:0]      work;       // Running remainder
41
 
42
    // Calculate the current digit
43
    wire [32:0]     sub = { work[30:0], result[31] } - denom;
44
 
45
    // Send the results to our master
46
    assign Quotient = !neg ? result : -result;
47
    assign Remainder = work;
48
    assign Stall = active;
49
 
50
    // The state machine
51
    always @(posedge clock) begin
52
        if (reset) begin
53
            active <= 0;
54
            neg <= 0;
55
            cycle <= 0;
56
            result <= 0;
57
            denom <= 0;
58
            work <= 0;
59
        end
60
        else begin
61
            if (OP_div) begin
62
                // Set up for a signed divide.  Remember the resulting sign,
63
                // and make the operands positive.
64
                cycle <= 5'd31;
65
                result <= (Dividend[31] == 0) ? Dividend : -Dividend;
66
                denom <= (Divisor[31] == 0) ? Divisor : -Divisor;
67
                work <= 32'b0;
68
                neg <= Dividend[31] ^ Divisor[31];
69
                active <= 1;
70
            end
71
            else if (OP_divu) begin
72
                // Set up for an unsigned divide.
73
                cycle <= 5'd31;
74
                result <= Dividend;
75
                denom <= Divisor;
76
                work <= 32'b0;
77
                neg <= 0;
78
                active <= 1;
79
            end
80
            else if (active) begin
81
                // Run an iteration of the divide.
82
                if (sub[32] == 0) begin
83
                    work <= sub[31:0];
84
                    result <= {result[30:0], 1'b1};
85
                end
86
                else begin
87
                    work <= {work[30:0], result[31]};
88
                    result <= {result[30:0], 1'b0};
89
                end
90
 
91
                if (cycle == 0) begin
92
                    active <= 0;
93
                end
94
 
95
                cycle <= cycle - 5'd1;
96
            end
97
        end
98
    end
99
 
100
endmodule

powered by: WebSVN 2.1.0

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