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