`timescale 1ns / 1ps ////////////////////////////////////////////////////////////////////////////////// // Company: // Engineer: // // Create Date: 13:33:36 01/02/2014 // Design Name: // Module Name: qmults // Project Name: // Target Devices: // Tool versions: // Description: // // Dependencies: // // Revision: // Revision 0.01 - File Created // Additional Comments: // ////////////////////////////////////////////////////////////////////////////////// module qmults#( //Parameterized values parameter Q = 0, parameter N = 32 ) ( input [N-1:0] i_multiplicand, input [N-1:0] i_multiplier, input i_start, input i_clk, input i_reset, output [N-1:0] o_result_out, output o_complete, output o_overflow ); 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 [N-1:0] reg_multiplicand_temp; // a working copy of the umultiplicand 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 // logarithm (base 2), and I don't know how to do that in a // way that will work for every possibility reg reg_done; // Computation completed flag reg reg_sign; // The result's sign bit reg reg_overflow; // Overflow flag 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_complete = reg_done; // "Done" flag assign o_overflow = reg_overflow; // Overflow flag always @( posedge i_clk or negedge i_reset) begin if (!i_reset) begin reg_done <= 1'b1; // Initial state is to not be doing anything reg_overflow <= 1'b0; // And there should be no woverflow present reg_sign <= 1'b0; // And the sign should be positive end else if( reg_done && i_start ) begin // This is our startup condition reg_done <= 1'b0; // We're not done reg_count <= 0; // Reset the count reg_working_result <= 0; // Clear out the result register reg_multiplier_temp <= 0; // Clear out the multiplier register reg_multiplicand_temp <= 0; // Clear out the multiplicand 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_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 end else if (!reg_done) begin 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_multiplier_temp <= reg_multiplier_temp << 1; // Do a left-shift on the multiplier reg_count <= reg_count + 1; // Increment the count //stop condition if(reg_count == N) begin 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 reg_overflow <= 1'b1; // else // reg_count <= reg_count + 1; // Increment the count end end end endmodule