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] - Diff between revs 7 and 8

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 7 Rev 8
`timescale 1ns / 1ps
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Company: 
// Engineer: 
// Engineer: 
// 
// 
// Create Date:    19:39:14 08/24/2011 
// Create Date:    19:39:14 08/24/2011 
// Design Name: 
// Design Name: 
// Module Name:    divider 
// Module Name:    divider 
// Project Name: 
// Project Name: 
// Target Devices: 
// Target Devices: 
// Tool versions: 
// Tool versions: 
// Description: 
// Description: 
//
//
// Dependencies: 
// Dependencies: 
//
//
// Revision: 
// Revision: 
// Revision 0.01 - File Created
// Revision 0.01 - File Created
// Additional Comments: Based on my description on youtube:
// Additional Comments: Based on my description on youtube:
//                      http://youtu.be/TEnaPMYiuR8
//                      http://youtu.be/TEnaPMYiuR8
//
//
//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////
 
 
module qdiv #(
module qdiv #(
        //Parameterized values
        //Parameterized values
        parameter Q = 15,
        parameter Q = 15,
        parameter N = 32
        parameter N = 32
        )
        )
        (
        (
        input   [N-1:0] i_dividend,
        input   [N-1:0] i_dividend,
        input   [N-1:0] i_divisor,
        input   [N-1:0] i_divisor,
        input   i_start,
        input   i_start,
        input   i_clk,
        input   i_clk,
        output  [N-1:0] o_quotient_out,
        output  [N-1:0] o_quotient_out,
        output  o_complete,
        output  o_complete,
        output  o_overflow
        output  o_overflow
        );
        );
 
 
        reg [2*N+Q-3:0]  reg_working_quotient;   //      Our working copy of the quotient
        reg [2*N+Q-3:0]  reg_working_quotient;   //      Our working copy of the quotient
        reg [N-1:0]              reg_quotient;                           //      Final quotient
        reg [N-1:0]              reg_quotient;                           //      Final quotient
        reg [N-2+Q:0]            reg_working_dividend;   //      Working copy of the dividend
        reg [N-2+Q:0]            reg_working_dividend;   //      Working copy of the dividend
        reg [2*N+Q-3:0]  reg_working_divisor;            // Working copy of the divisor
        reg [2*N+Q-3:0]  reg_working_divisor;            // Working copy of the divisor
 
 
        reg [N-1:0]                      reg_count;              //      This is obviously a lot bigger than it needs to be, as we only need 
        reg [N-1:0]                      reg_count;              //      This is obviously a lot bigger than it needs to be, as we only need 
                                                                                                //              count to N-1+Q but, computing that number of bits requires a 
                                                                                                        //              count to N-1+Q but, computing that number of bits requires a 
                                                                                                //              logarithm (base 2), and I don't know how to do that in a 
                                                                                                        //              logarithm (base 2), and I don't know how to do that in a 
                                                                                                //              way that will work for everyone
                                                                                                        //              way that will work for everyone
 
 
        reg                                     reg_done;               //      Computation completed flag
        reg                                     reg_done;                       //      Computation completed flag
        reg                                     reg_sign;               //      The quotient's sign bit
        reg                                     reg_sign;                       //      The quotient's sign bit
        reg                                     reg_overflow;   //      Overflow flag
        reg                                     reg_overflow;           //      Overflow flag
 
 
        initial reg_done = 1'b1;                        //      Initial state is to not be doing anything
        initial reg_done = 1'b1;                                //      Initial state is to not be doing anything
        initial reg_overflow = 1'b0;            //              And there should be no woverflow present
        initial reg_overflow = 1'b0;                    //              And there should be no woverflow present
        initial reg_sign = 1'b0;                        //              And the sign should be positive
        initial reg_sign = 1'b0;                                //              And the sign should be positive
 
 
        assign o_quotient_out[N-2:0] = reg_working_quotient;     //      The division results
        initial reg_working_quotient = 0;
 
        initial reg_quotient = 0;
 
        initial reg_working_dividend = 0;
 
        initial reg_working_divisor = 0;
 
        initial reg_count = 0;
 
 
 
 
 
        assign o_quotient_out[N-2:0] = reg_quotient[N-2:0];       //      The division results
        assign o_quotient_out[N-1] = reg_sign;                                          //      The sign of the quotient
        assign o_quotient_out[N-1] = reg_sign;                                          //      The sign of the quotient
        assign o_complete = reg_done;
        assign o_complete = reg_done;
        assign o_overflow = reg_overflow;
        assign o_overflow = reg_overflow;
 
 
        always @( posedge i_clk ) begin
        always @( posedge i_clk ) begin
                if( reg_done && i_start ) begin                                                                         //      This is our startup condition
                if( reg_done && i_start ) begin                                                                         //      This is our startup condition
                        //  Need to check for a divide by zero right here, I think....
                        //  Need to check for a divide by zero right here, I think....
                        reg_done <= 1'b0;                                                                                               //      We're not done                  
                        reg_done <= 1'b0;                                                                                               //      We're not done                  
                        reg_count <= N+Q-2;                                                                                     //      Set the count
                        reg_count <= N+Q-1;                                                                                     //      Set the count
                        reg_working_quotient <= 0;                                                                       //      Clear out the quotient register
                        reg_working_quotient <= 0;                                                                       //      Clear out the quotient register
                        reg_working_dividend <= 0;                                                                       //      Clear out the dividend register 
                        reg_working_dividend <= 0;                                                                       //      Clear out the dividend register 
                        reg_working_divisor <= 0;                                                                        //      Clear out the divisor register 
                        reg_working_divisor <= 0;                                                                        //      Clear out the divisor register 
                        reg_overflow <= 1'b0;                                                                           //      Clear the overflow register
                        reg_overflow <= 1'b0;                                                                           //      Clear the overflow register
 
 
                        reg_working_dividend[N+Q-2:Q] <= i_dividend[N-2:0];                              //      Left-align the dividend in its working register
                        reg_working_dividend[N+Q-2:Q] <= i_dividend[N-2:0];                              //      Left-align the dividend in its working register
                        reg_working_divisor[2*N+Q-3:N+Q-1] <= i_divisor[N-2:0];          //      Left-align the divisor into its working register
                        reg_working_divisor[2*N+Q-3:N+Q-1] <= i_divisor[N-2:0];          //      Left-align the divisor into its working register
 
 
                        reg_sign <= i_dividend[N-1] ^ i_divisor[N-1];           //      Set the sign bit
                        reg_sign <= i_dividend[N-1] ^ i_divisor[N-1];           //      Set the sign bit
                        end
                        end
                else if(!reg_done) begin
                else if(!reg_done) begin
                        reg_working_divisor <= reg_working_divisor >> 1;        //      Right shift the divisor (that is, divide it by two - aka reduce the divisor)
                        reg_working_divisor <= reg_working_divisor >> 1;        //      Right shift the divisor (that is, divide it by two - aka reduce the divisor)
                        reg_count <= reg_count - 1;                                                             //      Decrement the count
                        reg_count <= reg_count - 1;                                                             //      Decrement the count
 
 
                        //      If the dividend is greater than the divisor
                        //      If the dividend is greater than the divisor
                        if(reg_working_dividend >= reg_working_divisor) begin
                        if(reg_working_dividend >= reg_working_divisor) begin
                                reg_working_quotient[reg_count] <= 1'b1;                                                                                //      Set the quotient bit
                                reg_working_quotient[reg_count] <= 1'b1;                                                                                //      Set the quotient bit
                                reg_working_dividend <= reg_working_dividend - reg_working_divisor;     //              and subtract the divisor from the dividend
                                reg_working_dividend <= reg_working_dividend - reg_working_divisor;     //              and subtract the divisor from the dividend
                                end
                                end
 
 
                        //stop condition
                        //stop condition
                        if(reg_count == 0) begin
                        if(reg_count == 0) begin
                                reg_done <= 1'b1;                                                                               //      If we're done, it's time to tell the calling process
                                reg_done <= 1'b1;                                                                               //      If we're done, it's time to tell the calling process
 
                                reg_quotient <= reg_working_quotient;                   //      Move in our working copy to the outside world
                                if (reg_working_quotient[2*N+Q-3:N]>0)
                                if (reg_working_quotient[2*N+Q-3:N]>0)
                                        reg_overflow <= 1'b1;
                                        reg_overflow <= 1'b1;
                                        end
                                        end
                        else
                        else
                                reg_count <= reg_count - 1;
                                reg_count <= reg_count - 1;
                        end
                        end
                end
                end
 
 

powered by: WebSVN 2.1.0

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