1 |
2 |
rudi |
/////////////////////////////////////////////////////////////////////
|
2 |
|
|
//// ////
|
3 |
|
|
//// Pre Normalize ////
|
4 |
|
|
//// Floating Point Pre Normalization Unit for FMUL ////
|
5 |
|
|
//// ////
|
6 |
|
|
//// Author: Rudolf Usselmann ////
|
7 |
|
|
//// rudi@asics.ws ////
|
8 |
|
|
//// ////
|
9 |
|
|
/////////////////////////////////////////////////////////////////////
|
10 |
|
|
//// ////
|
11 |
|
|
//// Copyright (C) 2000 Rudolf Usselmann ////
|
12 |
|
|
//// rudi@asics.ws ////
|
13 |
|
|
//// ////
|
14 |
|
|
//// This source file may be used and distributed without ////
|
15 |
|
|
//// restriction provided that this copyright statement is not ////
|
16 |
|
|
//// removed from the file and that any derivative work contains ////
|
17 |
|
|
//// the original copyright notice and the associated disclaimer.////
|
18 |
|
|
//// ////
|
19 |
|
|
//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
|
20 |
|
|
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
|
21 |
|
|
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
|
22 |
|
|
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
|
23 |
|
|
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
|
24 |
|
|
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
|
25 |
|
|
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
|
26 |
|
|
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
|
27 |
|
|
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
|
28 |
|
|
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
|
29 |
|
|
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
|
30 |
|
|
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
|
31 |
|
|
//// POSSIBILITY OF SUCH DAMAGE. ////
|
32 |
|
|
//// ////
|
33 |
|
|
/////////////////////////////////////////////////////////////////////
|
34 |
|
|
|
35 |
|
|
`timescale 1ns / 100ps
|
36 |
|
|
|
37 |
|
|
module pre_norm_fmul(clk, fpu_op, opa, opb, fracta, fractb, exp_out, sign,
|
38 |
|
|
sign_exe, inf, exp_ovf, underflow);
|
39 |
|
|
input clk;
|
40 |
|
|
input [2:0] fpu_op;
|
41 |
|
|
input [31:0] opa, opb;
|
42 |
|
|
output [23:0] fracta, fractb;
|
43 |
|
|
output [7:0] exp_out;
|
44 |
|
|
output sign, sign_exe;
|
45 |
|
|
output inf;
|
46 |
|
|
output [1:0] exp_ovf;
|
47 |
|
|
output [2:0] underflow;
|
48 |
|
|
|
49 |
|
|
////////////////////////////////////////////////////////////////////////
|
50 |
|
|
//
|
51 |
|
|
// Local Wires and registers
|
52 |
|
|
//
|
53 |
|
|
|
54 |
|
|
reg [7:0] exp_out;
|
55 |
|
|
wire signa, signb;
|
56 |
|
|
reg sign, sign_d;
|
57 |
|
|
reg sign_exe;
|
58 |
|
|
reg inf;
|
59 |
|
|
wire [1:0] exp_ovf_d;
|
60 |
|
|
reg [1:0] exp_ovf;
|
61 |
|
|
wire [7:0] expa, expb;
|
62 |
|
|
wire [7:0] exp_tmp1, exp_tmp2;
|
63 |
|
|
wire co1, co2;
|
64 |
|
|
wire expa_dn, expb_dn;
|
65 |
|
|
wire [7:0] exp_out_a;
|
66 |
|
|
wire opa_00, opb_00, fracta_00, fractb_00;
|
67 |
|
|
wire [7:0] exp_tmp3, exp_tmp4, exp_tmp5;
|
68 |
|
|
wire [2:0] underflow_d;
|
69 |
|
|
reg [2:0] underflow;
|
70 |
|
|
wire op_div = (fpu_op == 3'b011);
|
71 |
|
|
wire [7:0] exp_out_mul, exp_out_div;
|
72 |
|
|
|
73 |
|
|
////////////////////////////////////////////////////////////////////////
|
74 |
|
|
//
|
75 |
|
|
// Aliases
|
76 |
|
|
//
|
77 |
|
|
|
78 |
|
|
assign signa = opa[31];
|
79 |
|
|
assign signb = opb[31];
|
80 |
|
|
assign expa = opa[30:23];
|
81 |
|
|
assign expb = opb[30:23];
|
82 |
|
|
|
83 |
|
|
////////////////////////////////////////////////////////////////////////
|
84 |
|
|
//
|
85 |
|
|
// Calculate Exponenet
|
86 |
|
|
//
|
87 |
|
|
|
88 |
|
|
assign expa_dn = !(|expa);
|
89 |
|
|
assign expb_dn = !(|expb);
|
90 |
|
|
assign opa_00 = !(|opa[30:0]);
|
91 |
|
|
assign opb_00 = !(|opb[30:0]);
|
92 |
|
|
assign fracta_00 = !(|opa[22:0]);
|
93 |
|
|
assign fractb_00 = !(|opb[22:0]);
|
94 |
|
|
|
95 |
|
|
assign fracta = {!expa_dn,opa[22:0]}; // Recover hidden bit
|
96 |
|
|
assign fractb = {!expb_dn,opb[22:0]}; // Recover hidden bit
|
97 |
|
|
|
98 |
|
|
assign {co1,exp_tmp1} = op_div ? (expa - expb) : (expa + expb);
|
99 |
|
|
assign {co2,exp_tmp2} = op_div ? ({co1,exp_tmp1} + 8'h7f) : ({co1,exp_tmp1} - 8'h7f);
|
100 |
|
|
|
101 |
|
|
assign exp_tmp3 = exp_tmp2 + 1;
|
102 |
|
|
assign exp_tmp4 = 8'h7f - exp_tmp1;
|
103 |
|
|
assign exp_tmp5 = op_div ? (exp_tmp4+1) : (exp_tmp4-1);
|
104 |
|
|
|
105 |
|
|
|
106 |
|
|
always@(posedge clk)
|
107 |
|
|
exp_out <= #1 op_div ? exp_out_div : exp_out_mul;
|
108 |
|
|
|
109 |
|
|
assign exp_out_div = (expa_dn | expb_dn) ? (co2 ? exp_tmp5 : exp_tmp3 ) : co2 ? exp_tmp4 : exp_tmp2;
|
110 |
|
|
assign exp_out_mul = exp_ovf_d[1] ? exp_out_a : (expa_dn | expb_dn) ? exp_tmp3 : exp_tmp2;
|
111 |
|
|
assign exp_out_a = (expa_dn | expb_dn) ? exp_tmp5 : exp_tmp4;
|
112 |
|
|
assign exp_ovf_d[0] = op_div ? (expa[7] & !expb[7]) : (co2 & expa[7] & expb[7]);
|
113 |
|
|
assign exp_ovf_d[1] = op_div ? co2 : ((!expa[7] & !expb[7] & exp_tmp2[7]) | co2);
|
114 |
|
|
|
115 |
|
|
always @(posedge clk)
|
116 |
|
|
exp_ovf <= #1 exp_ovf_d;
|
117 |
|
|
|
118 |
|
|
assign underflow_d[0] = (exp_tmp1 < 8'h7f) & !co1 & !(opa_00 | opb_00 | expa_dn | expb_dn);
|
119 |
|
|
assign underflow_d[1] = ((expa[7] | expb[7]) & !opa_00 & !opb_00) |
|
120 |
|
|
(expa_dn & !fracta_00) | (expb_dn & !fractb_00);
|
121 |
|
|
assign underflow_d[2] = !opa_00 & !opb_00 & (exp_tmp1 == 8'h7f);
|
122 |
|
|
|
123 |
|
|
always @(posedge clk)
|
124 |
|
|
underflow <= #1 underflow_d;
|
125 |
|
|
|
126 |
|
|
always @(posedge clk)
|
127 |
|
|
inf <= #1 op_div ? (expb_dn & !expa[7]) : ({co1,exp_tmp1} > 9'h17e) ;
|
128 |
|
|
|
129 |
|
|
|
130 |
|
|
////////////////////////////////////////////////////////////////////////
|
131 |
|
|
//
|
132 |
|
|
// Determine sign for the output
|
133 |
|
|
//
|
134 |
|
|
|
135 |
|
|
// sign: 0=Posetive Number; 1=Negative Number
|
136 |
|
|
always @(signa or signb)
|
137 |
|
|
case({signa, signb}) // synopsys full_case parallel_case
|
138 |
|
|
2'b0_0: sign_d = 0;
|
139 |
|
|
2'b0_1: sign_d = 1;
|
140 |
|
|
2'b1_0: sign_d = 1;
|
141 |
|
|
2'b1_1: sign_d = 0;
|
142 |
|
|
endcase
|
143 |
|
|
|
144 |
|
|
always @(posedge clk)
|
145 |
|
|
sign <= #1 sign_d;
|
146 |
|
|
|
147 |
|
|
always @(posedge clk)
|
148 |
|
|
sign_exe <= #1 signa & signb;
|
149 |
|
|
|
150 |
|
|
endmodule
|