1 |
4 |
tomburkeii |
`timescale 1ns / 1ps
|
2 |
|
|
//////////////////////////////////////////////////////////////////////////////////
|
3 |
|
|
// Company:
|
4 |
|
|
// Engineer:
|
5 |
|
|
//
|
6 |
|
|
// Create Date: 11:21:14 08/24/2011
|
7 |
|
|
// Design Name:
|
8 |
|
|
// Module Name: q15_mult
|
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:
|
19 |
|
|
//
|
20 |
|
|
//////////////////////////////////////////////////////////////////////////////////
|
21 |
|
|
module qmult #(
|
22 |
|
|
//Parameterized values
|
23 |
|
|
parameter Q = 15,
|
24 |
|
|
parameter N = 32
|
25 |
|
|
)
|
26 |
|
|
(
|
27 |
|
|
input [N-1:0] i_multiplicand,
|
28 |
|
|
input [N-1:0] i_multiplier,
|
29 |
|
|
output [N-1:0] o_result,
|
30 |
|
|
output reg ovr
|
31 |
|
|
);
|
32 |
|
|
|
33 |
|
|
// The underlying assumption, here, is that both fixed-point values are of the same length (N,Q)
|
34 |
|
|
// Because of this, the results will be of length N+N = 2N bits....
|
35 |
|
|
// This also simplifies the hand-back of results, as the binimal point
|
36 |
|
|
// will always be in the same location...
|
37 |
|
|
|
38 |
|
|
reg [2*N-1:0] r_result; // Multiplication by 2 values of N bits requires a
|
39 |
|
|
// register that is N+N = 2N deep...
|
40 |
|
|
reg [N-1:0] r_RetVal;
|
41 |
|
|
|
42 |
|
|
//--------------------------------------------------------------------------------
|
43 |
|
|
assign o_result = r_RetVal; // Only handing back the same number of bits as we received...
|
44 |
|
|
// with fixed point in same location...
|
45 |
|
|
|
46 |
|
|
//---------------------------------------------------------------------------------
|
47 |
|
|
always @(i_multiplicand, i_multiplier) begin // Do the multiply any time the inputs change
|
48 |
|
|
r_result <= i_multiplicand[N-2:0] * i_multiplier[N-2:0]; // Removing the sign bits from the multiply - that
|
49 |
|
|
// would introduce *big* errors
|
50 |
|
|
ovr <= 1'b0; // reset overflow flag to zero
|
51 |
|
|
end
|
52 |
|
|
|
53 |
|
|
// This always block will throw a warning, as it uses a & b, but only acts on changes in result...
|
54 |
|
|
always @(r_result) begin // Any time the result changes, we need to recompute the sign bit,
|
55 |
|
|
r_RetVal[N-1] <= i_multiplicand[N-1] ^ i_multiplier[N-1]; // which is the XOR of the input sign bits... (you do the truth table...)
|
56 |
|
|
r_RetVal[N-2:0] <= r_result[N-2+Q:Q]; // And we also need to push the proper N bits of result up to
|
57 |
|
|
// the calling entity...
|
58 |
|
|
if (r_result[2*N-2:N-1+Q] > 0) // And finally, we need to check for an overflow
|
59 |
|
|
ovr <= 1'b1;
|
60 |
|
|
end
|
61 |
|
|
|
62 |
|
|
endmodule
|