summaryrefslogtreecommitdiff
path: root/platform/wavelet3d/gfx_round_lane.sv
blob: d0b0b034c61124a4e6ba80485b82d9d3460006c4 (plain)
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