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 9

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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