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/] [qmults.v] - Diff between revs 4 and 7

Only display areas with differences | Details | Blame | View Log

Rev 4 Rev 7
`timescale 1ns / 1ps
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Company: 
// Engineer: 
// Engineer: 
// 
// 
// Create Date:    13:33:36 01/02/2014 
// Create Date:    13:33:36 01/02/2014 
// Design Name: 
// Design Name: 
// Module Name:    qmults 
// Module Name:    qmults 
// 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: 
// Additional Comments: 
//
//
//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////
module qmults#(
module qmults#(
        //Parameterized values
        //Parameterized values
        parameter Q = 15,
        parameter Q = 15,
        parameter N = 32
        parameter N = 32
        )
        )
        (
        (
        input   [N-1:0]  i_multiplicand,
        input   [N-1:0]  i_multiplicand,
        input   [N-1:0]  i_multiplier,
        input   [N-1:0]  i_multiplier,
        input   i_start,
        input   i_start,
        input   i_clk,
        input   i_clk,
        output  [N-1:0] o_result_out,
        output  [N-1:0] o_result_out,
        output  o_complete,
        output  o_complete,
        output  o_overflow
        output  o_overflow
        );
        );
 
 
        reg [2*N-2:0]    reg_working_result;             //      a place to accumulate our result
        reg [2*N-2:0]    reg_working_result;             //      a place to accumulate our result
        reg [2*N-2:0]    reg_multiplier_temp;            //      a working copy of the multiplier
        reg [2*N-2:0]    reg_multiplier_temp;            //      a working copy of the multiplier
        reg [N-1:0]              reg_multiplicand_temp;  //      a working copy of the umultiplicand
        reg [N-1:0]              reg_multiplicand_temp;  //      a working copy of the umultiplicand
 
 
        reg [N: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, but computing that number of bits requires a 
                                                                                                //              count to N, 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 every possibility
                                                                                                //              way that will work for every possibility
 
 
        reg                                     reg_done;               //      Computation completed flag
        reg                                     reg_done;               //      Computation completed flag
        reg                                     reg_sign;               //      The result's sign bit
        reg                                     reg_sign;               //      The result'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_result_out[N-2:0] = reg_working_result[N-2+Q:Q];        //      The multiplication results
        assign o_result_out[N-2:0] = reg_working_result[N-2+Q:Q];        //      The multiplication results
        assign o_result_out[N-1] = reg_sign;                                                            //      The sign of the result
        assign o_result_out[N-1] = reg_sign;                                                            //      The sign of the result
        assign o_complete = reg_done;                                                                                   //      "Done" flag
        assign o_complete = reg_done;                                                                                   //      "Done" flag
        assign o_overflow = reg_overflow;                                                                       //      Overflow flag
        assign o_overflow = reg_overflow;                                                                       //      Overflow flag
 
 
        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
                        reg_done <= 1'b0;                                                                                                               //      We're not done                  
                        reg_done <= 1'b0;                                                                                                               //      We're not done                  
                        reg_count <= 0;                                                                                                          //      Reset the count
                        reg_count <= 0;                                                                                                          //      Reset the count
                        reg_working_result <= 0;                                                                                 //      Clear out the result register
                        reg_working_result <= 0;                                                                                 //      Clear out the result register
                        reg_multiplier_temp <= 0;                                                                                        //      Clear out the multiplier register 
                        reg_multiplier_temp <= 0;                                                                                        //      Clear out the multiplier register 
                        reg_multiplicand_temp <= 0;                                                                              //      Clear out the multiplicand register 
                        reg_multiplicand_temp <= 0;                                                                              //      Clear out the multiplicand register 
                        reg_overflow <= 1'b0;                                                                                           //      Clear the overflow register
                        reg_overflow <= 1'b0;                                                                                           //      Clear the overflow register
 
 
                        reg_multiplicand_temp <= i_multiplicand[N-2:0];                          //      Load the multiplicand in its working register and lose the sign bit
                        reg_multiplicand_temp <= i_multiplicand[N-2:0];                          //      Load the multiplicand in its working register and lose the sign bit
                        reg_multiplier_temp <= i_multiplier[N-2:0];                                      //      Load the multiplier into its working register and lose the sign bit
                        reg_multiplier_temp <= i_multiplier[N-2:0];                                      //      Load the multiplier into its working register and lose the sign bit
 
 
                        reg_sign <= i_multiplicand[N-1] ^ i_multiplier[N-1];            //      Set the sign bit
                        reg_sign <= i_multiplicand[N-1] ^ i_multiplier[N-1];            //      Set the sign bit
                        end
                        end
 
 
                else if (!reg_done) begin
                else if (!reg_done) begin
                        if (reg_multiplicand_temp[reg_count] == 1'b1)                                                           //      if the appropriate multiplicand bit is 1
                        if (reg_multiplicand_temp[reg_count] == 1'b1)                                                           //      if the appropriate multiplicand bit is 1
                                reg_working_result <= reg_working_result + reg_multiplier_temp; //              then add the temp multiplier
                                reg_working_result <= reg_working_result + reg_multiplier_temp; //              then add the temp multiplier
 
 
                        reg_multiplier_temp <= reg_multiplier_temp << 1;                                                //      Do a left-shift on the multiplier
                        reg_multiplier_temp <= reg_multiplier_temp << 1;                                                //      Do a left-shift on the multiplier
                        reg_count <= reg_count + 1;                                                                                                     //      Increment the count
                        reg_count <= reg_count + 1;                                                                                                     //      Increment the count
 
 
                        //stop condition
                        //stop condition
                        if(reg_count == N) begin
                        if(reg_count == N) 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
                                if (reg_working_result[2*N-2:N-1+Q] > 0)                 // Check for an overflow
                                if (reg_working_result[2*N-2:N-1+Q] > 0)                 // Check for an overflow
                                        reg_overflow <= 1'b1;
                                        reg_overflow <= 1'b1;
//                      else
//                      else
//                              reg_count <= reg_count + 1;                                                                                                     //      Increment the count
//                              reg_count <= reg_count + 1;                                                                                                     //      Increment the count
                                end
                                end
                        end
                        end
                end
                end
endmodule
endmodule
 
 

powered by: WebSVN 2.1.0

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