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
|
module gfx_round_lane
(
input logic clk,
input gfx::float_round in,
output gfx::float out
);
import gfx::*;
logic exp_step, overflow, sign_0, sign_1, slow_0, slow_1,
slow_out, zero_0, zero_1;
float_exp exp_0, exp_1;
float_mant mant_0, mant_1;
assign slow_out = slow_1 || overflow || &exp_1;
always_ff @(posedge clk) begin
// Stage 0: redondeo
exp_0 <= in.normal.exp;
sign_0 <= in.normal.sign;
slow_0 <= in.slow;
zero_0 <= in.zero;
exp_step <= 0;
// Este es el modo más común: round to nearest, ties to even
if (in.guard & (in.round | in.sticky | in.normal.mant[0]))
{exp_step, mant_0} <= {1'b0, in.normal.mant} + 1;
else
mant_0 <= in.normal.mant;
sign_1 <= sign_0;
slow_1 <= slow_0;
zero_1 <= zero_0;
mant_1 <= mant_0;
overflow <= 0;
if (exp_step)
{overflow, exp_1} <= {1'b0, exp_0} + 1;
else
exp_1 <= exp_0;
// Stage 1: ceros y slow path
out.sign <= sign_1;
if (slow_out) begin
out.exp <= FLOAT_EXP_MAX;
out.mant <= 1;
end else if (zero_1) begin
out.exp <= 0;
out.mant <= 0;
end else begin
out.exp <= exp_1;
out.mant <= mant_1;
end
end
endmodule
|