summaryrefslogtreecommitdiff
path: root/platform/wavelet3d/gfx_pkg.sv
blob: cfab6a587349557266ef3fcdb81734743a19af07 (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
63
64
65
66
67
68
69
package gfx;

	typedef logic[31:0] word;
	typedef logic[63:0] dword;
	typedef logic[7:0]  float_exp;

	typedef logic[$bits(word) - $bits(float_exp) - 2:0] float_mant;
	typedef logic[$bits(float_mant):0] float_mant_full; // Incluye '1.' explícito

	localparam float_exp FLOAT_EXP_BIAS = (1 << ($bits(float_exp) - 1)) - 1;
	localparam float_exp FLOAT_EXP_MAX  = {($bits(float_exp)){1'b1}};

	function float_mant_full full_mant(float_mant in);
		full_mant = {1'b1, in};
	endfunction

	function float_mant implicit_mant(float_mant_full in);
		assert (in[$bits(in) - 1]);
		implicit_mant = in[$bits(in) - 2:0];
	endfunction

	typedef struct packed
	{
		logic      sign;
		float_exp  exp;
		float_mant mant;
	} float;

	/* Explicación de guard, round, sticky:
	 * https://drilian.com/2023/01/10/floating-point-numbers-and-rounding/
	 */
	typedef struct packed
	{
		float normal;
		logic slow,
		      zero,
		      guard,
		      round,
		      sticky;
	} float_round;

	typedef struct packed
	{
		logic exp_max,
		      exp_min,
		      mant_zero;
	} float_class;

	function float_class classify_float(float in);
		classify_float.exp_max = &in.exp;
		classify_float.exp_min = ~|in.exp;
		classify_float.mant_zero = ~|in.mant;
	endfunction

	function logic is_float_special(float_class in);
		is_float_special = in.exp_max | (in.exp_min & ~in.mant_zero);
	endfunction

	/* -> 4,4,4,4,4,4,4,4 -> 8,8,8,8 -> 16,16 -> 32
	 */
	localparam FADD_CLZ_STAGES = 4;

	typedef struct packed
	{
		logic fadd,
		      fmul;
	} arith_op;

endpackage