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 4

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
        reg [N:0]                        reg_count;              //      This is obviously a lot bigger than it needs to be, as we only need 
44
                                                                                                //              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
 
48
        reg                                     reg_done;               //      Computation completed flag
49
        reg                                     reg_sign;               //      The quotient's sign bit
50
        reg                                     reg_overflow;   //      Overflow flag
51
 
52
        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
        assign o_quotient_out[N-2:0] = reg_working_quotient;     //      The division results
57
        assign o_quotient_out[N-1] = reg_sign;                                          //      The sign of the quotient
58
        assign o_complete = reg_done;
59
        assign o_overflow = reg_overflow;
60
 
61
        always @( posedge i_clk ) begin
62
                if( reg_done && i_start ) begin                                                                         //      This is our startup condition
63
                        //  Need to check for a divide by zero right here, I think....
64
                        reg_done <= 1'b0;                                                                                               //      We're not done                  
65
                        reg_count <= N+Q-2;                                                                                     //      Set the count
66
                        reg_working_quotient <= 0;                                                                       //      Clear out the quotient register
67
                        reg_working_dividend <= 0;                                                                       //      Clear out the dividend register 
68
                        reg_working_divisor <= 0;                                                                        //      Clear out the divisor register 
69
                        reg_overflow <= 1'b0;                                                                           //      Clear the overflow register
70
 
71
                        reg_working_dividend[N+Q-2:Q] <= i_dividend[N-2:0];                              //      Left-align the dividend in its working register
72
                        reg_working_divisor[2*N+Q-3:N+Q-1] <= i_divisor[N-2:0];          //      Left-align the divisor into its working register
73
 
74
                        reg_sign <= i_dividend[N-1] ^ i_divisor[N-1];           //      Set the sign bit
75
                        end
76
                else if(!reg_done) begin
77
                        reg_working_divisor <= reg_working_divisor >> 1;        //      Right shift the divisor (that is, divide it by two - aka reduce the divisor)
78
                        reg_count <= reg_count - 1;                                                             //      Decrement the count
79
 
80
                        //      If the dividend is greater than the divisor
81
                        if(reg_working_dividend >= reg_working_divisor) begin
82
                                reg_working_quotient[reg_count] <= 1'b1;                                                                                //      Set the quotient bit
83
                                reg_working_dividend <= reg_working_dividend - reg_working_divisor;     //              and subtract the divisor from the dividend
84
                                end
85
 
86
                        //stop condition
87
                        if(reg_count == 0) begin
88
                                reg_done <= 1'b1;                                                                               //      If we're done, it's time to tell the calling process
89
                                if (reg_working_quotient[2*N+Q-3:N]>0)
90
                                        reg_overflow <= 1'b1;
91
                                        end
92
                        else
93
                                reg_count <= reg_count - 1;
94
                        end
95
                end
96
endmodule

powered by: WebSVN 2.1.0

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