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

Subversion Repositories verilog_fixed_point_math_library

[/] [verilog_fixed_point_math_library/] [trunk/] [qdiv.v] - Blame information for rev 8

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

Line No. Rev Author Line
1 4 tomburkeii
`timescale 1ns / 1ps
2
//////////////////////////////////////////////////////////////////////////////////
3
// Company: 
4
// Engineer: 
5
// 
6
// Create Date:    19:39:14 08/24/2011 
7
// Design Name: 
8
// Module Name:    divider 
9
// Project Name: 
10
// Target Devices: 
11
// Tool versions: 
12
// Description: 
13
//
14
// Dependencies: 
15
//
16
// Revision: 
17
// Revision 0.01 - File Created
18
// Additional Comments: Based on my description on youtube:
19
//                      http://youtu.be/TEnaPMYiuR8
20
//
21
//////////////////////////////////////////////////////////////////////////////////
22
 
23
module qdiv #(
24
        //Parameterized values
25
        parameter Q = 15,
26
        parameter N = 32
27
        )
28
        (
29
        input   [N-1:0] i_dividend,
30
        input   [N-1:0] i_divisor,
31
        input   i_start,
32
        input   i_clk,
33
        output  [N-1:0] o_quotient_out,
34
        output  o_complete,
35
        output  o_overflow
36
        );
37
 
38
        reg [2*N+Q-3:0]  reg_working_quotient;   //      Our working copy of the quotient
39
        reg [N-1:0]              reg_quotient;                           //      Final quotient
40
        reg [N-2+Q:0]            reg_working_dividend;   //      Working copy of the dividend
41
        reg [2*N+Q-3:0]  reg_working_divisor;            // Working copy of the divisor
42
 
43 7 tomburkeii
        reg [N-1:0]                      reg_count;              //      This is obviously a lot bigger than it needs to be, as we only need 
44 8 tomburkeii
                                                                                                        //              count to N-1+Q but, computing that number of bits requires a 
45
                                                                                                        //              logarithm (base 2), and I don't know how to do that in a 
46
                                                                                                        //              way that will work for everyone
47 4 tomburkeii
 
48 8 tomburkeii
        reg                                     reg_done;                       //      Computation completed flag
49
        reg                                     reg_sign;                       //      The quotient's sign bit
50
        reg                                     reg_overflow;           //      Overflow flag
51 4 tomburkeii
 
52 8 tomburkeii
        initial reg_done = 1'b1;                                //      Initial state is to not be doing anything
53
        initial reg_overflow = 1'b0;                    //              And there should be no woverflow present
54
        initial reg_sign = 1'b0;                                //              And the sign should be positive
55
 
56
        initial reg_working_quotient = 0;
57
        initial reg_quotient = 0;
58
        initial reg_working_dividend = 0;
59
        initial reg_working_divisor = 0;
60
        initial reg_count = 0;
61
 
62 4 tomburkeii
 
63 8 tomburkeii
        assign o_quotient_out[N-2:0] = reg_quotient[N-2:0];       //      The division results
64 4 tomburkeii
        assign o_quotient_out[N-1] = reg_sign;                                          //      The sign of the quotient
65
        assign o_complete = reg_done;
66
        assign o_overflow = reg_overflow;
67
 
68
        always @( posedge i_clk ) begin
69
                if( reg_done && i_start ) begin                                                                         //      This is our startup condition
70
                        //  Need to check for a divide by zero right here, I think....
71
                        reg_done <= 1'b0;                                                                                               //      We're not done                  
72 8 tomburkeii
                        reg_count <= N+Q-1;                                                                                     //      Set the count
73 4 tomburkeii
                        reg_working_quotient <= 0;                                                                       //      Clear out the quotient register
74
                        reg_working_dividend <= 0;                                                                       //      Clear out the dividend register 
75
                        reg_working_divisor <= 0;                                                                        //      Clear out the divisor register 
76
                        reg_overflow <= 1'b0;                                                                           //      Clear the overflow register
77
 
78
                        reg_working_dividend[N+Q-2:Q] <= i_dividend[N-2:0];                              //      Left-align the dividend in its working register
79
                        reg_working_divisor[2*N+Q-3:N+Q-1] <= i_divisor[N-2:0];          //      Left-align the divisor into its working register
80
 
81
                        reg_sign <= i_dividend[N-1] ^ i_divisor[N-1];           //      Set the sign bit
82
                        end
83
                else if(!reg_done) begin
84
                        reg_working_divisor <= reg_working_divisor >> 1;        //      Right shift the divisor (that is, divide it by two - aka reduce the divisor)
85
                        reg_count <= reg_count - 1;                                                             //      Decrement the count
86
 
87
                        //      If the dividend is greater than the divisor
88
                        if(reg_working_dividend >= reg_working_divisor) begin
89
                                reg_working_quotient[reg_count] <= 1'b1;                                                                                //      Set the quotient bit
90
                                reg_working_dividend <= reg_working_dividend - reg_working_divisor;     //              and subtract the divisor from the dividend
91
                                end
92
 
93
                        //stop condition
94
                        if(reg_count == 0) begin
95
                                reg_done <= 1'b1;                                                                               //      If we're done, it's time to tell the calling process
96 8 tomburkeii
                                reg_quotient <= reg_working_quotient;                   //      Move in our working copy to the outside world
97 4 tomburkeii
                                if (reg_working_quotient[2*N+Q-3:N]>0)
98
                                        reg_overflow <= 1'b1;
99
                                        end
100
                        else
101
                                reg_count <= reg_count - 1;
102
                        end
103
                end
104
endmodule

powered by: WebSVN 2.1.0

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