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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
|
------------------------------------------------------------------------------
-- ____ _____________ __ --
-- / __ \/ ____/ ___/\ \/ / _ _ _ --
-- / / / / __/ \__ \ \ / / \ / \ / \ --
-- / /_/ / /___ ___/ / / / = ( M | S | K )= --
-- /_____/_____//____/ /_/ \_/ \_/ \_/ --
-- --
------------------------------------------------------------------------------
--! @copyright Copyright 2022 DESY
--! SPDX-License-Identifier: CERN-OHL-W-2.0
------------------------------------------------------------------------------
--! @date 2022-04-01
--! @author Michael Buechler <michael.buechler@desy.de>
--! @author Lukasz Butkowski <lukasz.butkowski@desy.de>
------------------------------------------------------------------------------
--! @brief
--! Math utilities
------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.math_real.all;
--! Package of mathematical utilities and support functions
package math_utils is
--! Saturation status after an operation.
type t_saturation is (ST_SAT_OK, ST_SAT_OVERFLOWN, ST_SAT_UNDERFLOWN);
--! The encoding for _t_staturation_ is
--!
--! * ST_SAT_OK = "00" (No saturation)
--! * ST_SAT_OVERFLOWN = "10" (Operation has overflown)
--! * ST_SAT_UNDERFLOWN = "01" (Operation has underflown)
attribute enum_encoding : string;
attribute enum_encoding of t_saturation : type is "00 10 01";
--! f_bit_length:
--! Comparable to Python's int.bit_length(),
--! but when arg is negative, calculate for two's complement.
--! Attention: returns 1 for argument -1.
--! When arg is zero, return 0.
function f_bit_length (arg: integer) return integer;
--! f_unsigned_length:
--! Calculates the minimum unsigned signal length to store **arg**,
--! When arg is zero, return 0.
function f_unsigned_length (arg: natural) return natural;
--! Calculates the minimum signed signal length to store *arg*,
--! When arg is zero, return 0.
function f_signed_length (arg: integer) return integer;
--! f_maximum:
--! Porting of 'maximum' from VHDL 08' not present in the
--! 93' standard.
function f_maximum (a, b: integer) return integer;
--! f_minimum:
--! Porting of 'minimum' from VHDL 08' not present in the
--! 93' standard
function f_minimum (a, b: integer) return integer;
--! f_max_val_for_length:
--! Returns the maximum value representable by a numeric type of length
--! _length_ and sign _sign_.
function f_max_val_for_length (length: natural; sign : boolean) return integer;
function f_max_val_of (arg: unsigned) return unsigned;
--! f_max_val_of:
--! Returns the maximum value representable by a numeric type.
--! Signed and unsigned version.
function f_max_val_of (arg: signed) return signed;
--! f_max_val_for_length:
--! Returns the maximum value representable by a numeric type of length
--! _length_ and sign _sign_.
function f_min_val_for_length (length: natural; sign : boolean) return integer;
function f_min_val_of (arg: unsigned) return unsigned;
--! f_min_val_of:
--! Returns the minimum value representable by a numeric type.
--! Signed and unsigned version.
function f_min_val_of (arg: signed) return signed;
function f_is_max (arg: unsigned) return boolean;
--! f_is_max:
--! Checks whether a signal is at its maximum value.
--! Signed and unsigned version.
function f_is_max (arg: signed) return boolean;
function f_is_min (arg: unsigned) return boolean;
--! f_is_min:
--! Checks whether a signal is at its minimum value.
--! Signed and unsigned version.
function f_is_min (arg: signed) return boolean;
end package math_utils;
--******************************************************************************
--******************************************************************************
package body math_utils is
function f_bit_length (arg: integer) return integer is
begin
if (arg = 0) then
return 0;
elsif (arg > 0) then
return integer(ceil(log2(real(arg + 1))));
else
return integer(ceil(log2(-real(arg)))) + 1;
end if;
end function;
function f_unsigned_length (arg: natural) return natural is
begin
return natural(f_bit_length(integer(arg)));
end function;
function f_signed_length (arg: integer) return integer is
begin
if (arg >= 0) then
return f_bit_length(arg) + 1;
else
return f_bit_length(arg);
end if;
end function;
function f_maximum (a, b: integer) return integer is
begin
if (a > b) then
return a;
else
return b;
end if;
end function;
function f_minimum (a, b: integer) return integer is
begin
if (a < b) then
return a;
else
return b;
end if;
end function;
function f_max_val_for_length (length: natural; sign : boolean) return integer is
constant C_SMAX : integer := (2 ** (length - 1)) - 1;
constant C_UMAX : integer := (2 ** length) - 1;
begin
if (sign) then
return C_SMAX;
else
return C_UMAX;
end if;
end function;
function f_max_val_of (arg: unsigned) return unsigned is
begin
return to_unsigned(f_max_val_for_length(arg'length, false), arg'length);
end function;
function f_max_val_of (arg: signed) return signed is
begin
return to_signed(f_max_val_for_length(arg'length, true), arg'length);
end function;
function f_min_val_for_length (length: natural; sign : boolean) return integer is
constant C_SMIN : integer := - (2 ** (length - 1));
constant C_UMIN : integer := 0;
begin
if (sign) then
return C_SMIN;
else
return C_UMIN;
end if;
end function;
function f_min_val_of (arg: unsigned) return unsigned is
begin
return to_unsigned(f_min_val_for_length(arg'length, false), arg'length);
end function;
function f_min_val_of (arg: signed) return signed is
begin
return to_signed(f_min_val_for_length(arg'length, true), arg'length);
end function;
function f_is_max (arg: unsigned) return boolean is
begin
return arg = f_max_val_of(arg);
end;
function f_is_max (arg: signed) return boolean is
begin
return arg = f_max_val_of(arg);
end;
function f_is_min (arg: unsigned) return boolean is
begin
return arg = f_min_val_of(arg);
end;
function f_is_min (arg: signed) return boolean is
begin
return arg = f_min_val_of(arg);
end;
end package body math_utils;
|