OpenCores
URL https://opencores.org/ocsvn/fixed_extensions/fixed_extensions/trunk

Subversion Repositories fixed_extensions

[/] [fixed_extensions/] [trunk/] [sim/] [rtl_sim/] [src/] [fixed_pkg_c.vhd] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 kavi
-- --------------------------------------------------------------------
2
-- "fixed_pkg_c.vhdl" package contains functions for fixed point math.
3
-- Please see the documentation for the fixed point package.
4
-- This package should be compiled into "ieee_proposed" and used as follows:
5
-- use ieee.std_logic_1164.all;
6
-- use ieee.numeric_std.all;
7
-- use ieee_proposed.fixed_float_types.all;
8
-- use ieee_proposed.fixed_pkg.all;
9
--
10
--  This verison is designed to work with the VHDL-93 compilers 
11
--  synthesis tools.  Please note the "%%%" comments.  These are where we
12
--  diverge from the VHDL-200X LRM.
13
-- --------------------------------------------------------------------
14
-- Version    : $Revision: 1.21 $
15
-- Date       : $Date: 2007/09/26 18:08:53 $
16
-- --------------------------------------------------------------------
17
 
18
use STD.TEXTIO.all;
19
library IEEE;
20
use IEEE.STD_LOGIC_1164.all;
21
use IEEE.NUMERIC_STD.all;
22
use work.fixed_float_types.all;
23
 
24
package fixed_pkg is
25
-- generic (
26
  -- Rounding routine to use in fixed point, fixed_round or fixed_truncate
27
  constant fixed_round_style    : fixed_round_style_type    := fixed_round;
28
  -- Overflow routine to use in fixed point, fixed_saturate or fixed_wrap
29
  constant fixed_overflow_style : fixed_overflow_style_type := fixed_saturate;
30
  -- Extra bits used in divide routines
31
  constant fixed_guard_bits     : NATURAL                   := 3;
32
  -- If TRUE, then turn off warnings on "X" propagation
33
  constant no_warning           : BOOLEAN                   := (false
34
                                                                );
35
 
36
  -- Author David Bishop (dbishop@vhdl.org)
37
 
38
  -- base Unsigned fixed point type, downto direction assumed
39
  type UNRESOLVED_ufixed is array (INTEGER range <>) of STD_ULOGIC;
40
  -- base Signed fixed point type, downto direction assumed
41
  type UNRESOLVED_sfixed is array (INTEGER range <>) of STD_ULOGIC;
42
 
43
  subtype U_ufixed is UNRESOLVED_ufixed;
44
  subtype U_sfixed is UNRESOLVED_sfixed;
45
 
46
  subtype ufixed is UNRESOLVED_ufixed;
47
  subtype sfixed is UNRESOLVED_sfixed;
48
 
49
  --===========================================================================
50
  -- Arithmetic Operators:
51
  --===========================================================================
52
 
53
  -- Absolute value, 2's complement
54
  -- abs sfixed(a downto b) = sfixed(a+1 downto b)
55
  function "abs" (arg : UNRESOLVED_sfixed) return UNRESOLVED_sfixed;
56
 
57
  -- Negation, 2's complement
58
  -- - sfixed(a downto b) = sfixed(a+1 downto b)
59
  function "-" (arg : UNRESOLVED_sfixed)return UNRESOLVED_sfixed;
60
 
61
  -- Addition
62
  -- ufixed(a downto b) + ufixed(c downto d)
63
  --   = ufixed(maximum(a,c)+1 downto minimum(b,d))
64
  function "+" (l, r : UNRESOLVED_ufixed) return UNRESOLVED_ufixed;
65
 
66
  -- sfixed(a downto b) + sfixed(c downto d)
67
  --   = sfixed(maximum(a,c)+1 downto minimum(b,d))
68
  function "+" (l, r : UNRESOLVED_sfixed) return UNRESOLVED_sfixed;
69
 
70
  -- Subtraction
71
  -- ufixed(a downto b) - ufixed(c downto d)
72
  --   = ufixed(maximum(a,c)+1 downto minimum(b,d))
73
  function "-" (l, r : UNRESOLVED_ufixed) return UNRESOLVED_ufixed;
74
 
75
  -- sfixed(a downto b) - sfixed(c downto d)
76
  --   = sfixed(maximum(a,c)+1 downto minimum(b,d))
77
  function "-" (l, r : UNRESOLVED_sfixed) return UNRESOLVED_sfixed;
78
 
79
  -- Multiplication
80
  -- ufixed(a downto b) * ufixed(c downto d) = ufixed(a+c+1 downto b+d)
81
  function "*" (l, r : UNRESOLVED_ufixed) return UNRESOLVED_ufixed;
82
 
83
  -- sfixed(a downto b) * sfixed(c downto d) = sfixed(a+c+1 downto b+d)
84
  function "*" (l, r : UNRESOLVED_sfixed) return UNRESOLVED_sfixed;
85
 
86
  -- Division
87
  -- ufixed(a downto b) / ufixed(c downto d) = ufixed(a-d downto b-c-1)
88
--  function "/" (l, r : UNRESOLVED_ufixed) return UNRESOLVED_ufixed;
89
 
90
  -- sfixed(a downto b) / sfixed(c downto d) = sfixed(a-d+1 downto b-c)
91
--  function "/" (l, r : UNRESOLVED_sfixed) return UNRESOLVED_sfixed;
92
 
93
  -- Remainder
94
  -- ufixed (a downto b) rem ufixed (c downto d)
95
  --   = ufixed (minimum(a,c) downto minimum(b,d))
96
--  function "rem" (l, r : UNRESOLVED_ufixed) return UNRESOLVED_ufixed;
97
 
98
  -- sfixed (a downto b) rem sfixed (c downto d)
99
  --   = sfixed (minimum(a,c) downto minimum(b,d))
100
--  function "rem" (l, r : UNRESOLVED_sfixed) return UNRESOLVED_sfixed;
101
 
102
  -- Modulo
103
  -- ufixed (a downto b) mod ufixed (c downto d)
104
  --        = ufixed (minimum(a,c) downto minimum(b, d))
105
--  function "mod" (l, r : UNRESOLVED_ufixed) return UNRESOLVED_ufixed;
106
 
107
  -- sfixed (a downto b) mod sfixed (c downto d)
108
  --        = sfixed (c downto minimum(b, d))
109
--  function "mod" (l, r : UNRESOLVED_sfixed) return UNRESOLVED_sfixed;
110
 
111
  ----------------------------------------------------------------------------
112
  -- In these routines the "real" or "natural" (integer)
113
  -- are converted into a fixed point number and then the operation is
114
  -- performed.  It is assumed that the array will be large enough.
115
  -- If the input is "real" then the real number is converted into a fixed of
116
  -- the same size as the fixed point input.  If the number is an "integer"
117
  -- then it is converted into fixed with the range (l'high downto 0).
118
  ----------------------------------------------------------------------------
119
 
120
  -- ufixed(a downto b) + ufixed(a downto b) = ufixed(a+1 downto b)
121
  function "+" (l : UNRESOLVED_ufixed; r : REAL) return UNRESOLVED_ufixed;
122
 
123
  -- ufixed(c downto d) + ufixed(c downto d) = ufixed(c+1 downto d)
124
  function "+" (l : REAL; r : UNRESOLVED_ufixed) return UNRESOLVED_ufixed;
125
 
126
  -- ufixed(a downto b) + ufixed(a downto 0) = ufixed(a+1 downto minimum(0,b))
127
  function "+" (l : UNRESOLVED_ufixed; r : NATURAL) return UNRESOLVED_ufixed;
128
 
129
  -- ufixed(a downto 0) + ufixed(c downto d) = ufixed(c+1 downto minimum(0,d))
130
  function "+" (l : NATURAL; r : UNRESOLVED_ufixed) return UNRESOLVED_ufixed;
131
 
132
  -- ufixed(a downto b) - ufixed(a downto b) = ufixed(a+1 downto b)
133
  function "-" (l : UNRESOLVED_ufixed; r : REAL) return UNRESOLVED_ufixed;
134
 
135
  -- ufixed(c downto d) - ufixed(c downto d) = ufixed(c+1 downto d)
136
  function "-" (l : REAL; r : UNRESOLVED_ufixed) return UNRESOLVED_ufixed;
137
 
138
  -- ufixed(a downto b) - ufixed(a downto 0) = ufixed(a+1 downto minimum(0,b))
139
  function "-" (l : UNRESOLVED_ufixed; r : NATURAL) return UNRESOLVED_ufixed;
140
 
141
  -- ufixed(a downto 0) + ufixed(c downto d) = ufixed(c+1 downto minimum(0,d))
142
  function "-" (l : NATURAL; r : UNRESOLVED_ufixed) return UNRESOLVED_ufixed;
143
 
144
  -- ufixed(a downto b) * ufixed(a downto b) = ufixed(2a+1 downto 2b)
145
  function "*" (l : UNRESOLVED_ufixed; r : REAL) return UNRESOLVED_ufixed;
146
 
147
  -- ufixed(c downto d) * ufixed(c downto d) = ufixed(2c+1 downto 2d)
148
  function "*" (l : REAL; r : UNRESOLVED_ufixed) return UNRESOLVED_ufixed;
149
 
150
  -- ufixed (a downto b) * ufixed (a downto 0) = ufixed (2a+1 downto b)
151
  function "*" (l : UNRESOLVED_ufixed; r : NATURAL) return UNRESOLVED_ufixed;
152
 
153
  -- ufixed (a downto b) * ufixed (a downto 0) = ufixed (2a+1 downto b)
154
  function "*" (l : NATURAL; r : UNRESOLVED_ufixed) return UNRESOLVED_ufixed;
155
 
156
  -- ufixed(a downto b) / ufixed(a downto b) = ufixed(a-b downto b-a-1)
157
--  function "/" (l : UNRESOLVED_ufixed; r : REAL) return UNRESOLVED_ufixed;
158
 
159
--  -- ufixed(a downto b) / ufixed(a downto b) = ufixed(a-b downto b-a-1)
160
--  function "/" (l : REAL; r : UNRESOLVED_ufixed) return UNRESOLVED_ufixed;
161
 
162
  -- ufixed(a downto b) / ufixed(a downto 0) = ufixed(a downto b-a-1)
163
--  function "/" (l : UNRESOLVED_ufixed; r : NATURAL) return UNRESOLVED_ufixed;
164
 
165
  -- ufixed(c downto 0) / ufixed(c downto d) = ufixed(c-d downto -c-1)
166
--  function "/" (l : NATURAL; r : UNRESOLVED_ufixed) return UNRESOLVED_ufixed;
167
 
168
  -- ufixed (a downto b) rem ufixed (a downto b) = ufixed (a downto b)
169
--  function "rem" (l : UNRESOLVED_ufixed; r : REAL) return UNRESOLVED_ufixed;
170
 
171
--  -- ufixed (c downto d) rem ufixed (c downto d) = ufixed (c downto d)
172
--  function "rem" (l : REAL; r : UNRESOLVED_ufixed) return UNRESOLVED_ufixed;
173
 
174
--  -- ufixed (a downto b) rem ufixed (a downto 0) = ufixed (a downto minimum(b,0))
175
--  function "rem" (l : UNRESOLVED_ufixed; r : NATURAL) return UNRESOLVED_ufixed;
176
 
177
--  -- ufixed (c downto 0) rem ufixed (c downto d) = ufixed (c downto minimum(d,0))
178
--  function "rem" (l : NATURAL; r : UNRESOLVED_ufixed) return UNRESOLVED_ufixed;
179
 
180
--  -- ufixed (a downto b) mod ufixed (a downto b) = ufixed (a downto b)
181
--  function "mod" (l : UNRESOLVED_ufixed; r : REAL) return UNRESOLVED_ufixed;
182
 
183
--  -- ufixed (c downto d) mod ufixed (c downto d) = ufixed (c downto d)
184
--  function "mod" (l : REAL; r : UNRESOLVED_ufixed) return UNRESOLVED_ufixed;
185
 
186
--  -- ufixed (a downto b) mod ufixed (a downto 0) = ufixed (a downto minimum(b,0))
187
--  function "mod" (l : UNRESOLVED_ufixed; r : NATURAL) return UNRESOLVED_ufixed;
188
 
189
--  -- ufixed (c downto 0) mod ufixed (c downto d) = ufixed (c downto minimum(d,0))
190
--  function "mod" (l : NATURAL; r : UNRESOLVED_ufixed) return UNRESOLVED_ufixed;
191
 
192
  -- sfixed(a downto b) + sfixed(a downto b) = sfixed(a+1 downto b)
193
  function "+" (l : UNRESOLVED_sfixed; r : REAL) return UNRESOLVED_sfixed;
194
 
195
  -- sfixed(c downto d) + sfixed(c downto d) = sfixed(c+1 downto d)
196
  function "+" (l : REAL; r : UNRESOLVED_sfixed) return UNRESOLVED_sfixed;
197
 
198
  -- sfixed(a downto b) + sfixed(a downto 0) = sfixed(a+1 downto minimum(0,b))
199
  function "+" (l : UNRESOLVED_sfixed; r : INTEGER) return UNRESOLVED_sfixed;
200
 
201
  -- sfixed(c downto 0) + sfixed(c downto d) = sfixed(c+1 downto minimum(0,d))
202
  function "+" (l : INTEGER; r : UNRESOLVED_sfixed) return UNRESOLVED_sfixed;
203
 
204
  -- sfixed(a downto b) - sfixed(a downto b) = sfixed(a+1 downto b)
205
  function "-" (l : UNRESOLVED_sfixed; r : REAL) return UNRESOLVED_sfixed;
206
 
207
  -- sfixed(c downto d) - sfixed(c downto d) = sfixed(c+1 downto d)
208
  function "-" (l : REAL; r : UNRESOLVED_sfixed) return UNRESOLVED_sfixed;
209
 
210
  -- sfixed(a downto b) - sfixed(a downto 0) = sfixed(a+1 downto minimum(0,b))
211
  function "-" (l : UNRESOLVED_sfixed; r : INTEGER) return UNRESOLVED_sfixed;
212
 
213
  -- sfixed(c downto 0) - sfixed(c downto d) = sfixed(c+1 downto minimum(0,d))
214
  function "-" (l : INTEGER; r : UNRESOLVED_sfixed) return UNRESOLVED_sfixed;
215
 
216
  -- sfixed(a downto b) * sfixed(a downto b) = sfixed(2a+1 downto 2b)
217
  function "*" (l : UNRESOLVED_sfixed; r : REAL) return UNRESOLVED_sfixed;
218
 
219
  -- sfixed(c downto d) * sfixed(c downto d) = sfixed(2c+1 downto 2d)
220
  function "*" (l : REAL; r : UNRESOLVED_sfixed) return UNRESOLVED_sfixed;
221
 
222
  -- sfixed(a downto b) * sfixed(a downto 0) = sfixed(2a+1 downto b)
223
  function "*" (l : UNRESOLVED_sfixed; r : INTEGER) return UNRESOLVED_sfixed;
224
 
225
  -- sfixed(c downto 0) * sfixed(c downto d) = sfixed(2c+1 downto d)
226
  function "*" (l : INTEGER; r : UNRESOLVED_sfixed) return UNRESOLVED_sfixed;
227
 
228
  -- sfixed(a downto b) / sfixed(a downto b) = sfixed(a-b+1 downto b-a)
229
--  function "/" (l : UNRESOLVED_sfixed; r : REAL) return UNRESOLVED_sfixed;
230
 
231
  -- sfixed(c downto d) / sfixed(c downto d) = sfixed(c-d+1 downto d-c)
232
--  function "/" (l : REAL; r : UNRESOLVED_sfixed) return UNRESOLVED_sfixed;
233
 
234
  -- sfixed(a downto b) / sfixed(a downto 0) = sfixed(a+1 downto b-a)
235
--  function "/" (l : UNRESOLVED_sfixed; r : INTEGER) return UNRESOLVED_sfixed;
236
 
237
  -- sfixed(c downto 0) / sfixed(c downto d) = sfixed(c-d+1 downto -c)
238
--  function "/" (l : INTEGER; r : UNRESOLVED_sfixed) return UNRESOLVED_sfixed;
239
 
240
  -- sfixed (a downto b) rem sfixed (a downto b) = sfixed (a downto b)
241
--  function "rem" (l : UNRESOLVED_sfixed; r : REAL) return UNRESOLVED_sfixed;
242
 
243
--  -- sfixed (c downto d) rem sfixed (c downto d) = sfixed (c downto d)
244
--  function "rem" (l : REAL; r : UNRESOLVED_sfixed) return UNRESOLVED_sfixed;
245
 
246
--  -- sfixed (a downto b) rem sfixed (a downto 0) = sfixed (a downto minimum(b,0))
247
--  function "rem" (l : UNRESOLVED_sfixed; r : INTEGER) return UNRESOLVED_sfixed;
248
 
249
--  -- sfixed (c downto 0) rem sfixed (c downto d) = sfixed (c downto minimum(d,0))
250
--  function "rem" (l : INTEGER; r : UNRESOLVED_sfixed) return UNRESOLVED_sfixed;
251
 
252
--  -- sfixed (a downto b) mod sfixed (a downto b) = sfixed (a downto b)
253
--  function "mod" (l : UNRESOLVED_sfixed; r : REAL) return UNRESOLVED_sfixed;
254
 
255
--  -- sfixed (c downto d) mod sfixed (c downto d) = sfixed (c downto d)
256
--  function "mod" (l : REAL; r : UNRESOLVED_sfixed) return UNRESOLVED_sfixed;
257
 
258
--  -- sfixed (a downto b) mod sfixed (a downto 0) = sfixed (a downto minimum(b,0))
259
--  function "mod" (l : UNRESOLVED_sfixed; r : INTEGER) return UNRESOLVED_sfixed;
260
 
261
--  -- sfixed (c downto 0) mod sfixed (c downto d) = sfixed (c downto minimum(d,0))
262
--  function "mod" (l : INTEGER; r : UNRESOLVED_sfixed) return UNRESOLVED_sfixed;
263
 
264
  -- This version of divide gives the user more control
265
  -- ufixed(a downto b) / ufixed(c downto d) = ufixed(a-d downto b-c-1)
266
--  function divide (
267
--    l, r                 : UNRESOLVED_ufixed;
268
--    constant round_style : fixed_round_style_type := fixed_round_style;
269
--    constant guard_bits  : NATURAL                := fixed_guard_bits)
270
--    return UNRESOLVED_ufixed;
271
 
272
  -- This version of divide gives the user more control
273
  -- sfixed(a downto b) / sfixed(c downto d) = sfixed(a-d+1 downto b-c)
274
--  function divide (
275
--    l, r                 : UNRESOLVED_sfixed;
276
--    constant round_style : fixed_round_style_type := fixed_round_style;
277
--    constant guard_bits  : NATURAL                := fixed_guard_bits)
278
--    return UNRESOLVED_sfixed;
279
 
280
  -- These functions return 1/X
281
  -- 1 / ufixed(a downto b) = ufixed(-b downto -a-1)
282
--  function reciprocal (
283
--    arg                  : UNRESOLVED_ufixed;  -- fixed point input
284
--    constant round_style : fixed_round_style_type := fixed_round_style;
285
--    constant guard_bits  : NATURAL                := fixed_guard_bits)
286
--    return UNRESOLVED_ufixed;
287
 
288
  -- 1 / sfixed(a downto b) = sfixed(-b+1 downto -a)
289
--  function reciprocal (
290
--    arg                  : UNRESOLVED_sfixed;  -- fixed point input
291
--    constant round_style : fixed_round_style_type := fixed_round_style;
292
--    constant guard_bits  : NATURAL                := fixed_guard_bits)
293
--    return UNRESOLVED_sfixed;
294
 
295
  -- REM function
296
  -- ufixed (a downto b) rem ufixed (c downto d)
297
  --   = ufixed (minimum(a,c) downto minimum(b,d))
298
--  function remainder (
299
--    l, r                 : UNRESOLVED_ufixed;
300
--    constant round_style : fixed_round_style_type := fixed_round_style;
301
--    constant guard_bits  : NATURAL                := fixed_guard_bits)
302
--    return UNRESOLVED_ufixed;
303
 
304
  -- sfixed (a downto b) rem sfixed (c downto d)
305
  --   = sfixed (minimum(a,c) downto minimum(b,d))
306
--  function remainder (
307
--    l, r                 : UNRESOLVED_sfixed;
308
--    constant round_style : fixed_round_style_type := fixed_round_style;
309
--    constant guard_bits  : NATURAL                := fixed_guard_bits)
310
--    return UNRESOLVED_sfixed;
311
 
312
  -- mod function
313
  -- ufixed (a downto b) mod ufixed (c downto d)
314
  --        = ufixed (minimum(a,c) downto minimum(b, d))
315
--  function modulo (
316
--    l, r                 : UNRESOLVED_ufixed;
317
--    constant round_style : fixed_round_style_type := fixed_round_style;
318
--    constant guard_bits  : NATURAL                := fixed_guard_bits)
319
--    return UNRESOLVED_ufixed;
320
 
321
  -- sfixed (a downto b) mod sfixed (c downto d)
322
  --        = sfixed (c downto minimum(b, d))
323
--  function modulo (
324
--    l, r                    : UNRESOLVED_sfixed;
325
--    constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
326
--    constant round_style    : fixed_round_style_type    := fixed_round_style;
327
--    constant guard_bits     : NATURAL                   := fixed_guard_bits)
328
--    return UNRESOLVED_sfixed;
329
 
330
  -- Procedure for those who need an "accumulator" function.
331
  -- add_carry (ufixed(a downto b), ufixed (c downto d))
332
  --         = ufixed (maximum(a,c) downto minimum(b,d))
333
  procedure add_carry (
334
    L, R   : in  UNRESOLVED_ufixed;
335
    c_in   : in  STD_ULOGIC;
336
    result : out UNRESOLVED_ufixed;
337
    c_out  : out STD_ULOGIC);
338
 
339
  -- add_carry (sfixed(a downto b), sfixed (c downto d))
340
  --         = sfixed (maximum(a,c) downto minimum(b,d))
341
  procedure add_carry (
342
    L, R   : in  UNRESOLVED_sfixed;
343
    c_in   : in  STD_ULOGIC;
344
    result : out UNRESOLVED_sfixed;
345
    c_out  : out STD_ULOGIC);
346
 
347
  -- Scales the result by a power of 2.  Width of input = width of output with
348
  -- the binary point moved.
349
  function scalb (y : UNRESOLVED_ufixed; N : INTEGER) return UNRESOLVED_ufixed;
350
  function scalb (y : UNRESOLVED_ufixed; N : SIGNED) return UNRESOLVED_ufixed;
351
  function scalb (y : UNRESOLVED_sfixed; N : INTEGER) return UNRESOLVED_sfixed;
352
  function scalb (y : UNRESOLVED_sfixed; N : SIGNED) return UNRESOLVED_sfixed;
353
 
354
  function Is_Negative (arg : UNRESOLVED_sfixed) return BOOLEAN;
355
 
356
  --===========================================================================
357
  -- Comparison Operators
358
  --===========================================================================
359
 
360
  function ">"  (l, r : UNRESOLVED_ufixed) return BOOLEAN;
361
  function ">"  (l, r : UNRESOLVED_sfixed) return BOOLEAN;
362
  function "<"  (l, r : UNRESOLVED_ufixed) return BOOLEAN;
363
  function "<"  (l, r : UNRESOLVED_sfixed) return BOOLEAN;
364
  function "<=" (l, r : UNRESOLVED_ufixed) return BOOLEAN;
365
  function "<=" (l, r : UNRESOLVED_sfixed) return BOOLEAN;
366
  function ">=" (l, r : UNRESOLVED_ufixed) return BOOLEAN;
367
  function ">=" (l, r : UNRESOLVED_sfixed) return BOOLEAN;
368
  function "="  (l, r : UNRESOLVED_ufixed) return BOOLEAN;
369
  function "="  (l, r : UNRESOLVED_sfixed) return BOOLEAN;
370
  function "/=" (l, r : UNRESOLVED_ufixed) return BOOLEAN;
371
  function "/=" (l, r : UNRESOLVED_sfixed) return BOOLEAN;
372
 
373
  function \?=\  (l, r : UNRESOLVED_ufixed) return STD_ULOGIC;
374
  function \?/=\ (l, r : UNRESOLVED_ufixed) return STD_ULOGIC;
375
  function \?>\  (l, r : UNRESOLVED_ufixed) return STD_ULOGIC;
376
  function \?>=\ (l, r : UNRESOLVED_ufixed) return STD_ULOGIC;
377
  function \?<\  (l, r : UNRESOLVED_ufixed) return STD_ULOGIC;
378
  function \?<=\ (l, r : UNRESOLVED_ufixed) return STD_ULOGIC;
379
  function \?=\  (l, r : UNRESOLVED_sfixed) return STD_ULOGIC;
380
  function \?/=\ (l, r : UNRESOLVED_sfixed) return STD_ULOGIC;
381
  function \?>\  (l, r : UNRESOLVED_sfixed) return STD_ULOGIC;
382
  function \?>=\ (l, r : UNRESOLVED_sfixed) return STD_ULOGIC;
383
  function \?<\  (l, r : UNRESOLVED_sfixed) return STD_ULOGIC;
384
  function \?<=\ (l, r : UNRESOLVED_sfixed) return STD_ULOGIC;
385
 
386
  function std_match (l, r : UNRESOLVED_ufixed) return BOOLEAN;
387
  function std_match (l, r : UNRESOLVED_sfixed) return BOOLEAN;
388
 
389
  -- Overloads the default "maximum" and "minimum" function
390
 
391
  function maximum (l, r : UNRESOLVED_ufixed) return UNRESOLVED_ufixed;
392
  function minimum (l, r : UNRESOLVED_ufixed) return UNRESOLVED_ufixed;
393
  function maximum (l, r : UNRESOLVED_sfixed) return UNRESOLVED_sfixed;
394
  function minimum (l, r : UNRESOLVED_sfixed) return UNRESOLVED_sfixed;
395
 
396
  ----------------------------------------------------------------------------
397
  -- In these compare functions a natural is converted into a
398
  -- fixed point number of the bounds "maximum(l'high,0) downto 0"
399
  ----------------------------------------------------------------------------
400
 
401
  function "="  (l : UNRESOLVED_ufixed; r : NATURAL) return BOOLEAN;
402
  function "/=" (l : UNRESOLVED_ufixed; r : NATURAL) return BOOLEAN;
403
  function ">=" (l : UNRESOLVED_ufixed; r : NATURAL) return BOOLEAN;
404
  function "<=" (l : UNRESOLVED_ufixed; r : NATURAL) return BOOLEAN;
405
  function ">"  (l : UNRESOLVED_ufixed; r : NATURAL) return BOOLEAN;
406
  function "<"  (l : UNRESOLVED_ufixed; r : NATURAL) return BOOLEAN;
407
 
408
  function "="  (l : NATURAL; r : UNRESOLVED_ufixed) return BOOLEAN;
409
  function "/=" (l : NATURAL; r : UNRESOLVED_ufixed) return BOOLEAN;
410
  function ">=" (l : NATURAL; r : UNRESOLVED_ufixed) return BOOLEAN;
411
  function "<=" (l : NATURAL; r : UNRESOLVED_ufixed) return BOOLEAN;
412
  function ">"  (l : NATURAL; r : UNRESOLVED_ufixed) return BOOLEAN;
413
  function "<"  (l : NATURAL; r : UNRESOLVED_ufixed) return BOOLEAN;
414
 
415
  function \?=\  (l : UNRESOLVED_ufixed; r : NATURAL) return STD_ULOGIC;
416
  function \?/=\ (l : UNRESOLVED_ufixed; r : NATURAL) return STD_ULOGIC;
417
  function \?>=\ (l : UNRESOLVED_ufixed; r : NATURAL) return STD_ULOGIC;
418
  function \?<=\ (l : UNRESOLVED_ufixed; r : NATURAL) return STD_ULOGIC;
419
  function \?>\  (l : UNRESOLVED_ufixed; r : NATURAL) return STD_ULOGIC;
420
  function \?<\  (l : UNRESOLVED_ufixed; r : NATURAL) return STD_ULOGIC;
421
 
422
  function \?=\  (l : NATURAL; r : UNRESOLVED_ufixed) return STD_ULOGIC;
423
  function \?/=\ (l : NATURAL; r : UNRESOLVED_ufixed) return STD_ULOGIC;
424
  function \?>=\ (l : NATURAL; r : UNRESOLVED_ufixed) return STD_ULOGIC;
425
  function \?<=\ (l : NATURAL; r : UNRESOLVED_ufixed) return STD_ULOGIC;
426
  function \?>\  (l : NATURAL; r : UNRESOLVED_ufixed) return STD_ULOGIC;
427
  function \?<\  (l : NATURAL; r : UNRESOLVED_ufixed) return STD_ULOGIC;
428
 
429
  function maximum (l : UNRESOLVED_ufixed; r : NATURAL)
430
    return UNRESOLVED_ufixed;
431
  function minimum (l : UNRESOLVED_ufixed; r : NATURAL)
432
    return UNRESOLVED_ufixed;
433
  function maximum (l : NATURAL; r : UNRESOLVED_ufixed)
434
    return UNRESOLVED_ufixed;
435
  function minimum (l : NATURAL; r : UNRESOLVED_ufixed)
436
    return UNRESOLVED_ufixed;
437
  ----------------------------------------------------------------------------
438
  -- In these compare functions a real is converted into a
439
  -- fixed point number of the bounds "l'high+1 downto l'low"
440
  ----------------------------------------------------------------------------
441
 
442
  function "="  (l : UNRESOLVED_ufixed; r : REAL) return BOOLEAN;
443
  function "/=" (l : UNRESOLVED_ufixed; r : REAL) return BOOLEAN;
444
  function ">=" (l : UNRESOLVED_ufixed; r : REAL) return BOOLEAN;
445
  function "<=" (l : UNRESOLVED_ufixed; r : REAL) return BOOLEAN;
446
  function ">"  (l : UNRESOLVED_ufixed; r : REAL) return BOOLEAN;
447
  function "<"  (l : UNRESOLVED_ufixed; r : REAL) return BOOLEAN;
448
 
449
  function "="  (l : REAL; r : UNRESOLVED_ufixed) return BOOLEAN;
450
  function "/=" (l : REAL; r : UNRESOLVED_ufixed) return BOOLEAN;
451
  function ">=" (l : REAL; r : UNRESOLVED_ufixed) return BOOLEAN;
452
  function "<=" (l : REAL; r : UNRESOLVED_ufixed) return BOOLEAN;
453
  function ">"  (l : REAL; r : UNRESOLVED_ufixed) return BOOLEAN;
454
  function "<"  (l : REAL; r : UNRESOLVED_ufixed) return BOOLEAN;
455
 
456
  function \?=\  (l : UNRESOLVED_ufixed; r : REAL) return STD_ULOGIC;
457
  function \?/=\ (l : UNRESOLVED_ufixed; r : REAL) return STD_ULOGIC;
458
  function \?>=\ (l : UNRESOLVED_ufixed; r : REAL) return STD_ULOGIC;
459
  function \?<=\ (l : UNRESOLVED_ufixed; r : REAL) return STD_ULOGIC;
460
  function \?>\  (l : UNRESOLVED_ufixed; r : REAL) return STD_ULOGIC;
461
  function \?<\  (l : UNRESOLVED_ufixed; r : REAL) return STD_ULOGIC;
462
 
463
  function \?=\  (l : REAL; r : UNRESOLVED_ufixed) return STD_ULOGIC;
464
  function \?/=\ (l : REAL; r : UNRESOLVED_ufixed) return STD_ULOGIC;
465
  function \?>=\ (l : REAL; r : UNRESOLVED_ufixed) return STD_ULOGIC;
466
  function \?<=\ (l : REAL; r : UNRESOLVED_ufixed) return STD_ULOGIC;
467
  function \?>\  (l : REAL; r : UNRESOLVED_ufixed) return STD_ULOGIC;
468
  function \?<\  (l : REAL; r : UNRESOLVED_ufixed) return STD_ULOGIC;
469
 
470
  function maximum (l : UNRESOLVED_ufixed; r : REAL) return UNRESOLVED_ufixed;
471
  function maximum (l : REAL; r : UNRESOLVED_ufixed) return UNRESOLVED_ufixed;
472
  function minimum (l : UNRESOLVED_ufixed; r : REAL) return UNRESOLVED_ufixed;
473
  function minimum (l : REAL; r : UNRESOLVED_ufixed) return UNRESOLVED_ufixed;
474
  ----------------------------------------------------------------------------
475
  -- In these compare functions an integer is converted into a
476
  -- fixed point number of the bounds "maximum(l'high,1) downto 0"
477
  ----------------------------------------------------------------------------
478
 
479
  function "="  (l : UNRESOLVED_sfixed; r : INTEGER) return BOOLEAN;
480
  function "/=" (l : UNRESOLVED_sfixed; r : INTEGER) return BOOLEAN;
481
  function ">=" (l : UNRESOLVED_sfixed; r : INTEGER) return BOOLEAN;
482
  function "<=" (l : UNRESOLVED_sfixed; r : INTEGER) return BOOLEAN;
483
  function ">"  (l : UNRESOLVED_sfixed; r : INTEGER) return BOOLEAN;
484
  function "<"  (l : UNRESOLVED_sfixed; r : INTEGER) return BOOLEAN;
485
 
486
  function "="  (l : INTEGER; r : UNRESOLVED_sfixed) return BOOLEAN;
487
  function "/=" (l : INTEGER; r : UNRESOLVED_sfixed) return BOOLEAN;
488
  function ">=" (l : INTEGER; r : UNRESOLVED_sfixed) return BOOLEAN;
489
  function "<=" (l : INTEGER; r : UNRESOLVED_sfixed) return BOOLEAN;
490
  function ">"  (l : INTEGER; r : UNRESOLVED_sfixed) return BOOLEAN;
491
  function "<"  (l : INTEGER; r : UNRESOLVED_sfixed) return BOOLEAN;
492
 
493
  function \?=\  (l : UNRESOLVED_sfixed; r : INTEGER) return STD_ULOGIC;
494
  function \?/=\ (l : UNRESOLVED_sfixed; r : INTEGER) return STD_ULOGIC;
495
  function \?>=\ (l : UNRESOLVED_sfixed; r : INTEGER) return STD_ULOGIC;
496
  function \?<=\ (l : UNRESOLVED_sfixed; r : INTEGER) return STD_ULOGIC;
497
  function \?>\  (l : UNRESOLVED_sfixed; r : INTEGER) return STD_ULOGIC;
498
  function \?<\  (l : UNRESOLVED_sfixed; r : INTEGER) return STD_ULOGIC;
499
 
500
  function \?=\  (l : INTEGER; r : UNRESOLVED_sfixed) return STD_ULOGIC;
501
  function \?/=\ (l : INTEGER; r : UNRESOLVED_sfixed) return STD_ULOGIC;
502
  function \?>=\ (l : INTEGER; r : UNRESOLVED_sfixed) return STD_ULOGIC;
503
  function \?<=\ (l : INTEGER; r : UNRESOLVED_sfixed) return STD_ULOGIC;
504
  function \?>\  (l : INTEGER; r : UNRESOLVED_sfixed) return STD_ULOGIC;
505
  function \?<\  (l : INTEGER; r : UNRESOLVED_sfixed) return STD_ULOGIC;
506
 
507
  function maximum (l : UNRESOLVED_sfixed; r : INTEGER)
508
    return UNRESOLVED_sfixed;
509
  function maximum (l : INTEGER; r : UNRESOLVED_sfixed)
510
    return UNRESOLVED_sfixed;
511
  function minimum (l : UNRESOLVED_sfixed; r : INTEGER)
512
    return UNRESOLVED_sfixed;
513
  function minimum (l : INTEGER; r : UNRESOLVED_sfixed)
514
    return UNRESOLVED_sfixed;
515
  ----------------------------------------------------------------------------
516
  -- In these compare functions a real is converted into a
517
  -- fixed point number of the bounds "l'high+1 downto l'low"
518
  ----------------------------------------------------------------------------
519
 
520
  function "="  (l : UNRESOLVED_sfixed; r : REAL) return BOOLEAN;
521
  function "/=" (l : UNRESOLVED_sfixed; r : REAL) return BOOLEAN;
522
  function ">=" (l : UNRESOLVED_sfixed; r : REAL) return BOOLEAN;
523
  function "<=" (l : UNRESOLVED_sfixed; r : REAL) return BOOLEAN;
524
  function ">"  (l : UNRESOLVED_sfixed; r : REAL) return BOOLEAN;
525
  function "<"  (l : UNRESOLVED_sfixed; r : REAL) return BOOLEAN;
526
 
527
  function "="  (l : REAL; r : UNRESOLVED_sfixed) return BOOLEAN;
528
  function "/=" (l : REAL; r : UNRESOLVED_sfixed) return BOOLEAN;
529
  function ">=" (l : REAL; r : UNRESOLVED_sfixed) return BOOLEAN;
530
  function "<=" (l : REAL; r : UNRESOLVED_sfixed) return BOOLEAN;
531
  function ">"  (l : REAL; r : UNRESOLVED_sfixed) return BOOLEAN;
532
  function "<"  (l : REAL; r : UNRESOLVED_sfixed) return BOOLEAN;
533
 
534
  function \?=\  (l : UNRESOLVED_sfixed; r : REAL) return STD_ULOGIC;
535
  function \?/=\ (l : UNRESOLVED_sfixed; r : REAL) return STD_ULOGIC;
536
  function \?>=\ (l : UNRESOLVED_sfixed; r : REAL) return STD_ULOGIC;
537
  function \?<=\ (l : UNRESOLVED_sfixed; r : REAL) return STD_ULOGIC;
538
  function \?>\  (l : UNRESOLVED_sfixed; r : REAL) return STD_ULOGIC;
539
  function \?<\  (l : UNRESOLVED_sfixed; r : REAL) return STD_ULOGIC;
540
 
541
  function \?=\  (l : REAL; r : UNRESOLVED_sfixed) return STD_ULOGIC;
542
  function \?/=\ (l : REAL; r : UNRESOLVED_sfixed) return STD_ULOGIC;
543
  function \?>=\ (l : REAL; r : UNRESOLVED_sfixed) return STD_ULOGIC;
544
  function \?<=\ (l : REAL; r : UNRESOLVED_sfixed) return STD_ULOGIC;
545
  function \?>\  (l : REAL; r : UNRESOLVED_sfixed) return STD_ULOGIC;
546
  function \?<\  (l : REAL; r : UNRESOLVED_sfixed) return STD_ULOGIC;
547
 
548
  function maximum (l : UNRESOLVED_sfixed; r : REAL) return UNRESOLVED_sfixed;
549
  function maximum (l : REAL; r : UNRESOLVED_sfixed) return UNRESOLVED_sfixed;
550
  function minimum (l : UNRESOLVED_sfixed; r : REAL) return UNRESOLVED_sfixed;
551
  function minimum (l : REAL; r : UNRESOLVED_sfixed) return UNRESOLVED_sfixed;
552
  --===========================================================================
553
  -- Shift and Rotate Functions.
554
  -- Note that sra and sla are not the same as the BIT_VECTOR version
555
  --===========================================================================
556
 
557
  function "sll" (ARG : UNRESOLVED_ufixed; COUNT : INTEGER)
558
    return UNRESOLVED_ufixed;
559
  function "srl" (ARG : UNRESOLVED_ufixed; COUNT : INTEGER)
560
    return UNRESOLVED_ufixed;
561
  function "rol" (ARG : UNRESOLVED_ufixed; COUNT : INTEGER)
562
    return UNRESOLVED_ufixed;
563
  function "ror" (ARG : UNRESOLVED_ufixed; COUNT : INTEGER)
564
    return UNRESOLVED_ufixed;
565
  function "sla" (ARG : UNRESOLVED_ufixed; COUNT : INTEGER)
566
    return UNRESOLVED_ufixed;
567
  function "sra" (ARG : UNRESOLVED_ufixed; COUNT : INTEGER)
568
    return UNRESOLVED_ufixed;
569
  function "sll" (ARG : UNRESOLVED_sfixed; COUNT : INTEGER)
570
    return UNRESOLVED_sfixed;
571
  function "srl" (ARG : UNRESOLVED_sfixed; COUNT : INTEGER)
572
    return UNRESOLVED_sfixed;
573
  function "rol" (ARG : UNRESOLVED_sfixed; COUNT : INTEGER)
574
    return UNRESOLVED_sfixed;
575
  function "ror" (ARG : UNRESOLVED_sfixed; COUNT : INTEGER)
576
    return UNRESOLVED_sfixed;
577
  function "sla" (ARG : UNRESOLVED_sfixed; COUNT : INTEGER)
578
    return UNRESOLVED_sfixed;
579
  function "sra" (ARG : UNRESOLVED_sfixed; COUNT : INTEGER)
580
    return UNRESOLVED_sfixed;
581
  function SHIFT_LEFT  (ARG : UNRESOLVED_ufixed; COUNT : NATURAL)
582
    return UNRESOLVED_ufixed;
583
  function SHIFT_RIGHT (ARG : UNRESOLVED_ufixed; COUNT : NATURAL)
584
    return UNRESOLVED_ufixed;
585
  function SHIFT_LEFT  (ARG : UNRESOLVED_sfixed; COUNT : NATURAL)
586
    return UNRESOLVED_sfixed;
587
  function SHIFT_RIGHT (ARG : UNRESOLVED_sfixed; COUNT : NATURAL)
588
    return UNRESOLVED_sfixed;
589
 
590
  ----------------------------------------------------------------------------
591
  -- logical functions
592
  ----------------------------------------------------------------------------
593
 
594
  function "not"  (l    : UNRESOLVED_ufixed) return UNRESOLVED_ufixed;
595
  function "and"  (l, r : UNRESOLVED_ufixed) return UNRESOLVED_ufixed;
596
  function "or"   (l, r : UNRESOLVED_ufixed) return UNRESOLVED_ufixed;
597
  function "nand" (l, r : UNRESOLVED_ufixed) return UNRESOLVED_ufixed;
598
  function "nor"  (l, r : UNRESOLVED_ufixed) return UNRESOLVED_ufixed;
599
  function "xor"  (l, r : UNRESOLVED_ufixed) return UNRESOLVED_ufixed;
600
  function "xnor" (l, r : UNRESOLVED_ufixed) return UNRESOLVED_ufixed;
601
  function "not"  (l    : UNRESOLVED_sfixed) return UNRESOLVED_sfixed;
602
  function "and"  (l, r : UNRESOLVED_sfixed) return UNRESOLVED_sfixed;
603
  function "or"   (l, r : UNRESOLVED_sfixed) return UNRESOLVED_sfixed;
604
  function "nand" (l, r : UNRESOLVED_sfixed) return UNRESOLVED_sfixed;
605
  function "nor"  (l, r : UNRESOLVED_sfixed) return UNRESOLVED_sfixed;
606
  function "xor"  (l, r : UNRESOLVED_sfixed) return UNRESOLVED_sfixed;
607
  function "xnor" (l, r : UNRESOLVED_sfixed) return UNRESOLVED_sfixed;
608
 
609
  -- Vector and std_ulogic functions, same as functions in numeric_std
610
  function "and"  (l : STD_ULOGIC; r : UNRESOLVED_ufixed)
611
    return UNRESOLVED_ufixed;
612
  function "and"  (l : UNRESOLVED_ufixed; r : STD_ULOGIC)
613
    return UNRESOLVED_ufixed;
614
  function "or"   (l : STD_ULOGIC; r : UNRESOLVED_ufixed)
615
    return UNRESOLVED_ufixed;
616
  function "or"   (l : UNRESOLVED_ufixed; r : STD_ULOGIC)
617
    return UNRESOLVED_ufixed;
618
  function "nand" (l : STD_ULOGIC; r : UNRESOLVED_ufixed)
619
    return UNRESOLVED_ufixed;
620
  function "nand" (l : UNRESOLVED_ufixed; r : STD_ULOGIC)
621
    return UNRESOLVED_ufixed;
622
  function "nor"  (l : STD_ULOGIC; r : UNRESOLVED_ufixed)
623
    return UNRESOLVED_ufixed;
624
  function "nor"  (l : UNRESOLVED_ufixed; r : STD_ULOGIC)
625
    return UNRESOLVED_ufixed;
626
  function "xor"  (l : STD_ULOGIC; r : UNRESOLVED_ufixed)
627
    return UNRESOLVED_ufixed;
628
  function "xor"  (l : UNRESOLVED_ufixed; r : STD_ULOGIC)
629
    return UNRESOLVED_ufixed;
630
  function "xnor" (l : STD_ULOGIC; r : UNRESOLVED_ufixed)
631
    return UNRESOLVED_ufixed;
632
  function "xnor" (l : UNRESOLVED_ufixed; r : STD_ULOGIC)
633
    return UNRESOLVED_ufixed;
634
  function "and"  (l : STD_ULOGIC; r : UNRESOLVED_sfixed)
635
    return UNRESOLVED_sfixed;
636
  function "and"  (l : UNRESOLVED_sfixed; r : STD_ULOGIC)
637
    return UNRESOLVED_sfixed;
638
  function "or"   (l : STD_ULOGIC; r : UNRESOLVED_sfixed)
639
    return UNRESOLVED_sfixed;
640
  function "or"   (l : UNRESOLVED_sfixed; r : STD_ULOGIC)
641
    return UNRESOLVED_sfixed;
642
  function "nand" (l : STD_ULOGIC; r : UNRESOLVED_sfixed)
643
    return UNRESOLVED_sfixed;
644
  function "nand" (l : UNRESOLVED_sfixed; r : STD_ULOGIC)
645
    return UNRESOLVED_sfixed;
646
  function "nor"  (l : STD_ULOGIC; r : UNRESOLVED_sfixed)
647
    return UNRESOLVED_sfixed;
648
  function "nor"  (l : UNRESOLVED_sfixed; r : STD_ULOGIC)
649
    return UNRESOLVED_sfixed;
650
  function "xor"  (l : STD_ULOGIC; r : UNRESOLVED_sfixed)
651
    return UNRESOLVED_sfixed;
652
  function "xor"  (l : UNRESOLVED_sfixed; r : STD_ULOGIC)
653
    return UNRESOLVED_sfixed;
654
  function "xnor" (l : STD_ULOGIC; r : UNRESOLVED_sfixed)
655
    return UNRESOLVED_sfixed;
656
  function "xnor" (l : UNRESOLVED_sfixed; r : STD_ULOGIC)
657
    return UNRESOLVED_sfixed;
658
 
659
  -- Reduction operators, same as numeric_std functions
660
  function and_reduce (l : UNRESOLVED_ufixed) return STD_ULOGIC;
661
  function nand_reduce (l : UNRESOLVED_ufixed) return STD_ULOGIC;
662
  function or_reduce (l : UNRESOLVED_ufixed) return STD_ULOGIC;
663
  function nor_reduce (l : UNRESOLVED_ufixed) return STD_ULOGIC;
664
  function xor_reduce (l : UNRESOLVED_ufixed) return STD_ULOGIC;
665
  function xnor_reduce (l : UNRESOLVED_ufixed) return STD_ULOGIC;
666
  function and_reduce (l : UNRESOLVED_sfixed) return STD_ULOGIC;
667
  function nand_reduce (l : UNRESOLVED_sfixed) return STD_ULOGIC;
668
  function or_reduce (l : UNRESOLVED_sfixed) return STD_ULOGIC;
669
  function nor_reduce (l : UNRESOLVED_sfixed) return STD_ULOGIC;
670
  function xor_reduce (l : UNRESOLVED_sfixed) return STD_ULOGIC;
671
  function xnor_reduce (l : UNRESOLVED_sfixed) return STD_ULOGIC;
672
 
673
  -- returns arg'low-1 if not found
674
  function find_leftmost (arg : UNRESOLVED_ufixed; y : STD_ULOGIC)
675
    return INTEGER;
676
  function find_leftmost (arg : UNRESOLVED_sfixed; y : STD_ULOGIC)
677
    return INTEGER;
678
 
679
  -- returns arg'high+1 if not found
680
  function find_rightmost (arg : UNRESOLVED_ufixed; y : STD_ULOGIC)
681
    return INTEGER;
682
  function find_rightmost (arg : UNRESOLVED_sfixed; y : STD_ULOGIC)
683
    return INTEGER;
684
 
685
  --===========================================================================
686
  --   RESIZE Functions
687
  --===========================================================================
688
  -- resizes the number (larger or smaller)
689
  -- The returned result will be ufixed (left_index downto right_index)
690
  -- If "round_style" is fixed_round, then the result will be rounded.
691
  -- If the MSB of the remainder is a "1" AND the LSB of the unrounded result
692
  -- is a '1' or the lower bits of the remainder include a '1' then the result
693
  -- will be increased by the smallest representable number for that type.
694
  -- "overflow_style" can be fixed_saturate or fixed_wrap.
695
  -- In saturate mode, if the number overflows then the largest possible
696
  -- representable number is returned.  If wrap mode, then the upper bits
697
  -- of the number are truncated.
698
 
699
  function resize (
700
    arg                     : UNRESOLVED_ufixed;  -- input
701
    constant left_index     : INTEGER;  -- integer portion
702
    constant right_index    : INTEGER;  -- size of fraction
703
    constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
704
    constant round_style    : fixed_round_style_type    := fixed_round_style)
705
    return UNRESOLVED_ufixed;
706
 
707
  -- "size_res" functions create the size of the output from the indices
708
  -- of the "size_res" input.  The actual value of "size_res" is not used.
709
  function resize (
710
    arg                     : UNRESOLVED_ufixed;  -- input
711
    size_res                : UNRESOLVED_ufixed;  -- for size only
712
    constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
713
    constant round_style    : fixed_round_style_type    := fixed_round_style)
714
    return UNRESOLVED_ufixed;
715
 
716
  -- Note that in "wrap" mode the sign bit is not replicated.  Thus the
717
  -- resize of a negative number can have a positive result in wrap mode.
718
  function resize (
719
    arg                     : UNRESOLVED_sfixed;  -- input
720
    constant left_index     : INTEGER;            -- integer portion
721
    constant right_index    : INTEGER;            -- size of fraction
722
    constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
723
    constant round_style    : fixed_round_style_type    := fixed_round_style)
724
    return UNRESOLVED_sfixed;
725
 
726
  function resize (
727
    arg                     : UNRESOLVED_sfixed;  -- input
728
    size_res                : UNRESOLVED_sfixed;  -- for size only
729
    constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
730
    constant round_style    : fixed_round_style_type    := fixed_round_style)
731
    return UNRESOLVED_sfixed;
732
 
733
  --===========================================================================
734
  -- Conversion Functions
735
  --===========================================================================
736
 
737
  -- integer (natural) to unsigned fixed point.
738
  -- arguments are the upper and lower bounds of the number, thus
739
  -- ufixed (7 downto -3) <= to_ufixed (int, 7, -3);
740
  function to_ufixed (
741
    arg                     : NATURAL;  -- integer
742
    constant left_index     : INTEGER;  -- left index (high index)
743
    constant right_index    : INTEGER                   := 0;  -- right index
744
    constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
745
    constant round_style    : fixed_round_style_type    := fixed_round_style)
746
    return UNRESOLVED_ufixed;
747
 
748
  function to_ufixed (
749
    arg                     : NATURAL;            -- integer
750
    size_res                : UNRESOLVED_ufixed;  -- for size only
751
    constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
752
    constant round_style    : fixed_round_style_type    := fixed_round_style)
753
    return UNRESOLVED_ufixed;
754
 
755
  -- real to unsigned fixed point
756
  function to_ufixed (
757
    arg                     : REAL;     -- real
758
    constant left_index     : INTEGER;  -- left index (high index)
759
    constant right_index    : INTEGER;  -- right index
760
    constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
761
    constant round_style    : fixed_round_style_type    := fixed_round_style;
762
    constant guard_bits     : NATURAL                   := fixed_guard_bits)
763
    return UNRESOLVED_ufixed;
764
 
765
  function to_ufixed (
766
    arg                     : REAL;     -- real
767
    size_res                : UNRESOLVED_ufixed;  -- for size only
768
    constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
769
    constant round_style    : fixed_round_style_type    := fixed_round_style;
770
    constant guard_bits     : NATURAL                   := fixed_guard_bits)
771
    return UNRESOLVED_ufixed;
772
 
773
  -- unsigned to unsigned fixed point
774
  function to_ufixed (
775
    arg                     : UNSIGNED;                        -- unsigned
776
    constant left_index     : INTEGER;  -- left index (high index)
777
    constant right_index    : INTEGER                   := 0;  -- right index
778
    constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
779
    constant round_style    : fixed_round_style_type    := fixed_round_style)
780
    return UNRESOLVED_ufixed;
781
 
782
  function to_ufixed (
783
    arg                     : UNSIGNED;           -- unsigned
784
    size_res                : UNRESOLVED_ufixed;  -- for size only
785
    constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
786
    constant round_style    : fixed_round_style_type    := fixed_round_style)
787
    return UNRESOLVED_ufixed;
788
 
789
  -- Performs a conversion.  ufixed (arg'range) is returned
790
  function to_ufixed (
791
    arg : UNSIGNED)          -- unsigned
792
    return UNRESOLVED_ufixed;
793
 
794
  -- unsigned fixed point to unsigned
795
  function to_unsigned (
796
    arg                     : UNRESOLVED_ufixed;  -- fixed point input
797
    constant size           : NATURAL;            -- length of output
798
    constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
799
    constant round_style    : fixed_round_style_type    := fixed_round_style)
800
    return UNSIGNED;
801
 
802
  -- unsigned fixed point to unsigned
803
  function to_unsigned (
804
    arg                     : UNRESOLVED_ufixed;    -- fixed point input
805
    size_res                : UNSIGNED;  -- used for length of output
806
    constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
807
    constant round_style    : fixed_round_style_type    := fixed_round_style)
808
    return UNSIGNED;
809
 
810
  -- unsigned fixed point to real
811
  function to_real (
812
    arg : UNRESOLVED_ufixed)            -- fixed point input
813
    return REAL;
814
 
815
  -- unsigned fixed point to integer
816
  function to_integer (
817
    arg                     : UNRESOLVED_ufixed;  -- fixed point input
818
    constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
819
    constant round_style    : fixed_round_style_type    := fixed_round_style)
820
    return NATURAL;
821
 
822
  -- Integer to UNRESOLVED_sfixed
823
  function to_sfixed (
824
    arg                     : INTEGER;  -- integer
825
    constant left_index     : INTEGER;  -- left index (high index)
826
    constant right_index    : INTEGER                   := 0;  -- right index
827
    constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
828
    constant round_style    : fixed_round_style_type    := fixed_round_style)
829
    return UNRESOLVED_sfixed;
830
 
831
  function to_sfixed (
832
    arg                     : INTEGER;            -- integer
833
    size_res                : UNRESOLVED_sfixed;  -- for size only
834
    constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
835
    constant round_style    : fixed_round_style_type    := fixed_round_style)
836
    return UNRESOLVED_sfixed;
837
 
838
  -- Real to sfixed
839
  function to_sfixed (
840
    arg                     : REAL;     -- real
841
    constant left_index     : INTEGER;  -- left index (high index)
842
    constant right_index    : INTEGER;  -- right index
843
    constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
844
    constant round_style    : fixed_round_style_type    := fixed_round_style;
845
    constant guard_bits     : NATURAL                   := fixed_guard_bits)
846
    return UNRESOLVED_sfixed;
847
 
848
  function to_sfixed (
849
    arg                     : REAL;     -- real
850
    size_res                : UNRESOLVED_sfixed;  -- for size only
851
    constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
852
    constant round_style    : fixed_round_style_type    := fixed_round_style;
853
    constant guard_bits     : NATURAL                   := fixed_guard_bits)
854
    return UNRESOLVED_sfixed;
855
 
856
  -- signed to sfixed
857
  function to_sfixed (
858
    arg                     : SIGNED;               -- signed
859
    constant left_index     : INTEGER;  -- left index (high index)
860
    constant right_index    : INTEGER                   := 0;  -- right index
861
    constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
862
    constant round_style    : fixed_round_style_type    := fixed_round_style)
863
    return UNRESOLVED_sfixed;
864
 
865
  function to_sfixed (
866
    arg                     : SIGNED;  -- signed
867
    size_res                : UNRESOLVED_sfixed;  -- for size only
868
    constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
869
    constant round_style    : fixed_round_style_type    := fixed_round_style)
870
    return UNRESOLVED_sfixed;
871
 
872
  -- signed to sfixed (output assumed to be size of signed input)
873
  function to_sfixed (
874
    arg : SIGNED)            -- signed
875
    return UNRESOLVED_sfixed;
876
 
877
  -- Conversion from ufixed to sfixed
878
  function to_sfixed (
879
    arg : UNRESOLVED_ufixed)
880
    return UNRESOLVED_sfixed;
881
 
882
  -- signed fixed point to signed
883
  function to_signed (
884
    arg                     : UNRESOLVED_sfixed;  -- fixed point input
885
    constant size           : NATURAL;            -- length of output
886
    constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
887
    constant round_style    : fixed_round_style_type    := fixed_round_style)
888
    return SIGNED;
889
 
890
  -- signed fixed point to signed
891
  function to_signed (
892
    arg                     : UNRESOLVED_sfixed;  -- fixed point input
893
    size_res                : SIGNED;  -- used for length of output
894
    constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
895
    constant round_style    : fixed_round_style_type    := fixed_round_style)
896
    return SIGNED;
897
 
898
  -- signed fixed point to real
899
  function to_real (
900
    arg : UNRESOLVED_sfixed)            -- fixed point input
901
    return REAL;
902
 
903
  -- signed fixed point to integer
904
  function to_integer (
905
    arg                     : UNRESOLVED_sfixed;  -- fixed point input
906
    constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
907
    constant round_style    : fixed_round_style_type    := fixed_round_style)
908
    return INTEGER;
909
 
910
  -- Because of the fairly complicated sizing rules in the fixed point
911
  -- packages these functions are provided to compute the result ranges
912
  -- Example:
913
  -- signal uf1 : ufixed (3 downto -3);
914
  -- signal uf2 : ufixed (4 downto -2);
915
  -- signal uf1multuf2 : ufixed (ufixed_high (3, -3, '*', 4, -2) downto
916
  --                             ufixed_low (3, -3, '*', 4, -2));
917
  -- uf1multuf2 <= uf1 * uf2;
918
  -- Valid characters: '+', '-', '*', '/', 'r' or 'R' (rem), 'm' or 'M' (mod),
919
  --                   '1' (reciprocal), 'a' or 'A' (abs), 'n' or 'N' (unary -)
920
  function ufixed_high (left_index, right_index   : INTEGER;
921
                        operation                 : CHARACTER := 'X';
922
                        left_index2, right_index2 : INTEGER   := 0)
923
    return INTEGER;
924
 
925
  function ufixed_low (left_index, right_index   : INTEGER;
926
                       operation                 : CHARACTER := 'X';
927
                       left_index2, right_index2 : INTEGER   := 0)
928
    return INTEGER;
929
 
930
  function sfixed_high (left_index, right_index   : INTEGER;
931
                        operation                 : CHARACTER := 'X';
932
                        left_index2, right_index2 : INTEGER   := 0)
933
    return INTEGER;
934
 
935
  function sfixed_low (left_index, right_index   : INTEGER;
936
                       operation                 : CHARACTER := 'X';
937
                       left_index2, right_index2 : INTEGER   := 0)
938
    return INTEGER;
939
 
940
  -- Same as above, but using the "size_res" input only for their ranges:
941
  -- signal uf1multuf2 : ufixed (ufixed_high (uf1, '*', uf2) downto
942
  --                             ufixed_low (uf1, '*', uf2));
943
  -- uf1multuf2 <= uf1 * uf2;
944
  -- 
945
  function ufixed_high (size_res  : UNRESOLVED_ufixed;
946
                        operation : CHARACTER := 'X';
947
                        size_res2 : UNRESOLVED_ufixed)
948
    return INTEGER;
949
 
950
  function ufixed_low (size_res  : UNRESOLVED_ufixed;
951
                       operation : CHARACTER := 'X';
952
                       size_res2 : UNRESOLVED_ufixed)
953
    return INTEGER;
954
 
955
  function sfixed_high (size_res  : UNRESOLVED_sfixed;
956
                        operation : CHARACTER := 'X';
957
                        size_res2 : UNRESOLVED_sfixed)
958
    return INTEGER;
959
 
960
  function sfixed_low (size_res  : UNRESOLVED_sfixed;
961
                       operation : CHARACTER := 'X';
962
                       size_res2 : UNRESOLVED_sfixed)
963
    return INTEGER;
964
 
965
  -- purpose: returns a saturated number
966
  function saturate (
967
    constant left_index  : INTEGER;
968
    constant right_index : INTEGER)
969
    return UNRESOLVED_ufixed;
970
 
971
  -- purpose: returns a saturated number
972
  function saturate (
973
    constant left_index  : INTEGER;
974
    constant right_index : INTEGER)
975
    return UNRESOLVED_sfixed;
976
 
977
  function saturate (
978
    size_res : UNRESOLVED_ufixed)       -- only the size of this is used
979
    return UNRESOLVED_ufixed;
980
 
981
  function saturate (
982
    size_res : UNRESOLVED_sfixed)       -- only the size of this is used
983
    return UNRESOLVED_sfixed;
984
 
985
  --===========================================================================
986
  -- Translation Functions
987
  --===========================================================================
988
 
989
  -- maps meta-logical values
990
  function to_01 (
991
    s             : UNRESOLVED_ufixed;  -- fixed point input
992
    constant XMAP : STD_ULOGIC := '0')  -- Map x to
993
    return UNRESOLVED_ufixed;
994
 
995
  -- maps meta-logical values
996
  function to_01 (
997
    s             : UNRESOLVED_sfixed;  -- fixed point input
998
    constant XMAP : STD_ULOGIC := '0')  -- Map x to
999
    return UNRESOLVED_sfixed;
1000
 
1001
  function Is_X    (arg : UNRESOLVED_ufixed) return BOOLEAN;
1002
  function Is_X    (arg : UNRESOLVED_sfixed) return BOOLEAN;
1003
  function to_X01  (arg : UNRESOLVED_ufixed) return UNRESOLVED_ufixed;
1004
  function to_X01  (arg : UNRESOLVED_sfixed) return UNRESOLVED_sfixed;
1005
  function to_X01Z (arg : UNRESOLVED_ufixed) return UNRESOLVED_ufixed;
1006
  function to_X01Z (arg : UNRESOLVED_sfixed) return UNRESOLVED_sfixed;
1007
  function to_UX01 (arg : UNRESOLVED_ufixed) return UNRESOLVED_ufixed;
1008
  function to_UX01 (arg : UNRESOLVED_sfixed) return UNRESOLVED_sfixed;
1009
 
1010
  -- straight vector conversion routines, needed for synthesis.
1011
  -- These functions are here so that a std_logic_vector can be
1012
  -- converted to and from sfixed and ufixed.  Note that you can
1013
  -- not convert these vectors because of their negative index.
1014
 
1015
  function to_slv (
1016
    arg : UNRESOLVED_ufixed)            -- fixed point vector
1017
    return STD_LOGIC_VECTOR;
1018
--  alias to_StdLogicVector is to_slv [UNRESOLVED_ufixed
1019
--                                     return STD_LOGIC_VECTOR];
1020
--  alias to_Std_Logic_Vector is to_slv [UNRESOLVED_ufixed
1021
--                                       return STD_LOGIC_VECTOR];
1022
 
1023
  function to_slv (
1024
    arg : UNRESOLVED_sfixed)            -- fixed point vector
1025
    return STD_LOGIC_VECTOR;
1026
--  alias to_StdLogicVector is to_slv [UNRESOLVED_sfixed
1027
--                                     return STD_LOGIC_VECTOR];
1028
--  alias to_Std_Logic_Vector is to_slv [UNRESOLVED_sfixed
1029
--                                       return STD_LOGIC_VECTOR];
1030
 
1031
  function to_sulv (
1032
    arg : UNRESOLVED_ufixed)            -- fixed point vector
1033
    return STD_ULOGIC_VECTOR;
1034
--  alias to_StdULogicVector is to_sulv [UNRESOLVED_ufixed
1035
--                                      return STD_ULOGIC_VECTOR];
1036
--  alias to_Std_ULogic_Vector is to_sulv [UNRESOLVED_ufixed
1037
--                                        return STD_ULOGIC_VECTOR];
1038
 
1039
  function to_sulv (
1040
    arg : UNRESOLVED_sfixed)            -- fixed point vector
1041
    return STD_ULOGIC_VECTOR;
1042
--  alias to_StdULogicVector is to_sulv [UNRESOLVED_sfixed
1043
--                                      return STD_ULOGIC_VECTOR];
1044
--  alias to_Std_ULogic_Vector is to_sulv [UNRESOLVED_sfixed
1045
--                                        return STD_ULOGIC_VECTOR];
1046
 
1047
  function to_ufixed (
1048
    arg                  : STD_ULOGIC_VECTOR;  -- shifted vector
1049
    constant left_index  : INTEGER;
1050
    constant right_index : INTEGER)
1051
    return UNRESOLVED_ufixed;
1052
 
1053
  function to_ufixed (
1054
    arg      : STD_ULOGIC_VECTOR;       -- shifted vector
1055
    size_res : UNRESOLVED_ufixed)       -- for size only
1056
    return UNRESOLVED_ufixed;
1057
 
1058
  function to_sfixed (
1059
    arg                  : STD_ULOGIC_VECTOR;  -- shifted vector
1060
    constant left_index  : INTEGER;
1061
    constant right_index : INTEGER)
1062
    return UNRESOLVED_sfixed;
1063
 
1064
  function to_sfixed (
1065
    arg      : STD_ULOGIC_VECTOR;       -- shifted vector
1066
    size_res : UNRESOLVED_sfixed)       -- for size only
1067
    return UNRESOLVED_sfixed;
1068
 
1069
  -- As a concession to those who use a graphical DSP environment,
1070
  -- these functions take parameters in those tools format and create
1071
  -- fixed point numbers.  These functions are designed to convert from
1072
  -- a std_logic_vector to the VHDL fixed point format using the conventions
1073
  -- of these packages.  In a pure VHDL environment you should use the
1074
  -- "to_ufixed" and "to_sfixed" routines.
1075
 
1076
  -- unsigned fixed point
1077
  function to_UFix (
1078
    arg      : STD_ULOGIC_VECTOR;
1079
    width    : NATURAL;                 -- width of vector
1080
    fraction : NATURAL)                 -- width of fraction
1081
    return UNRESOLVED_ufixed;
1082
 
1083
  -- signed fixed point
1084
  function to_SFix (
1085
    arg      : STD_ULOGIC_VECTOR;
1086
    width    : NATURAL;                 -- width of vector
1087
    fraction : NATURAL)                 -- width of fraction
1088
    return UNRESOLVED_sfixed;
1089
 
1090
  -- finding the bounds of a number.  These functions can be used like this:
1091
  -- signal xxx : ufixed (7 downto -3);
1092
  -- -- Which is the same as "ufixed (UFix_high (11,3) downto UFix_low(11,3))"
1093
  -- signal yyy : ufixed (UFix_high (11, 3, "+", 11, 3)
1094
  --               downto UFix_low(11, 3, "+", 11, 3));
1095
  -- Where "11" is the width of xxx (xxx'length),
1096
  -- and 3 is the lower bound (abs (xxx'low))
1097
  -- In a pure VHDL environment use "ufixed_high" and "ufixed_low"
1098
 
1099
  function UFix_high (width, fraction   : NATURAL;
1100
                      operation         : CHARACTER := 'X';
1101
                      width2, fraction2 : NATURAL   := 0)
1102
    return INTEGER;
1103
 
1104
  function UFix_low (width, fraction   : NATURAL;
1105
                     operation         : CHARACTER := 'X';
1106
                     width2, fraction2 : NATURAL   := 0)
1107
    return INTEGER;
1108
 
1109
  -- Same as above but for signed fixed point.  Note that the width
1110
  -- of a signed fixed point number ignores the sign bit, thus
1111
  -- width = sxxx'length-1
1112
 
1113
  function SFix_high (width, fraction   : NATURAL;
1114
                      operation         : CHARACTER := 'X';
1115
                      width2, fraction2 : NATURAL   := 0)
1116
    return INTEGER;
1117
 
1118
  function SFix_low (width, fraction   : NATURAL;
1119
                     operation         : CHARACTER := 'X';
1120
                     width2, fraction2 : NATURAL   := 0)
1121
    return INTEGER;
1122
-- rtl_synthesis off
1123
-- pragma synthesis_off
1124
  --===========================================================================
1125
  -- string and textio Functions
1126
  --===========================================================================
1127
 
1128
  -- purpose: writes fixed point into a line
1129
  procedure WRITE (
1130
    L         : inout LINE;               -- input line
1131
    VALUE     : in    UNRESOLVED_ufixed;  -- fixed point input
1132
    JUSTIFIED : in    SIDE  := right;
1133
    FIELD     : in    WIDTH := 0);
1134
 
1135
  -- purpose: writes fixed point into a line
1136
  procedure WRITE (
1137
    L         : inout LINE;               -- input line
1138
    VALUE     : in    UNRESOLVED_sfixed;  -- fixed point input
1139
    JUSTIFIED : in    SIDE  := right;
1140
    FIELD     : in    WIDTH := 0);
1141
 
1142
  procedure READ(L     : inout LINE;
1143
                 VALUE : out   UNRESOLVED_ufixed);
1144
 
1145
  procedure READ(L     : inout LINE;
1146
                 VALUE : out   UNRESOLVED_ufixed;
1147
                 GOOD  : out   BOOLEAN);
1148
 
1149
  procedure READ(L     : inout LINE;
1150
                 VALUE : out   UNRESOLVED_sfixed);
1151
 
1152
  procedure READ(L     : inout LINE;
1153
                 VALUE : out   UNRESOLVED_sfixed;
1154
                 GOOD  : out   BOOLEAN);
1155
 
1156
  alias bwrite is WRITE [LINE, UNRESOLVED_ufixed, SIDE, width];
1157
  alias bwrite is WRITE [LINE, UNRESOLVED_sfixed, SIDE, width];
1158
  alias bread is READ [LINE, UNRESOLVED_ufixed];
1159
  alias bread is READ [LINE, UNRESOLVED_ufixed, BOOLEAN];
1160
  alias bread is READ [LINE, UNRESOLVED_sfixed];
1161
  alias bread is READ [LINE, UNRESOLVED_sfixed, BOOLEAN];
1162
  alias BINARY_WRITE is WRITE [LINE, UNRESOLVED_ufixed, SIDE, width];
1163
  alias BINARY_WRITE is WRITE [LINE, UNRESOLVED_sfixed, SIDE, width];
1164
  alias BINARY_READ is READ [LINE, UNRESOLVED_ufixed, BOOLEAN];
1165
  alias BINARY_READ is READ [LINE, UNRESOLVED_ufixed];
1166
  alias BINARY_READ is READ [LINE, UNRESOLVED_sfixed, BOOLEAN];
1167
  alias BINARY_READ is READ [LINE, UNRESOLVED_sfixed];
1168
 
1169
  -- octal read and write
1170
  procedure OWRITE (
1171
    L         : inout LINE;               -- input line
1172
    VALUE     : in    UNRESOLVED_ufixed;  -- fixed point input
1173
    JUSTIFIED : in    SIDE  := right;
1174
    FIELD     : in    WIDTH := 0);
1175
 
1176
  procedure OWRITE (
1177
    L         : inout LINE;               -- input line
1178
    VALUE     : in    UNRESOLVED_sfixed;  -- fixed point input
1179
    JUSTIFIED : in    SIDE  := right;
1180
    FIELD     : in    WIDTH := 0);
1181
 
1182
  procedure OREAD(L     : inout LINE;
1183
                  VALUE : out   UNRESOLVED_ufixed);
1184
 
1185
  procedure OREAD(L     : inout LINE;
1186
                  VALUE : out   UNRESOLVED_ufixed;
1187
                  GOOD  : out   BOOLEAN);
1188
 
1189
  procedure OREAD(L     : inout LINE;
1190
                  VALUE : out   UNRESOLVED_sfixed);
1191
 
1192
  procedure OREAD(L     : inout LINE;
1193
                  VALUE : out   UNRESOLVED_sfixed;
1194
                  GOOD  : out   BOOLEAN);
1195
  alias OCTAL_READ is OREAD [LINE, UNRESOLVED_ufixed, BOOLEAN];
1196
  alias OCTAL_READ is OREAD [LINE, UNRESOLVED_ufixed];
1197
  alias OCTAL_READ is OREAD [LINE, UNRESOLVED_sfixed, BOOLEAN];
1198
  alias OCTAL_READ is OREAD [LINE, UNRESOLVED_sfixed];
1199
  alias OCTAL_WRITE is OWRITE [LINE, UNRESOLVED_ufixed, SIDE, WIDTH];
1200
  alias OCTAL_WRITE is OWRITE [LINE, UNRESOLVED_sfixed, SIDE, WIDTH];
1201
 
1202
  -- hex read and write
1203
  procedure HWRITE (
1204
    L         : inout LINE;               -- input line
1205
    VALUE     : in    UNRESOLVED_ufixed;  -- fixed point input
1206
    JUSTIFIED : in    SIDE  := right;
1207
    FIELD     : in    WIDTH := 0);
1208
 
1209
  -- purpose: writes fixed point into a line
1210
  procedure HWRITE (
1211
    L         : inout LINE;               -- input line
1212
    VALUE     : in    UNRESOLVED_sfixed;  -- fixed point input
1213
    JUSTIFIED : in    SIDE  := right;
1214
    FIELD     : in    WIDTH := 0);
1215
 
1216
  procedure HREAD(L     : inout LINE;
1217
                  VALUE : out   UNRESOLVED_ufixed);
1218
 
1219
  procedure HREAD(L     : inout LINE;
1220
                  VALUE : out   UNRESOLVED_ufixed;
1221
                  GOOD  : out   BOOLEAN);
1222
 
1223
  procedure HREAD(L     : inout LINE;
1224
                  VALUE : out   UNRESOLVED_sfixed);
1225
 
1226
  procedure HREAD(L     : inout LINE;
1227
                  VALUE : out   UNRESOLVED_sfixed;
1228
                  GOOD  : out   BOOLEAN);
1229
  alias HEX_READ is HREAD [LINE, UNRESOLVED_ufixed, BOOLEAN];
1230
  alias HEX_READ is HREAD [LINE, UNRESOLVED_sfixed, BOOLEAN];
1231
  alias HEX_READ is HREAD [LINE, UNRESOLVED_ufixed];
1232
  alias HEX_READ is HREAD [LINE, UNRESOLVED_sfixed];
1233
  alias HEX_WRITE is HWRITE [LINE, UNRESOLVED_ufixed, SIDE, WIDTH];
1234
  alias HEX_WRITE is HWRITE [LINE, UNRESOLVED_sfixed, SIDE, WIDTH];
1235
 
1236
  -- returns a string, useful for:
1237
  -- assert (x = y) report "error found " & to_string(x) severity error;
1238
  function to_string (value : UNRESOLVED_ufixed) return STRING;
1239
  alias to_bstring is to_string [UNRESOLVED_ufixed return STRING];
1240
  alias TO_BINARY_STRING is TO_STRING [UNRESOLVED_ufixed return STRING];
1241
 
1242
  function to_ostring (value : UNRESOLVED_ufixed) return STRING;
1243
  alias TO_OCTAL_STRING is TO_OSTRING [UNRESOLVED_ufixed return STRING];
1244
 
1245
  function to_hstring (value : UNRESOLVED_ufixed) return STRING;
1246
  alias TO_HEX_STRING is TO_HSTRING [UNRESOLVED_ufixed return STRING];
1247
 
1248
  function to_string (value : UNRESOLVED_sfixed) return STRING;
1249
  alias to_bstring is to_string [UNRESOLVED_sfixed return STRING];
1250
  alias TO_BINARY_STRING is TO_STRING [UNRESOLVED_sfixed return STRING];
1251
 
1252
  function to_ostring (value : UNRESOLVED_sfixed) return STRING;
1253
  alias TO_OCTAL_STRING is TO_OSTRING [UNRESOLVED_sfixed return STRING];
1254
 
1255
  function to_hstring (value : UNRESOLVED_sfixed) return STRING;
1256
  alias TO_HEX_STRING is TO_HSTRING [UNRESOLVED_sfixed return STRING];
1257
 
1258
  -- From string functions allow you to convert a string into a fixed
1259
  -- point number.  Example:
1260
  --  signal uf1 : ufixed (3 downto -3);
1261
  --  uf1 <= from_string ("0110.100", uf1'high, uf1'low); -- 6.5
1262
  -- The "." is optional in this syntax, however it exist and is
1263
  -- in the wrong location an error is produced.  Overflow will
1264
  -- result in saturation.
1265
 
1266
  function from_string (
1267
    bstring              : STRING;      -- binary string
1268
    constant left_index  : INTEGER;
1269
    constant right_index : INTEGER)
1270
    return UNRESOLVED_ufixed;
1271
  alias from_bstring is from_string [STRING, INTEGER, INTEGER
1272
                                     return UNRESOLVED_ufixed];
1273
  alias from_binary_string is from_string [STRING, INTEGER, INTEGER
1274
                                           return UNRESOLVED_ufixed];
1275
 
1276
  -- Octal and hex conversions work as follows:
1277
  -- uf1 <= from_hstring ("6.8", 3, -3); -- 6.5 (bottom zeros dropped)
1278
  -- uf1 <= from_ostring ("06.4", 3, -3); -- 6.5 (top zeros dropped)
1279
 
1280
  function from_ostring (
1281
    ostring              : STRING;      -- Octal string
1282
    constant left_index  : INTEGER;
1283
    constant right_index : INTEGER)
1284
    return UNRESOLVED_ufixed;
1285
  alias from_octal_string is from_ostring [STRING, INTEGER, INTEGER
1286
                                           return UNRESOLVED_ufixed];
1287
 
1288
  function from_hstring (
1289
    hstring              : STRING;      -- hex string
1290
    constant left_index  : INTEGER;
1291
    constant right_index : INTEGER)
1292
    return UNRESOLVED_ufixed;
1293
  alias from_hex_string is from_hstring [STRING, INTEGER, INTEGER
1294
                                         return UNRESOLVED_ufixed];
1295
 
1296
  function from_string (
1297
    bstring              : STRING;      -- binary string
1298
    constant left_index  : INTEGER;
1299
    constant right_index : INTEGER)
1300
    return UNRESOLVED_sfixed;
1301
  alias from_bstring is from_string [STRING, INTEGER, INTEGER
1302
                                     return UNRESOLVED_sfixed];
1303
  alias from_binary_string is from_string [STRING, INTEGER, INTEGER
1304
                                           return UNRESOLVED_sfixed];
1305
 
1306
  function from_ostring (
1307
    ostring              : STRING;      -- Octal string
1308
    constant left_index  : INTEGER;
1309
    constant right_index : INTEGER)
1310
    return UNRESOLVED_sfixed;
1311
  alias from_octal_string is from_ostring [STRING, INTEGER, INTEGER
1312
                                           return UNRESOLVED_sfixed];
1313
 
1314
  function from_hstring (
1315
    hstring              : STRING;      -- hex string
1316
    constant left_index  : INTEGER;
1317
    constant right_index : INTEGER)
1318
    return UNRESOLVED_sfixed;
1319
  alias from_hex_string is from_hstring [STRING, INTEGER, INTEGER
1320
                                         return UNRESOLVED_sfixed];
1321
 
1322
  -- Same as above, "size_res" is used for it's range only.
1323
  function from_string (
1324
    bstring  : STRING;                  -- binary string
1325
    size_res : UNRESOLVED_ufixed)
1326
    return UNRESOLVED_ufixed;
1327
  alias from_bstring is from_string [STRING, UNRESOLVED_ufixed
1328
                                     return UNRESOLVED_ufixed];
1329
  alias from_binary_string is from_string [STRING, UNRESOLVED_ufixed
1330
                                           return UNRESOLVED_ufixed];
1331
 
1332
  function from_ostring (
1333
    ostring  : STRING;                  -- Octal string
1334
    size_res : UNRESOLVED_ufixed)
1335
    return UNRESOLVED_ufixed;
1336
  alias from_octal_string is from_ostring [STRING, UNRESOLVED_ufixed
1337
                                           return UNRESOLVED_ufixed];
1338
 
1339
  function from_hstring (
1340
    hstring  : STRING;                  -- hex string
1341
    size_res : UNRESOLVED_ufixed)
1342
    return UNRESOLVED_ufixed;
1343
  alias from_hex_string is from_hstring [STRING, UNRESOLVED_ufixed
1344
                                         return UNRESOLVED_ufixed];
1345
 
1346
  function from_string (
1347
    bstring  : STRING;                  -- binary string
1348
    size_res : UNRESOLVED_sfixed)
1349
    return UNRESOLVED_sfixed;
1350
  alias from_bstring is from_string [STRING, UNRESOLVED_sfixed
1351
                                     return UNRESOLVED_sfixed];
1352
  alias from_binary_string is from_string [STRING, UNRESOLVED_sfixed
1353
                                           return UNRESOLVED_sfixed];
1354
 
1355
  function from_ostring (
1356
    ostring  : STRING;                  -- Octal string
1357
    size_res : UNRESOLVED_sfixed)
1358
    return UNRESOLVED_sfixed;
1359
  alias from_octal_string is from_ostring [STRING, UNRESOLVED_sfixed
1360
                                           return UNRESOLVED_sfixed];
1361
 
1362
  function from_hstring (
1363
    hstring  : STRING;                  -- hex string
1364
    size_res : UNRESOLVED_sfixed)
1365
    return UNRESOLVED_sfixed;
1366
  alias from_hex_string is from_hstring [STRING, UNRESOLVED_sfixed
1367
                                         return UNRESOLVED_sfixed];
1368
 
1369
  -- Direct conversion functions.  Example:
1370
  --  signal uf1 : ufixed (3 downto -3);
1371
  --  uf1 <= from_string ("0110.100"); -- 6.5
1372
  -- In this case the "." is not optional, and the size of
1373
  -- the output must match exactly.
1374
 
1375
  function from_string (
1376
    bstring : STRING)                   -- binary string
1377
    return UNRESOLVED_ufixed;
1378
  alias from_bstring is from_string [STRING return UNRESOLVED_ufixed];
1379
  alias from_binary_string is from_string [STRING return UNRESOLVED_ufixed];
1380
 
1381
  -- Direct octal and hex conversion functions.  In this case
1382
  -- the string lengths must match.  Example:
1383
  -- signal sf1 := sfixed (5 downto -3);
1384
  -- sf1 <= from_ostring ("71.4") -- -6.5
1385
 
1386
  function from_ostring (
1387
    ostring : STRING)                   -- Octal string
1388
    return UNRESOLVED_ufixed;
1389
  alias from_octal_string is from_ostring [STRING return UNRESOLVED_ufixed];
1390
 
1391
  function from_hstring (
1392
    hstring : STRING)                   -- hex string
1393
    return UNRESOLVED_ufixed;
1394
  alias from_hex_string is from_hstring [STRING return UNRESOLVED_ufixed];
1395
 
1396
  function from_string (
1397
    bstring : STRING)                   -- binary string
1398
    return UNRESOLVED_sfixed;
1399
  alias from_bstring is from_string [STRING return UNRESOLVED_sfixed];
1400
  alias from_binary_string is from_string [STRING return UNRESOLVED_sfixed];
1401
 
1402
  function from_ostring (
1403
    ostring : STRING)                   -- Octal string
1404
    return UNRESOLVED_sfixed;
1405
  alias from_octal_string is from_ostring [STRING return UNRESOLVED_sfixed];
1406
 
1407
  function from_hstring (
1408
    hstring : STRING)                   -- hex string
1409
    return UNRESOLVED_sfixed;
1410
  alias from_hex_string is from_hstring [STRING return UNRESOLVED_sfixed];
1411
-- rtl_synthesis on
1412
-- pragma synthesis_on
1413
 
1414
  -- IN VHDL-2006 std_logic_vector is a subtype of std_ulogic_vector, so these
1415
  -- extra functions are needed for compatability.
1416
  function to_ufixed (
1417
    arg                  : STD_LOGIC_VECTOR;  -- shifted vector
1418
    constant left_index  : INTEGER;
1419
    constant right_index : INTEGER)
1420
    return UNRESOLVED_ufixed;
1421
 
1422
  function to_ufixed (
1423
    arg      : STD_LOGIC_VECTOR;       -- shifted vector
1424
    size_res : UNRESOLVED_ufixed)       -- for size only
1425
    return UNRESOLVED_ufixed;
1426
 
1427
  function to_sfixed (
1428
    arg                  : STD_LOGIC_VECTOR;  -- shifted vector
1429
    constant left_index  : INTEGER;
1430
    constant right_index : INTEGER)
1431
    return UNRESOLVED_sfixed;
1432
 
1433
  function to_sfixed (
1434
    arg      : STD_LOGIC_VECTOR;       -- shifted vector
1435
    size_res : UNRESOLVED_sfixed)       -- for size only
1436
    return UNRESOLVED_sfixed;
1437
 
1438
  -- unsigned fixed point
1439
  function to_UFix (
1440
    arg      : STD_LOGIC_VECTOR;
1441
    width    : NATURAL;                 -- width of vector
1442
    fraction : NATURAL)                 -- width of fraction
1443
    return UNRESOLVED_ufixed;
1444
 
1445
  -- signed fixed point
1446
  function to_SFix (
1447
    arg      : STD_LOGIC_VECTOR;
1448
    width    : NATURAL;                 -- width of vector
1449
    fraction : NATURAL)                 -- width of fraction
1450
    return UNRESOLVED_sfixed;
1451
 
1452
end package fixed_pkg;
1453
-------------------------------------------------------------------------------
1454
-- Proposed package body for the VHDL-200x-FT fixed_pkg package
1455
-- (Fixed point math package)
1456
-- This package body supplies a recommended implementation of these functions
1457
-- Version    : $Revision: 1.21 $
1458
-- Date       : $Date: 2007/09/26 18:08:53 $
1459
--
1460
--  Created for VHDL-200X-ft, David Bishop (dbishop@vhdl.org)
1461
-------------------------------------------------------------------------------
1462
library IEEE;
1463
use IEEE.MATH_REAL.all;
1464
 
1465
package body fixed_pkg is
1466
  -- Author David Bishop (dbishop@vhdl.org)
1467
  -- Other contributers: Jim Lewis, Yannick Grugni, Ryan W. Hilton
1468
  -- null array constants
1469
  constant NAUF : UNRESOLVED_ufixed (0 downto 1) := (others => '0');
1470
  constant NASF : UNRESOLVED_sfixed (0 downto 1) := (others => '0');
1471
  constant NSLV : STD_ULOGIC_VECTOR (0 downto 1) := (others => '0');
1472
 
1473
  -- This differed constant will tell you if the package body is synthesizable
1474
  -- or implemented as real numbers, set to "true" if synthesizable.
1475
  constant fixedsynth_or_real : BOOLEAN := true;
1476
 
1477
  -- %%% Replicated functions
1478
  function maximum (
1479
    l, r : integer)                    -- inputs
1480
    return integer is
1481
  begin  -- function max
1482
    if l > r then return l;
1483
    else return r;
1484
    end if;
1485
  end function maximum;
1486
 
1487
  function minimum (
1488
    l, r : integer)                    -- inputs
1489
    return integer is
1490
  begin  -- function min
1491
    if l > r then return r;
1492
    else return l;
1493
    end if;
1494
  end function minimum;
1495
 
1496
  function "sra" (arg : SIGNED; count : INTEGER)
1497
    return SIGNED is
1498
  begin
1499
    if (COUNT >= 0) then
1500
      return SHIFT_RIGHT(arg, count);
1501
    else
1502
      return SHIFT_LEFT(arg, -count);
1503
    end if;
1504
  end function "sra";
1505
 
1506
  function or_reduce (arg : STD_ULOGIC_VECTOR)
1507
    return STD_LOGIC is
1508
    variable Upper, Lower : STD_ULOGIC;
1509
    variable Half         : INTEGER;
1510
    variable BUS_int      : STD_ULOGIC_VECTOR (arg'length - 1 downto 0);
1511
    variable Result       : STD_ULOGIC;
1512
  begin
1513
    if (arg'length < 1) then            -- In the case of a NULL range
1514
      Result := '0';
1515
    else
1516
      BUS_int := to_ux01 (arg);
1517
      if (BUS_int'length = 1) then
1518
        Result := BUS_int (BUS_int'left);
1519
      elsif (BUS_int'length = 2) then
1520
        Result := BUS_int (BUS_int'right) or BUS_int (BUS_int'left);
1521
      else
1522
        Half   := (BUS_int'length + 1) / 2 + BUS_int'right;
1523
        Upper  := or_reduce (BUS_int (BUS_int'left downto Half));
1524
        Lower  := or_reduce (BUS_int (Half - 1 downto BUS_int'right));
1525
        Result := Upper or Lower;
1526
      end if;
1527
    end if;
1528
    return Result;
1529
  end function or_reduce;
1530
 
1531
  -- purpose: AND all of the bits in a vector together
1532
  -- This is a copy of the proposed "and_reduce" from 1076.3
1533
  function and_reduce (arg : STD_ULOGIC_VECTOR)
1534
    return STD_LOGIC is
1535
    variable Upper, Lower : STD_ULOGIC;
1536
    variable Half         : INTEGER;
1537
    variable BUS_int      : STD_ULOGIC_VECTOR (arg'length - 1 downto 0);
1538
    variable Result       : STD_ULOGIC;
1539
  begin
1540
    if (arg'length < 1) then            -- In the case of a NULL range
1541
      Result := '1';
1542
    else
1543
      BUS_int := to_ux01 (arg);
1544
      if (BUS_int'length = 1) then
1545
        Result := BUS_int (BUS_int'left);
1546
      elsif (BUS_int'length = 2) then
1547
        Result := BUS_int (BUS_int'right) and BUS_int (BUS_int'left);
1548
      else
1549
        Half   := (BUS_int'length + 1) / 2 + BUS_int'right;
1550
        Upper  := and_reduce (BUS_int (BUS_int'left downto Half));
1551
        Lower  := and_reduce (BUS_int (Half - 1 downto BUS_int'right));
1552
        Result := Upper and Lower;
1553
      end if;
1554
    end if;
1555
    return Result;
1556
  end function and_reduce;
1557
 
1558
  function xor_reduce (arg : STD_ULOGIC_VECTOR) return STD_ULOGIC is
1559
    variable Upper, Lower : STD_ULOGIC;
1560
    variable Half         : INTEGER;
1561
    variable BUS_int      : STD_ULOGIC_VECTOR (arg'length - 1 downto 0);
1562
    variable Result       : STD_ULOGIC := '0';  -- In the case of a NULL range
1563
  begin
1564
    if (arg'length >= 1) then
1565
      BUS_int := to_ux01 (arg);
1566
      if (BUS_int'length = 1) then
1567
        Result := BUS_int (BUS_int'left);
1568
      elsif (BUS_int'length = 2) then
1569
        Result := BUS_int(BUS_int'right) xor BUS_int(BUS_int'left);
1570
      else
1571
        Half   := (BUS_int'length + 1) / 2 + BUS_int'right;
1572
        Upper  := xor_reduce (BUS_int (BUS_int'left downto Half));
1573
        Lower  := xor_reduce (BUS_int (Half - 1 downto BUS_int'right));
1574
        Result := Upper xor Lower;
1575
      end if;
1576
    end if;
1577
    return Result;
1578
  end function xor_reduce;
1579
 
1580
  function nand_reduce(arg : std_ulogic_vector) return STD_ULOGIC is
1581
  begin
1582
    return not and_reduce (arg);
1583
  end function nand_reduce;
1584
  function nor_reduce(arg : std_ulogic_vector) return STD_ULOGIC is
1585
  begin
1586
    return not or_reduce (arg);
1587
  end function nor_reduce;
1588
  function xnor_reduce(arg : std_ulogic_vector) return STD_ULOGIC is
1589
  begin
1590
    return not xor_reduce (arg);
1591
  end function xnor_reduce;
1592
  -- Match table, copied form new std_logic_1164
1593
--  type stdlogic_table is array(STD_ULOGIC, STD_ULOGIC) of STD_ULOGIC;
1594
--  constant match_logic_table : stdlogic_table := (
1595
--    -----------------------------------------------------
1596
--    -- U    X    0    1    Z    W    L    H    -         |   |  
1597
--    -----------------------------------------------------
1598
--    ('U', 'U', 'U', 'U', 'U', 'U', 'U', 'U', '1'),  -- | U |
1599
--    ('U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', '1'),  -- | X |
1600
--    ('U', 'X', '1', '0', 'X', 'X', '1', '0', '1'),  -- | 0 |
1601
--    ('U', 'X', '0', '1', 'X', 'X', '0', '1', '1'),  -- | 1 |
1602
--    ('U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', '1'),  -- | Z |
1603
--    ('U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', '1'),  -- | W |
1604
--    ('U', 'X', '1', '0', 'X', 'X', '1', '0', '1'),  -- | L |
1605
--    ('U', 'X', '0', '1', 'X', 'X', '0', '1', '1'),  -- | H |
1606
--    ('1', '1', '1', '1', '1', '1', '1', '1', '1')   -- | - |
1607
--    );
1608
 
1609
--  constant no_match_logic_table : stdlogic_table := (
1610
--    -----------------------------------------------------
1611
--    -- U    X    0    1    Z    W    L    H    -         |   |  
1612
--    -----------------------------------------------------
1613
--    ('U', 'U', 'U', 'U', 'U', 'U', 'U', 'U', '0'),  -- | U |
1614
--    ('U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', '0'),  -- | X |
1615
--    ('U', 'X', '0', '1', 'X', 'X', '0', '1', '0'),  -- | 0 |
1616
--    ('U', 'X', '1', '0', 'X', 'X', '1', '0', '0'),  -- | 1 |
1617
--    ('U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', '0'),  -- | Z |
1618
--    ('U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', '0'),  -- | W |
1619
--    ('U', 'X', '0', '1', 'X', 'X', '0', '1', '0'),  -- | L |
1620
--    ('U', 'X', '1', '0', 'X', 'X', '1', '0', '0'),  -- | H |
1621
--    ('0', '0', '0', '0', '0', '0', '0', '0', '0')   -- | - |
1622
--    );
1623
 
1624
  -------------------------------------------------------------------
1625
  -- ?= functions, Similar to "std_match", but returns "std_ulogic".
1626
  -------------------------------------------------------------------
1627
  function \?=\ (l, r : STD_ULOGIC) return STD_ULOGIC is
1628
    variable lx, rx : STD_ULOGIC;
1629
  begin
1630
--    return match_logic_table (l, r);
1631
    lx := to_x01(l);
1632
    rx := to_x01(r);
1633
    if lx = 'X' or rx = 'X' then
1634
      return 'X';
1635
    elsif lx = rx then
1636
      return '1';
1637
    else
1638
      return '0';
1639
    end if;
1640
  end function \?=\;
1641
  function \?/=\ (l, r : STD_ULOGIC) return STD_ULOGIC is
1642
  begin
1643
--    return no_match_logic_table (l, r);
1644
    return not \?=\ (l, r);
1645
  end function \?/=\;
1646
  -- "?=" operator is similar to "std_match", but returns a std_ulogic..
1647
  -- Id: M.2B
1648
  function \?=\ (L, R: UNSIGNED) return STD_ULOGIC is
1649
    constant L_LEFT : INTEGER := L'LENGTH-1;
1650
    constant R_LEFT : INTEGER := R'LENGTH-1;
1651
    alias XL        : UNSIGNED(L_LEFT downto 0) is L;
1652
    alias XR        : UNSIGNED(R_LEFT downto 0) is R;
1653
    constant SIZE   : NATURAL := MAXIMUM(L'LENGTH, R'LENGTH);
1654
    variable LX     : UNSIGNED(SIZE-1 downto 0);
1655
    variable RX     : UNSIGNED(SIZE-1 downto 0);
1656
    variable result, result1 : STD_ULOGIC;          -- result
1657
  begin
1658
    -- Logically identical to an "=" operator.
1659
    if ((L'LENGTH < 1) or (R'LENGTH < 1)) then
1660
      assert NO_WARNING
1661
        report "NUMERIC_STD.""?="": null detected, returning X"
1662
        severity warning;
1663
      return 'X';
1664
    else
1665
      LX := RESIZE(XL, SIZE);
1666
      RX := RESIZE(XR, SIZE);
1667
      result := '1';
1668
      for i in LX'low to LX'high loop
1669
        result1 := \?=\(LX(i), RX(i));
1670
        if result1 = 'U' then
1671
          return 'U';
1672
        elsif result1 = 'X' or result = 'X' then
1673
          result := 'X';
1674
        else
1675
          result := result and result1;
1676
        end if;
1677
      end loop;
1678
      return result;
1679
    end if;
1680
  end function \?=\;
1681
 
1682
  -- Id: M.3B
1683
  function \?=\ (L, R: SIGNED) return std_ulogic is
1684
    constant L_LEFT : INTEGER := L'LENGTH-1;
1685
    constant R_LEFT : INTEGER := R'LENGTH-1;
1686
    alias XL        : SIGNED(L_LEFT downto 0) is L;
1687
    alias XR        : SIGNED(R_LEFT downto 0) is R;
1688
    constant SIZE   : NATURAL := MAXIMUM(L'LENGTH, R'LENGTH);
1689
    variable LX     : SIGNED(SIZE-1 downto 0);
1690
    variable RX     : SIGNED(SIZE-1 downto 0);
1691
    variable result, result1 : STD_ULOGIC;          -- result
1692
  begin                                 -- ?=
1693
    if ((L'LENGTH < 1) or (R'LENGTH < 1)) then
1694
      assert NO_WARNING
1695
        report "NUMERIC_STD.""?="": null detected, returning X"
1696
        severity warning;
1697
      return 'X';
1698
    else
1699
      LX := RESIZE(XL, SIZE);
1700
      RX := RESIZE(XR, SIZE);
1701
      result := '1';
1702
      for i in LX'low to LX'high loop
1703
        result1 := \?=\ (LX(i), RX(i));
1704
        if result1 = 'U' then
1705
          return 'U';
1706
        elsif result1 = 'X' or result = 'X' then
1707
          result := 'X';
1708
        else
1709
          result := result and result1;
1710
        end if;
1711
      end loop;
1712
      return result;
1713
    end if;
1714
  end function \?=\;
1715
 
1716
  function \?/=\ (L, R : UNSIGNED) return std_ulogic is
1717
    constant L_LEFT : INTEGER := L'LENGTH-1;
1718
    constant R_LEFT : INTEGER := R'LENGTH-1;
1719
    alias XL        : UNSIGNED(L_LEFT downto 0) is L;
1720
    alias XR        : UNSIGNED(R_LEFT downto 0) is R;
1721
    constant SIZE   : NATURAL := MAXIMUM(L'LENGTH, R'LENGTH);
1722
    variable LX     : UNSIGNED(SIZE-1 downto 0);
1723
    variable RX     : UNSIGNED(SIZE-1 downto 0);
1724
    variable result, result1 : STD_ULOGIC;             -- result
1725
  begin                                 -- ?=
1726
    if ((L'LENGTH < 1) or (R'LENGTH < 1)) then
1727
      assert NO_WARNING
1728
        report "NUMERIC_STD.""?/="": null detected, returning X"
1729
        severity warning;
1730
      return 'X';
1731
    else
1732
      LX := RESIZE(XL, SIZE);
1733
      RX := RESIZE(XR, SIZE);
1734
      result := '0';
1735
      for i in LX'low to LX'high loop
1736
        result1 := \?/=\ (LX(i), RX(i));
1737
        if result1 = 'U' then
1738
          return 'U';
1739
        elsif result1 = 'X' or result = 'X' then
1740
          result := 'X';
1741
        else
1742
          result := result or result1;
1743
        end if;
1744
      end loop;
1745
      return result;
1746
    end if;
1747
  end function \?/=\;
1748
 
1749
  function \?/=\ (L, R : SIGNED) return std_ulogic is
1750
    constant L_LEFT : INTEGER := L'LENGTH-1;
1751
    constant R_LEFT : INTEGER := R'LENGTH-1;
1752
    alias XL        : SIGNED(L_LEFT downto 0) is L;
1753
    alias XR        : SIGNED(R_LEFT downto 0) is R;
1754
    constant SIZE   : NATURAL := MAXIMUM(L'LENGTH, R'LENGTH);
1755
    variable LX     : SIGNED(SIZE-1 downto 0);
1756
    variable RX     : SIGNED(SIZE-1 downto 0);
1757
    variable result, result1 : STD_ULOGIC;                   -- result
1758
  begin                                 -- ?=
1759
    if ((L'LENGTH < 1) or (R'LENGTH < 1)) then
1760
      assert NO_WARNING
1761
        report "NUMERIC_STD.""?/="": null detected, returning X"
1762
        severity warning;
1763
      return 'X';
1764
    else
1765
      LX := RESIZE(XL, SIZE);
1766
      RX := RESIZE(XR, SIZE);
1767
      result := '0';
1768
      for i in LX'low to LX'high loop
1769
        result1 := \?/=\ (LX(i), RX(i));
1770
        if result1 = 'U' then
1771
          return 'U';
1772
        elsif result1 = 'X' or result = 'X' then
1773
          result := 'X';
1774
        else
1775
          result := result or result1;
1776
        end if;
1777
      end loop;
1778
      return result;
1779
    end if;
1780
  end function \?/=\;
1781
 
1782
  function Is_X ( s : UNSIGNED ) return BOOLEAN is
1783
  begin
1784
    return Is_X (STD_LOGIC_VECTOR (s));
1785
  end function Is_X;
1786
 
1787
  function Is_X ( s : SIGNED ) return BOOLEAN is
1788
  begin
1789
    return Is_X (STD_LOGIC_VECTOR (s));
1790
  end function Is_X;
1791
  function \?>\ (L, R : UNSIGNED) return STD_ULOGIC is
1792
  begin
1793
    if ((l'length < 1) or (r'length < 1)) then
1794
      assert NO_WARNING
1795
        report "NUMERIC_STD.""?>"": null detected, returning X"
1796
        severity warning;
1797
      return 'X';
1798
    else
1799
      for i in L'range loop
1800
        if L(i) = '-' then
1801
          report "NUMERIC_STD.""?>"": '-' found in compare string"
1802
            severity error;
1803
          return 'X';
1804
        end if;
1805
      end loop;
1806
      for i in R'range loop
1807
        if R(i) = '-' then
1808
          report "NUMERIC_STD.""?>"": '-' found in compare string"
1809
            severity error;
1810
          return 'X';
1811
        end if;
1812
      end loop;
1813
      if is_x(l) or is_x(r) then
1814
        return 'X';
1815
      elsif l > r then
1816
        return '1';
1817
      else
1818
        return '0';
1819
      end if;
1820
    end if;
1821
  end function \?>\;
1822
  -- %%% function "?>" (L, R : UNSIGNED) return std_ulogic is
1823
  -- %%% end function "?>"\;
1824
  function \?>\ (L, R : SIGNED) return STD_ULOGIC is
1825
  begin
1826
    if ((l'length < 1) or (r'length < 1)) then
1827
      assert NO_WARNING
1828
        report "NUMERIC_STD.""?>"": null detected, returning X"
1829
        severity warning;
1830
      return 'X';
1831
    else
1832
      for i in L'range loop
1833
        if L(i) = '-' then
1834
          report "NUMERIC_STD.""?>"": '-' found in compare string"
1835
            severity error;
1836
          return 'X';
1837
        end if;
1838
      end loop;
1839
      for i in R'range loop
1840
        if R(i) = '-' then
1841
          report "NUMERIC_STD.""?>"": '-' found in compare string"
1842
            severity error;
1843
          return 'X';
1844
        end if;
1845
      end loop;
1846
      if is_x(l) or is_x(r) then
1847
        return 'X';
1848
      elsif l > r then
1849
        return '1';
1850
      else
1851
        return '0';
1852
      end if;
1853
    end if;
1854
  end function \?>\;
1855
  function \?>=\ (L, R : UNSIGNED) return STD_ULOGIC is
1856
  begin
1857
    if ((l'length < 1) or (r'length < 1)) then
1858
      assert NO_WARNING
1859
        report "NUMERIC_STD.""?>="": null detected, returning X"
1860
        severity warning;
1861
      return 'X';
1862
    else
1863
      for i in L'range loop
1864
        if L(i) = '-' then
1865
          report "NUMERIC_STD.""?>="": '-' found in compare string"
1866
            severity error;
1867
          return 'X';
1868
        end if;
1869
      end loop;
1870
      for i in R'range loop
1871
        if R(i) = '-' then
1872
          report "NUMERIC_STD.""?>="": '-' found in compare string"
1873
            severity error;
1874
          return 'X';
1875
        end if;
1876
      end loop;
1877
      if is_x(l) or is_x(r) then
1878
        return 'X';
1879
      elsif l >= r then
1880
        return '1';
1881
      else
1882
        return '0';
1883
      end if;
1884
    end if;
1885
  end function \?>=\;
1886
  -- %%% function "?>=" (L, R : UNSIGNED) return std_ulogic is
1887
  -- %%% end function "?>=";
1888
  function \?>=\ (L, R : SIGNED) return STD_ULOGIC is
1889
  begin
1890
    if ((l'length < 1) or (r'length < 1)) then
1891
      assert NO_WARNING
1892
        report "NUMERIC_STD.""?>="": null detected, returning X"
1893
        severity warning;
1894
      return 'X';
1895
    else
1896
      for i in L'range loop
1897
        if L(i) = '-' then
1898
          report "NUMERIC_STD.""?>="": '-' found in compare string"
1899
            severity error;
1900
          return 'X';
1901
        end if;
1902
      end loop;
1903
      for i in R'range loop
1904
        if R(i) = '-' then
1905
          report "NUMERIC_STD.""?>="": '-' found in compare string"
1906
            severity error;
1907
          return 'X';
1908
        end if;
1909
      end loop;
1910
      if is_x(l) or is_x(r) then
1911
        return 'X';
1912
      elsif l >= r then
1913
        return '1';
1914
      else
1915
        return '0';
1916
      end if;
1917
    end if;
1918
  end function \?>=\;
1919
  function \?<\ (L, R : UNSIGNED) return STD_ULOGIC is
1920
  begin
1921
    if ((l'length < 1) or (r'length < 1)) then
1922
      assert NO_WARNING
1923
        report "NUMERIC_STD.""?<"": null detected, returning X"
1924
        severity warning;
1925
      return 'X';
1926
    else
1927
      for i in L'range loop
1928
        if L(i) = '-' then
1929
          report "NUMERIC_STD.""?<"": '-' found in compare string"
1930
            severity error;
1931
          return 'X';
1932
        end if;
1933
      end loop;
1934
      for i in R'range loop
1935
        if R(i) = '-' then
1936
          report "NUMERIC_STD.""?<"": '-' found in compare string"
1937
            severity error;
1938
          return 'X';
1939
        end if;
1940
      end loop;
1941
      if is_x(l) or is_x(r) then
1942
        return 'X';
1943
      elsif l < r then
1944
        return '1';
1945
      else
1946
        return '0';
1947
      end if;
1948
    end if;
1949
  end function \?<\;
1950
  -- %%% function "?<" (L, R : UNSIGNED) return std_ulogic is
1951
  -- %%% end function "?<";
1952
  function \?<\ (L, R : SIGNED) return STD_ULOGIC is
1953
  begin
1954
    if ((l'length < 1) or (r'length < 1)) then
1955
      assert NO_WARNING
1956
        report "NUMERIC_STD.""?<"": null detected, returning X"
1957
        severity warning;
1958
      return 'X';
1959
    else
1960
      for i in L'range loop
1961
        if L(i) = '-' then
1962
          report "NUMERIC_STD.""?<"": '-' found in compare string"
1963
            severity error;
1964
          return 'X';
1965
        end if;
1966
      end loop;
1967
      for i in R'range loop
1968
        if R(i) = '-' then
1969
          report "NUMERIC_STD.""?<"": '-' found in compare string"
1970
            severity error;
1971
          return 'X';
1972
        end if;
1973
      end loop;
1974
      if is_x(l) or is_x(r) then
1975
        return 'X';
1976
      elsif l < r then
1977
        return '1';
1978
      else
1979
        return '0';
1980
      end if;
1981
    end if;
1982
  end function \?<\;
1983
  function \?<=\ (L, R : UNSIGNED) return STD_ULOGIC is
1984
  begin
1985
    if ((l'length < 1) or (r'length < 1)) then
1986
      assert NO_WARNING
1987
        report "NUMERIC_STD.""?<="": null detected, returning X"
1988
        severity warning;
1989
      return 'X';
1990
    else
1991
      for i in L'range loop
1992
        if L(i) = '-' then
1993
          report "NUMERIC_STD.""?<="": '-' found in compare string"
1994
            severity error;
1995
          return 'X';
1996
        end if;
1997
      end loop;
1998
      for i in R'range loop
1999
        if R(i) = '-' then
2000
          report "NUMERIC_STD.""?<="": '-' found in compare string"
2001
            severity error;
2002
          return 'X';
2003
        end if;
2004
      end loop;
2005
      if is_x(l) or is_x(r) then
2006
        return 'X';
2007
      elsif l <= r then
2008
        return '1';
2009
      else
2010
        return '0';
2011
      end if;
2012
    end if;
2013
  end function \?<=\;
2014
  -- %%% function "?<=" (L, R : UNSIGNED) return std_ulogic is
2015
  -- %%% end function "?<=";
2016
  function \?<=\ (L, R : SIGNED) return STD_ULOGIC is
2017
  begin
2018
    if ((l'length < 1) or (r'length < 1)) then
2019
      assert NO_WARNING
2020
        report "NUMERIC_STD.""?<="": null detected, returning X"
2021
        severity warning;
2022
      return 'X';
2023
    else
2024
      for i in L'range loop
2025
        if L(i) = '-' then
2026
          report "NUMERIC_STD.""?<="": '-' found in compare string"
2027
            severity error;
2028
          return 'X';
2029
        end if;
2030
      end loop;
2031
      for i in R'range loop
2032
        if R(i) = '-' then
2033
          report "NUMERIC_STD.""?<="": '-' found in compare string"
2034
            severity error;
2035
          return 'X';
2036
        end if;
2037
      end loop;
2038
      if is_x(l) or is_x(r) then
2039
        return 'X';
2040
      elsif l <= r then
2041
        return '1';
2042
      else
2043
        return '0';
2044
      end if;
2045
    end if;
2046
  end function \?<=\;
2047
 
2048
-- %%% END replicated functions
2049
  -- Special version of "minimum" to do some boundary checking without errors
2050
  function mins (l, r : INTEGER)
2051
    return INTEGER is
2052
  begin  -- function mins
2053
    if (L = INTEGER'low or R = INTEGER'low) then
2054
      return 0;                         -- error condition, silent
2055
    end if;
2056
    return minimum (L, R);
2057
  end function mins;
2058
 
2059
  -- Special version of "minimum" to do some boundary checking with errors
2060
  function mine (l, r : INTEGER)
2061
    return INTEGER is
2062
  begin  -- function mine
2063
    if (L = INTEGER'low or R = INTEGER'low) then
2064
      report "fixed_pkg:"
2065
        & " Unbounded number passed, was a literal used?"
2066
        severity error;
2067
      return 0;
2068
    end if;
2069
    return minimum (L, R);
2070
  end function mine;
2071
 
2072
  -- The following functions are used only internally.  Every function
2073
  -- calls "cleanvec" either directly or indirectly.
2074
  -- purpose: Fixes "downto" problem and resolves meta states
2075
  function cleanvec (
2076
    arg : UNRESOLVED_sfixed)            -- input
2077
    return UNRESOLVED_sfixed is
2078
    constant left_index  : INTEGER := maximum(arg'left, arg'right);
2079
    constant right_index : INTEGER := mins(arg'left, arg'right);
2080
    variable result      : UNRESOLVED_sfixed (arg'range);
2081
  begin  -- function cleanvec
2082
    assert not (arg'ascending and (arg'low /= INTEGER'low))
2083
      report "fixed_pkg:"
2084
      & " Vector passed using a ""to"" range, expected is ""downto"""
2085
      severity error;
2086
    return arg;
2087
  end function cleanvec;
2088
 
2089
  -- purpose: Fixes "downto" problem and resolves meta states
2090
  function cleanvec (
2091
    arg : UNRESOLVED_ufixed)            -- input
2092
    return UNRESOLVED_ufixed is
2093
    constant left_index  : INTEGER := maximum(arg'left, arg'right);
2094
    constant right_index : INTEGER := mins(arg'left, arg'right);
2095
    variable result      : UNRESOLVED_ufixed (arg'range);
2096
  begin  -- function cleanvec
2097
    assert not (arg'ascending and (arg'low /= INTEGER'low))
2098
      report "fixed_pkg:"
2099
      & " Vector passed using a ""to"" range, expected is ""downto"""
2100
      severity error;
2101
    return arg;
2102
  end function cleanvec;
2103
 
2104
  -- Type convert a "unsigned" into a "ufixed", used internally
2105
  function to_fixed (
2106
    arg                  : UNSIGNED;  -- shifted vector
2107
    constant left_index  : INTEGER;
2108
    constant right_index : INTEGER)
2109
    return UNRESOLVED_ufixed is
2110
    variable result : UNRESOLVED_ufixed (left_index downto right_index);
2111
  begin  -- function to_fixed
2112
    result := UNRESOLVED_ufixed(arg);
2113
    return result;
2114
  end function to_fixed;
2115
 
2116
  -- Type convert a "signed" into an "sfixed", used internally
2117
  function to_fixed (
2118
    arg                  : SIGNED;  -- shifted vector
2119
    constant left_index  : INTEGER;
2120
    constant right_index : INTEGER)
2121
    return UNRESOLVED_sfixed is
2122
    variable result : UNRESOLVED_sfixed (left_index downto right_index);
2123
  begin  -- function to_fixed
2124
    result := UNRESOLVED_sfixed(arg);
2125
    return result;
2126
  end function to_fixed;
2127
 
2128
  -- Type convert a "ufixed" into an "unsigned", used internally
2129
  function to_uns (
2130
    arg : UNRESOLVED_ufixed)            -- fp vector
2131
    return UNSIGNED is
2132
    subtype t is UNSIGNED(arg'high - arg'low downto 0);
2133
    variable slv : t;
2134
  begin  -- function to_uns
2135
    slv := t(arg);
2136
    return slv;
2137
  end function to_uns;
2138
 
2139
  -- Type convert an "sfixed" into a "signed", used internally
2140
  function to_s (
2141
    arg : UNRESOLVED_sfixed)            -- fp vector
2142
    return SIGNED is
2143
    subtype t is SIGNED(arg'high - arg'low downto 0);
2144
    variable slv : t;
2145
  begin  -- function to_s
2146
    slv := t(arg);
2147
    return slv;
2148
  end function to_s;
2149
 
2150
  -- adds 1 to the LSB of the number
2151
  procedure round_up (arg       : in  UNRESOLVED_ufixed;
2152
                      result    : out UNRESOLVED_ufixed;
2153
                      overflowx : out BOOLEAN) is
2154
    variable arguns, resuns : UNSIGNED (arg'high-arg'low+1 downto 0)
2155
      := (others => '0');
2156
  begin  -- round_up
2157
    arguns (arguns'high-1 downto 0) := to_uns (arg);
2158
    resuns                          := arguns + 1;
2159
    result := to_fixed(resuns(arg'high-arg'low
2160
                              downto 0), arg'high, arg'low);
2161
    overflowx := (resuns(resuns'high) = '1');
2162
  end procedure round_up;
2163
 
2164
  -- adds 1 to the LSB of the number
2165
  procedure round_up (arg       : in  UNRESOLVED_sfixed;
2166
                      result    : out UNRESOLVED_sfixed;
2167
                      overflowx : out BOOLEAN) is
2168
    variable args, ress : SIGNED (arg'high-arg'low+1 downto 0);
2169
  begin  -- round_up
2170
    args (args'high-1 downto 0) := to_s (arg);
2171
    args(args'high)             := arg(arg'high);  -- sign extend
2172
    ress                        := args + 1;
2173
    result := to_fixed(ress (ress'high-1
2174
                             downto 0), arg'high, arg'low);
2175
    overflowx := ((arg(arg'high) /= ress(ress'high-1))
2176
                  and (or_reduce (STD_ULOGIC_VECTOR(ress)) /= '0'));
2177
  end procedure round_up;
2178
 
2179
  -- Rounding - Performs a "round_nearest" (IEEE 754) which rounds up
2180
  -- when the remainder is > 0.5.  If the remainder IS 0.5 then if the
2181
  -- bottom bit is a "1" it is rounded, otherwise it remains the same.
2182
  function round_fixed (arg            : UNRESOLVED_ufixed;
2183
                        remainder      : UNRESOLVED_ufixed;
2184
                        overflow_style : fixed_overflow_style_type := fixed_overflow_style)
2185
    return UNRESOLVED_ufixed is
2186
    variable rounds         : BOOLEAN;
2187
    variable round_overflow : BOOLEAN;
2188
    variable result         : UNRESOLVED_ufixed (arg'range);
2189
  begin
2190
    rounds := false;
2191
    if (remainder'length > 1) then
2192
      if (remainder (remainder'high) = '1') then
2193
        rounds := (arg(arg'low) = '1')
2194
                  or (or_reduce (to_sulv(remainder(remainder'high-1 downto
2195
                                                  remainder'low))) = '1');
2196
      end if;
2197
    else
2198
      rounds := (arg(arg'low) = '1') and (remainder (remainder'high) = '1');
2199
    end if;
2200
    if rounds then
2201
      round_up(arg       => arg,
2202
               result    => result,
2203
               overflowx => round_overflow);
2204
    else
2205
      result := arg;
2206
    end if;
2207
    if (overflow_style = fixed_saturate) and round_overflow then
2208
      result := saturate (result'high, result'low);
2209
    end if;
2210
    return result;
2211
  end function round_fixed;
2212
 
2213
  -- Rounding case statement
2214
  function round_fixed (arg            : UNRESOLVED_sfixed;
2215
                        remainder      : UNRESOLVED_sfixed;
2216
                        overflow_style : fixed_overflow_style_type := fixed_overflow_style)
2217
    return UNRESOLVED_sfixed is
2218
    variable rounds         : BOOLEAN;
2219
    variable round_overflow : BOOLEAN;
2220
    variable result         : UNRESOLVED_sfixed (arg'range);
2221
  begin
2222
    rounds := false;
2223
    if (remainder'length > 1) then
2224
      if (remainder (remainder'high) = '1') then
2225
        rounds := (arg(arg'low) = '1')
2226
                  or (or_reduce (to_sulv(remainder(remainder'high-1 downto
2227
                                                  remainder'low))) = '1');
2228
      end if;
2229
    else
2230
      rounds := (arg(arg'low) = '1') and (remainder (remainder'high) = '1');
2231
    end if;
2232
    if rounds then
2233
      round_up(arg       => arg,
2234
               result    => result,
2235
               overflowx => round_overflow);
2236
    else
2237
      result := arg;
2238
    end if;
2239
    if round_overflow then
2240
      if (overflow_style = fixed_saturate) then
2241
        if arg(arg'high) = '0' then
2242
          result := saturate (result'high, result'low);
2243
        else
2244
          result := not saturate (result'high, result'low);
2245
        end if;
2246
        -- Sign bit not fixed when wrapping
2247
      end if;
2248
    end if;
2249
    return result;
2250
  end function round_fixed;
2251
 
2252
  -- converts an sfixed into a ufixed.  The output is the same length as the
2253
  -- input, because abs("1000") = "1000" = 8.
2254
  function to_ufixed (
2255
    arg : UNRESOLVED_sfixed)
2256
    return UNRESOLVED_ufixed
2257
  is
2258
    constant left_index  : INTEGER := arg'high;
2259
    constant right_index : INTEGER := mine(arg'low, arg'low);
2260
    variable xarg        : UNRESOLVED_sfixed(left_index+1 downto right_index);
2261
    variable result      : UNRESOLVED_ufixed(left_index downto right_index);
2262
  begin
2263
    if arg'length < 1 then
2264
      return NAUF;
2265
    end if;
2266
    xarg   := abs(arg);
2267
    result := UNRESOLVED_ufixed (xarg (left_index downto right_index));
2268
    return result;
2269
  end function to_ufixed;
2270
 
2271
-----------------------------------------------------------------------------
2272
-- Visible functions
2273
-----------------------------------------------------------------------------
2274
 
2275
  -- Conversion functions.  These are needed for synthesis where typically
2276
  -- the only input and output type is a std_logic_vector.
2277
  function to_sulv (
2278
    arg : UNRESOLVED_ufixed)            -- fixed point vector
2279
    return STD_ULOGIC_VECTOR is
2280
    variable result : STD_ULOGIC_VECTOR (arg'length-1 downto 0);
2281
  begin
2282
    if arg'length < 1 then
2283
      return NSLV;
2284
    end if;
2285
    result := STD_ULOGIC_VECTOR (arg);
2286
    return result;
2287
  end function to_sulv;
2288
 
2289
  function to_sulv (
2290
    arg : UNRESOLVED_sfixed)            -- fixed point vector
2291
    return STD_ULOGIC_VECTOR is
2292
    variable result : STD_ULOGIC_VECTOR (arg'length-1 downto 0);
2293
  begin
2294
    if arg'length < 1 then
2295
      return NSLV;
2296
    end if;
2297
    result := STD_ULOGIC_VECTOR (arg);
2298
    return result;
2299
  end function to_sulv;
2300
 
2301
  function to_slv (
2302
    arg : UNRESOLVED_ufixed)            -- fixed point vector
2303
    return STD_LOGIC_VECTOR is
2304
  begin
2305
    return std_logic_vector(to_sulv(arg));
2306
  end function to_slv;
2307
 
2308
  function to_slv (
2309
    arg : UNRESOLVED_sfixed)            -- fixed point vector
2310
    return STD_LOGIC_VECTOR is
2311
  begin
2312
    return std_logic_vector(to_sulv(arg));
2313
  end function to_slv;
2314
 
2315
  function to_ufixed (
2316
    arg                  : STD_ULOGIC_VECTOR;  -- shifted vector
2317
    constant left_index  : INTEGER;
2318
    constant right_index : INTEGER)
2319
    return unresolved_ufixed is
2320
    variable result : UNRESOLVED_ufixed (left_index downto right_index);
2321
  begin
2322
    if (arg'length < 1 or right_index > left_index) then
2323
      return NAUF;
2324
    end if;
2325
    if (arg'length /= result'length) then
2326
      report "fixed_pkg:" & "TO_UFIXED(SLV) "
2327
        & "Vector lengths do not match.  Input length is "
2328
        & INTEGER'image(arg'length) & " and output will be "
2329
        & INTEGER'image(result'length) & " wide."
2330
        severity error;
2331
      return NAUF;
2332
    else
2333
      result := to_fixed (arg         => UNSIGNED(arg),
2334
                          left_index  => left_index,
2335
                          right_index => right_index);
2336
      return result;
2337
    end if;
2338
  end function to_ufixed;
2339
 
2340
  function to_sfixed (
2341
    arg                  : STD_ULOGIC_VECTOR;  -- shifted vector
2342
    constant left_index  : INTEGER;
2343
    constant right_index : INTEGER)
2344
    return unresolved_sfixed is
2345
    variable result : UNRESOLVED_sfixed (left_index downto right_index);
2346
  begin
2347
    if (arg'length < 1 or right_index > left_index) then
2348
      return NASF;
2349
    end if;
2350
    if (arg'length /= result'length) then
2351
      report "fixed_pkg:" & "TO_SFIXED(SLV) "
2352
        & "Vector lengths do not match.  Input length is "
2353
        & INTEGER'image(arg'length) & " and output will be "
2354
        & INTEGER'image(result'length) & " wide."
2355
        severity error;
2356
      return NASF;
2357
    else
2358
      result := to_fixed (arg         => SIGNED(arg),
2359
                          left_index  => left_index,
2360
                          right_index => right_index);
2361
      return result;
2362
    end if;
2363
  end function to_sfixed;
2364
 
2365
  -- Two's complement number, Grows the vector by 1 bit.
2366
  -- because "abs (1000.000) = 01000.000" or abs(-16) = 16.
2367
  function "abs" (
2368
    arg : UNRESOLVED_sfixed)            -- fixed point input
2369
    return UNRESOLVED_sfixed is
2370
    constant left_index  : INTEGER := arg'high;
2371
    constant right_index : INTEGER := mine(arg'low, arg'low);
2372
    variable ressns      : SIGNED (arg'length downto 0);
2373
    variable result      : UNRESOLVED_sfixed (left_index+1 downto right_index);
2374
  begin
2375
    if (arg'length < 1 or result'length < 1) then
2376
      return NASF;
2377
    end if;
2378
    ressns (arg'length-1 downto 0) := to_s (cleanvec (arg));
2379
    ressns (arg'length)            := ressns (arg'length-1);  -- expand sign bit
2380
    result                         := to_fixed (abs(ressns), left_index+1, right_index);
2381
    return result;
2382
  end function "abs";
2383
 
2384
  -- also grows the vector by 1 bit.
2385
  function "-" (
2386
    arg : UNRESOLVED_sfixed)            -- fixed point input
2387
    return UNRESOLVED_sfixed is
2388
    constant left_index  : INTEGER := arg'high+1;
2389
    constant right_index : INTEGER := mine(arg'low, arg'low);
2390
    variable ressns      : SIGNED (arg'length downto 0);
2391
    variable result      : UNRESOLVED_sfixed (left_index downto right_index);
2392
  begin
2393
    if (arg'length < 1 or result'length < 1) then
2394
      return NASF;
2395
    end if;
2396
    ressns (arg'length-1 downto 0) := to_s (cleanvec(arg));
2397
    ressns (arg'length)            := ressns (arg'length-1);  -- expand sign bit
2398
    result                         := to_fixed (-ressns, left_index, right_index);
2399
    return result;
2400
  end function "-";
2401
 
2402
  -- Addition
2403
  function "+" (
2404
    l, r : UNRESOLVED_ufixed)    -- ufixed(a downto b) + ufixed(c downto d) =
2405
    return UNRESOLVED_ufixed is         -- ufixed(max(a,c)+1 downto min(b,d))
2406
    constant left_index       : INTEGER := maximum(l'high, r'high)+1;
2407
    constant right_index      : INTEGER := mine(l'low, r'low);
2408
    variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
2409
    variable result           : UNRESOLVED_ufixed (left_index downto right_index);
2410
    variable lslv, rslv : UNSIGNED (left_index-right_index
2411
                                    downto 0);
2412
    variable result_slv : UNSIGNED (left_index-right_index
2413
                                    downto 0);
2414
  begin
2415
    if (l'length < 1 or r'length < 1 or result'length < 1) then
2416
      return NAUF;
2417
    end if;
2418
    lresize    := resize (l, left_index, right_index);
2419
    rresize    := resize (r, left_index, right_index);
2420
    lslv       := to_uns (lresize);
2421
    rslv       := to_uns (rresize);
2422
    result_slv := lslv + rslv;
2423
    result     := to_fixed(result_slv, left_index, right_index);
2424
    return result;
2425
  end function "+";
2426
 
2427
  function "+" (
2428
    l, r : UNRESOLVED_sfixed)    -- sfixed(a downto b) + sfixed(c downto d) = 
2429
    return UNRESOLVED_sfixed is         -- sfixed(max(a,c)+1 downto min(b,d))
2430
    constant left_index       : INTEGER := maximum(l'high, r'high)+1;
2431
    constant right_index      : INTEGER := mine(l'low, r'low);
2432
    variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
2433
    variable result           : UNRESOLVED_sfixed (left_index downto right_index);
2434
    variable lslv, rslv       : SIGNED (left_index-right_index downto 0);
2435
    variable result_slv       : SIGNED (left_index-right_index downto 0);
2436
  begin
2437
    if (l'length < 1 or r'length < 1 or result'length < 1) then
2438
      return NASF;
2439
    end if;
2440
    lresize    := resize (l, left_index, right_index);
2441
    rresize    := resize (r, left_index, right_index);
2442
    lslv       := to_s (lresize);
2443
    rslv       := to_s (rresize);
2444
    result_slv := lslv + rslv;
2445
    result     := to_fixed(result_slv, left_index, right_index);
2446
    return result;
2447
  end function "+";
2448
 
2449
  -- Subtraction
2450
  function "-" (
2451
    l, r : UNRESOLVED_ufixed)    -- ufixed(a downto b) - ufixed(c downto d) =
2452
    return UNRESOLVED_ufixed is         -- ufixed(max(a,c)+1 downto min(b,d))
2453
    constant left_index       : INTEGER := maximum(l'high, r'high)+1;
2454
    constant right_index      : INTEGER := mine(l'low, r'low);
2455
    variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
2456
    variable result           : UNRESOLVED_ufixed (left_index downto right_index);
2457
    variable lslv, rslv : UNSIGNED (left_index-right_index
2458
                                    downto 0);
2459
    variable result_slv : UNSIGNED (left_index-right_index
2460
                                    downto 0);
2461
  begin
2462
    if (l'length < 1 or r'length < 1 or result'length < 1) then
2463
      return NAUF;
2464
    end if;
2465
    lresize    := resize (l, left_index, right_index);
2466
    rresize    := resize (r, left_index, right_index);
2467
    lslv       := to_uns (lresize);
2468
    rslv       := to_uns (rresize);
2469
    result_slv := lslv - rslv;
2470
    result     := to_fixed(result_slv, left_index, right_index);
2471
    return result;
2472
  end function "-";
2473
 
2474
  function "-" (
2475
    l, r : UNRESOLVED_sfixed)    -- sfixed(a downto b) - sfixed(c downto d) = 
2476
    return UNRESOLVED_sfixed is         -- sfixed(max(a,c)+1 downto min(b,d))
2477
    constant left_index       : INTEGER := maximum(l'high, r'high)+1;
2478
    constant right_index      : INTEGER := mine(l'low, r'low);
2479
    variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
2480
    variable result           : UNRESOLVED_sfixed (left_index downto right_index);
2481
    variable lslv, rslv       : SIGNED (left_index-right_index downto 0);
2482
    variable result_slv       : SIGNED (left_index-right_index downto 0);
2483
  begin
2484
    if (l'length < 1 or r'length < 1 or result'length < 1) then
2485
      return NASF;
2486
    end if;
2487
    lresize    := resize (l, left_index, right_index);
2488
    rresize    := resize (r, left_index, right_index);
2489
    lslv       := to_s (lresize);
2490
    rslv       := to_s (rresize);
2491
    result_slv := lslv - rslv;
2492
    result     := to_fixed(result_slv, left_index, right_index);
2493
    return result;
2494
  end function "-";
2495
 
2496
  function "*" (
2497
    l, r : UNRESOLVED_ufixed)    -- ufixed(a downto b) * ufixed(c downto d) =
2498
    return UNRESOLVED_ufixed is         -- ufixed(a+c+1 downto b+d)
2499
    variable lslv       : UNSIGNED (l'length-1 downto 0);
2500
    variable rslv       : UNSIGNED (r'length-1 downto 0);
2501
    variable result_slv : UNSIGNED (r'length+l'length-1 downto 0);
2502
    variable result     : UNRESOLVED_ufixed (l'high + r'high+1 downto
2503
                                             mine(l'low, l'low) + mine(r'low, r'low));
2504
  begin
2505
    if (l'length < 1 or r'length < 1 or
2506
        result'length /= result_slv'length) then
2507
      return NAUF;
2508
    end if;
2509
    lslv       := to_uns (cleanvec(l));
2510
    rslv       := to_uns (cleanvec(r));
2511
    result_slv := lslv * rslv;
2512
    result     := to_fixed (result_slv, result'high, result'low);
2513
    return result;
2514
  end function "*";
2515
 
2516
  function "*" (
2517
    l, r : UNRESOLVED_sfixed)    -- sfixed(a downto b) * sfixed(c downto d) = 
2518
    return UNRESOLVED_sfixed is         --  sfixed(a+c+1 downto b+d)
2519
    variable lslv       : SIGNED (l'length-1 downto 0);
2520
    variable rslv       : SIGNED (r'length-1 downto 0);
2521
    variable result_slv : SIGNED (r'length+l'length-1 downto 0);
2522
    variable result     : UNRESOLVED_sfixed (l'high + r'high+1 downto
2523
                                             mine(l'low, l'low) + mine(r'low, r'low));
2524
  begin
2525
    if (l'length < 1 or r'length < 1 or
2526
        result'length /= result_slv'length) then
2527
      return NASF;
2528
    end if;
2529
    lslv       := to_s (cleanvec(l));
2530
    rslv       := to_s (cleanvec(r));
2531
    result_slv := lslv * rslv;
2532
    result     := to_fixed (result_slv, result'high, result'low);
2533
    return result;
2534
  end function "*";
2535
 
2536
--  function "/" (
2537
--    l, r : UNRESOLVED_ufixed)    -- ufixed(a downto b) / ufixed(c downto d) = 
2538
--    return UNRESOLVED_ufixed is         --  ufixed(a-d downto b-c-1)
2539
--  begin
2540
--    return divide (l, r);
2541
--  end function "/";
2542
 
2543
--  function "/" (
2544
--    l, r : UNRESOLVED_sfixed)    -- sfixed(a downto b) / sfixed(c downto d) = 
2545
--    return UNRESOLVED_sfixed is         -- sfixed(a-d+1 downto b-c)
2546
--  begin
2547
--    return divide (l, r);
2548
--  end function "/";
2549
 
2550
  -- This version of divide gives the user more control
2551
  -- ufixed(a downto b) / ufixed(c downto d) = ufixed(a-d downto b-c-1)
2552
--  function divide (
2553
--    l, r                 : UNRESOLVED_ufixed;
2554
--    constant round_style : fixed_round_style_type := fixed_round_style;
2555
--    constant guard_bits  : NATURAL                := fixed_guard_bits)
2556
--    return UNRESOLVED_ufixed is
2557
--    variable result : UNRESOLVED_ufixed (l'high - mine(r'low, r'low) downto
2558
--                                         mine (l'low, l'low) - r'high -1);
2559
--    variable dresult    : UNRESOLVED_ufixed (result'high downto result'low -guard_bits);
2560
--    variable lresize    : UNRESOLVED_ufixed (l'high downto l'high - dresult'length+1);
2561
--    variable lslv       : UNSIGNED (lresize'length-1 downto 0);
2562
--    variable rslv       : UNSIGNED (r'length-1 downto 0);
2563
--    variable result_slv : UNSIGNED (lresize'length-1 downto 0);
2564
--  begin
2565
--    if (l'length < 1 or r'length < 1 or
2566
--        mins(r'low, r'low) /= r'low or mins(l'low, l'low) /= l'low) then
2567
--      return NAUF;
2568
--    end if;
2569
--    lresize := resize (arg            => l,
2570
--                       left_index     => lresize'high,
2571
--                       right_index    => lresize'low,
2572
--                       overflow_style => fixed_wrap,   -- vector only grows
2573
--                       round_style    => fixed_truncate);
2574
--    lslv := to_uns (cleanvec (lresize));
2575
--    rslv := to_uns (cleanvec (r));
2576
--    if (rslv = 0) then
2577
--      report "fixed_pkg:"
2578
--        & "DIVIDE(ufixed) Division by zero" severity error;
2579
--      result := saturate (result'high, result'low);    -- saturate
2580
--    else
2581
--      result_slv := lslv / rslv;
2582
--      dresult    := to_fixed (result_slv, dresult'high, dresult'low);
2583
--      result := resize (arg            => dresult,
2584
--                        left_index     => result'high,
2585
--                        right_index    => result'low,
2586
--                        overflow_style => fixed_wrap,  -- overflow impossible
2587
--                        round_style    => round_style);
2588
--    end if;
2589
--    return result;
2590
--  end function divide;
2591
 
2592
  -- sfixed(a downto b) / sfixed(c downto d) = sfixed(a-d+1 downto b-c)
2593
--  function divide (
2594
--    l, r                 : UNRESOLVED_sfixed;
2595
--    constant round_style : fixed_round_style_type := fixed_round_style;
2596
--    constant guard_bits  : NATURAL                := fixed_guard_bits)
2597
--    return UNRESOLVED_sfixed is
2598
--    variable result     : UNRESOLVED_sfixed (l'high - mine(r'low, r'low) + 1 downto 
2599
--                                             mine (l'low, l'low) - r'high);
2600
--    variable dresult    : UNRESOLVED_sfixed (result'high downto result'low-guard_bits);
2601
--    variable lresize    : UNRESOLVED_sfixed (l'high+1 downto l'high+1 -dresult'length+1);
2602
--    variable lslv       : SIGNED (lresize'length-1 downto 0);
2603
--    variable rslv       : SIGNED (r'length-1 downto 0);
2604
--    variable result_slv : SIGNED (lresize'length-1 downto 0);
2605
--  begin
2606
--    if (l'length < 1 or r'length < 1 or
2607
--        mins(r'low, r'low) /= r'low or mins(l'low, l'low) /= l'low) then
2608
--      return NASF;
2609
--    end if;
2610
--    lresize := resize (arg            => l,
2611
--                       left_index     => lresize'high,
2612
--                       right_index    => lresize'low,
2613
--                       overflow_style => fixed_wrap,   -- vector only grows
2614
--                       round_style    => fixed_truncate);
2615
--    lslv := to_s (cleanvec (lresize));
2616
--    rslv := to_s (cleanvec (r));
2617
--    if (rslv = 0) then
2618
--      report "fixed_pkg:"
2619
--        & "DIVIDE(sfixed) Division by zero" severity error;
2620
--      result := saturate (result'high, result'low);
2621
--    else
2622
--      result_slv := lslv / rslv;
2623
--      dresult    := to_fixed (result_slv, dresult'high, dresult'low);
2624
--      result := resize (arg            => dresult,
2625
--                        left_index     => result'high,
2626
--                        right_index    => result'low,
2627
--                        overflow_style => fixed_wrap,  -- overflow impossible
2628
--                        round_style    => round_style);
2629
--    end if;
2630
--    return result;
2631
--  end function divide;
2632
 
2633
  -- 1 / ufixed(a downto b) = ufixed(-b downto -a-1)
2634
--  function reciprocal (
2635
--    arg                  : UNRESOLVED_ufixed;  -- fixed point input
2636
--    constant round_style : fixed_round_style_type := fixed_round_style;
2637
--    constant guard_bits  : NATURAL                := fixed_guard_bits)
2638
--    return UNRESOLVED_ufixed is
2639
--    constant one : UNRESOLVED_ufixed (0 downto 0) := "1";
2640
--  begin
2641
--    return divide (l           => one,
2642
--                   r           => arg,
2643
--                   round_style => round_style,
2644
--                   guard_bits  => guard_bits);
2645
--  end function reciprocal;
2646
 
2647
  -- 1 / sfixed(a downto b) = sfixed(-b+1 downto -a)
2648
--  function reciprocal (
2649
--    arg                  : UNRESOLVED_sfixed;              -- fixed point input
2650
--    constant round_style : fixed_round_style_type := fixed_round_style;
2651
--    constant guard_bits  : NATURAL                := fixed_guard_bits)
2652
--    return UNRESOLVED_sfixed is
2653
--    constant one     : UNRESOLVED_sfixed (1 downto 0) := "01";  -- extra bit.
2654
--    variable resultx : UNRESOLVED_sfixed (-mine(arg'low, arg'low)+2 downto -arg'high);
2655
--  begin
2656
--    if (arg'length < 1 or resultx'length < 1) then
2657
--      return NASF;
2658
--    else
2659
--      resultx := divide (l           => one,
2660
--                         r           => arg,
2661
--                         round_style => round_style,
2662
--                         guard_bits  => guard_bits);
2663
--      return resultx (resultx'high-1 downto resultx'low);  -- remove extra bit
2664
--    end if;
2665
--  end function reciprocal;
2666
 
2667
  -- ufixed (a downto b) rem ufixed (c downto d)
2668
  --        = ufixed (min(a,c) downto min(b,d))
2669
--  function "rem" (
2670
--    l, r : UNRESOLVED_ufixed)           -- fixed point input
2671
--    return UNRESOLVED_ufixed is
2672
--  begin
2673
--    return remainder (l, r);
2674
--  end function "rem";
2675
 
2676
--  -- remainder
2677
--  -- sfixed (a downto b) rem sfixed (c downto d)
2678
--  --        = sfixed (min(a,c) downto min(b,d))
2679
--  function "rem" (
2680
--    l, r : UNRESOLVED_sfixed)           -- fixed point input
2681
--    return UNRESOLVED_sfixed is
2682
--  begin
2683
--    return remainder (l, r);
2684
--  end function "rem";
2685
 
2686
  -- ufixed (a downto b) rem ufixed (c downto d)
2687
  --        = ufixed (min(a,c) downto min(b,d))
2688
--  function remainder (
2689
--    l, r                 : UNRESOLVED_ufixed;            -- fixed point input
2690
--    constant round_style : fixed_round_style_type := fixed_round_style;
2691
--    constant guard_bits  : NATURAL                := fixed_guard_bits)
2692
--    return UNRESOLVED_ufixed is
2693
--    variable result     : UNRESOLVED_ufixed (minimum(l'high, r'high) downto
2694
--                                             mine(l'low, r'low));
2695
--    variable lresize    : UNRESOLVED_ufixed (maximum(l'high, r'low) downto
2696
--                                             mins(r'low, r'low)-guard_bits);
2697
--    variable rresize    : UNRESOLVED_ufixed (r'high downto r'low-guard_bits);
2698
--    variable dresult    : UNRESOLVED_ufixed (rresize'range);
2699
--    variable lslv       : UNSIGNED (lresize'length-1 downto 0);
2700
--    variable rslv       : UNSIGNED (rresize'length-1 downto 0);
2701
--    variable result_slv : UNSIGNED (rslv'range);
2702
--  begin
2703
--    if (l'length < 1 or r'length < 1 or
2704
--        mins(r'low, r'low) /= r'low or mins(l'low, l'low) /= l'low) then
2705
--      return NAUF;
2706
--    end if;
2707
--    lresize := resize (arg            => l,
2708
--                       left_index     => lresize'high,
2709
--                       right_index    => lresize'low,
2710
--                       overflow_style => fixed_wrap,     -- vector only grows
2711
--                       round_style    => fixed_truncate);
2712
--    lslv := to_uns (lresize);
2713
--    rresize := resize (arg            => r,
2714
--                       left_index     => rresize'high,
2715
--                       right_index    => rresize'low,
2716
--                       overflow_style => fixed_wrap,     -- vector only grows
2717
--                       round_style    => fixed_truncate);
2718
--    rslv := to_uns (rresize);
2719
--    if (rslv = 0) then
2720
--      report "fixed_pkg:"
2721
--        & "remainder(ufixed) Division by zero" severity error;
2722
--      result := saturate (result'high, result'low);      -- saturate
2723
--    else
2724
--      if (r'low <= l'high) then
2725
--        result_slv := lslv rem rslv;
2726
--        dresult    := to_fixed (result_slv, dresult'high, dresult'low);
2727
--        result := resize (arg            => dresult,
2728
--                          left_index     => result'high,
2729
--                          right_index    => result'low,
2730
--                          overflow_style => fixed_wrap,  -- can't overflow
2731
--                          round_style    => round_style);
2732
--      end if;
2733
--      if l'low < r'low then
2734
--        result(mins(r'low-1, l'high) downto l'low) :=
2735
--          cleanvec(l(mins(r'low-1, l'high) downto l'low));
2736
--      end if;
2737
--    end if;
2738
--    return result;
2739
--  end function remainder;
2740
 
2741
--  -- remainder
2742
--  -- sfixed (a downto b) rem sfixed (c downto d)
2743
--  --        = sfixed (min(a,c) downto min(b,d))
2744
--  function remainder (
2745
--    l, r                 : UNRESOLVED_sfixed;  -- fixed point input
2746
--    constant round_style : fixed_round_style_type := fixed_round_style;
2747
--    constant guard_bits  : NATURAL                := fixed_guard_bits)
2748
--    return UNRESOLVED_sfixed is
2749
--    variable l_abs      : UNRESOLVED_ufixed (l'range);
2750
--    variable r_abs      : UNRESOLVED_ufixed (r'range);
2751
--    variable result     : UNRESOLVED_sfixed (minimum(r'high, l'high) downto
2752
--                                             mine(r'low, l'low));
2753
--    variable neg_result : UNRESOLVED_sfixed (minimum(r'high, l'high)+1 downto
2754
--                                             mins(r'low, l'low));
2755
--  begin
2756
--    if (l'length < 1 or r'length < 1 or
2757
--        mins(r'low, r'low) /= r'low or mins(l'low, l'low) /= l'low) then
2758
--      return NASF;
2759
--    end if;
2760
--    l_abs := to_ufixed (l);
2761
--    r_abs := to_ufixed (r);
2762
--    result := UNRESOLVED_sfixed (remainder (
2763
--      l           => l_abs,
2764
--      r           => r_abs,
2765
--      round_style => round_style));
2766
--    neg_result := -result;
2767
--    if l(l'high) = '1' then
2768
--      result := neg_result(result'range);
2769
--    end if;
2770
--    return result;
2771
--  end function remainder;
2772
 
2773
--  -- modulo
2774
--  -- ufixed (a downto b) mod ufixed (c downto d)
2775
--  --        = ufixed (min(a,c) downto min(b, d))
2776
--  function "mod" (
2777
--    l, r : UNRESOLVED_ufixed)           -- fixed point input
2778
--    return UNRESOLVED_ufixed is
2779
--  begin
2780
--    return modulo (l, r);
2781
--  end function "mod";
2782
 
2783
--  -- sfixed (a downto b) mod sfixed (c downto d)
2784
--  --        = sfixed (c downto min(b, d))
2785
--  function "mod" (
2786
--    l, r : UNRESOLVED_sfixed)           -- fixed point input
2787
--    return UNRESOLVED_sfixed is
2788
--  begin
2789
--    return modulo(l, r);
2790
--  end function "mod";
2791
 
2792
--  -- modulo
2793
--  -- ufixed (a downto b) mod ufixed (c downto d)
2794
--  --        = ufixed (min(a,c) downto min(b, d))
2795
--  function modulo (
2796
--    l, r                 : UNRESOLVED_ufixed;  -- fixed point input
2797
--    constant round_style : fixed_round_style_type := fixed_round_style;
2798
--    constant guard_bits  : NATURAL                := fixed_guard_bits)
2799
--    return UNRESOLVED_ufixed is
2800
--  begin
2801
--    return remainder(l           => l,
2802
--                     r           => r,
2803
--                     round_style => round_style,
2804
--                     guard_bits  => guard_bits);
2805
--  end function modulo;
2806
 
2807
--  -- sfixed (a downto b) mod sfixed (c downto d)
2808
--  --        = sfixed (c downto min(b, d))
2809
--  function modulo (
2810
--    l, r                    : UNRESOLVED_sfixed;  -- fixed point input
2811
--    constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
2812
--    constant round_style    : fixed_round_style_type    := fixed_round_style;
2813
--    constant guard_bits     : NATURAL                   := fixed_guard_bits)
2814
--    return UNRESOLVED_sfixed is
2815
--    variable l_abs : UNRESOLVED_ufixed (l'range);
2816
--    variable r_abs : UNRESOLVED_ufixed (r'range);
2817
--    variable result : UNRESOLVED_sfixed (r'high downto
2818
--                                         mine(r'low, l'low));
2819
--    variable dresult : UNRESOLVED_sfixed (minimum(r'high, l'high)+1 downto
2820
--                                          mins(r'low, l'low));
2821
--    variable dresult_not_zero : BOOLEAN;
2822
--  begin
2823
--    if (l'length < 1 or r'length < 1 or
2824
--        mins(r'low, r'low) /= r'low or mins(l'low, l'low) /= l'low) then
2825
--      return NASF;
2826
--    end if;
2827
--    l_abs := to_ufixed (l);
2828
--    r_abs := to_ufixed (r);
2829
--    dresult := "0" & UNRESOLVED_sfixed(remainder (l           => l_abs,
2830
--                                                  r           => r_abs,
2831
--                                                  round_style => round_style));
2832
--    if (to_s(dresult) = 0) then
2833
--      dresult_not_zero := false;
2834
--    else
2835
--      dresult_not_zero := true;
2836
--    end if;
2837
--    if to_x01(l(l'high)) = '1' and to_x01(r(r'high)) = '0'
2838
--      and dresult_not_zero then
2839
--      result := resize (arg            => r - dresult,
2840
--                        left_index     => result'high,
2841
--                        right_index    => result'low,
2842
--                        overflow_style => overflow_style,
2843
--                        round_style    => round_style);
2844
--    elsif to_x01(l(l'high)) = '1' and to_x01(r(r'high)) = '1' then
2845
--      result := resize (arg            => -dresult,
2846
--                        left_index     => result'high,
2847
--                        right_index    => result'low,
2848
--                        overflow_style => overflow_style,
2849
--                        round_style    => round_style);
2850
--    elsif to_x01(l(l'high)) = '0' and to_x01(r(r'high)) = '1'
2851
--      and dresult_not_zero then
2852
--      result := resize (arg            => dresult + r,
2853
--                        left_index     => result'high,
2854
--                        right_index    => result'low,
2855
--                        overflow_style => overflow_style,
2856
--                        round_style    => round_style);
2857
--    else
2858
--      result := resize (arg            => dresult,
2859
--                        left_index     => result'high,
2860
--                        right_index    => result'low,
2861
--                        overflow_style => overflow_style,
2862
--                        round_style    => round_style);
2863
--    end if;
2864
--    return result;
2865
--  end function modulo;
2866
 
2867
  -- Procedure for those who need an "accumulator" function
2868
  procedure add_carry (
2869
    L, R   : in  UNRESOLVED_ufixed;
2870
    c_in   : in  STD_ULOGIC;
2871
    result : out UNRESOLVED_ufixed;
2872
    c_out  : out STD_ULOGIC) is
2873
    constant left_index       : INTEGER := maximum(l'high, r'high)+1;
2874
    constant right_index      : INTEGER := mins(l'low, r'low);
2875
    variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
2876
    variable lslv, rslv : UNSIGNED (left_index-right_index
2877
                                    downto 0);
2878
    variable result_slv : UNSIGNED (left_index-right_index
2879
                                    downto 0);
2880
    variable cx : UNSIGNED (0 downto 0);  -- Carry in
2881
  begin
2882
    if (l'length < 1 or r'length < 1) then
2883
      result := NAUF;
2884
      c_out  := '0';
2885
    else
2886
      cx (0)     := c_in;
2887
      lresize    := resize (l, left_index, right_index);
2888
      rresize    := resize (r, left_index, right_index);
2889
      lslv       := to_uns (lresize);
2890
      rslv       := to_uns (rresize);
2891
      result_slv := lslv + rslv + cx;
2892
      c_out      := result_slv(left_index);
2893
      result := to_fixed(result_slv (left_index-right_index-1 downto 0),
2894
                         left_index-1, right_index);
2895
    end if;
2896
  end procedure add_carry;
2897
 
2898
  procedure add_carry (
2899
    L, R   : in  UNRESOLVED_sfixed;
2900
    c_in   : in  STD_ULOGIC;
2901
    result : out UNRESOLVED_sfixed;
2902
    c_out  : out STD_ULOGIC) is
2903
    constant left_index       : INTEGER := maximum(l'high, r'high)+1;
2904
    constant right_index      : INTEGER := mins(l'low, r'low);
2905
    variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
2906
    variable lslv, rslv : SIGNED (left_index-right_index
2907
                                  downto 0);
2908
    variable result_slv : SIGNED (left_index-right_index
2909
                                  downto 0);
2910
    variable cx : SIGNED (1 downto 0);  -- Carry in
2911
  begin
2912
    if (l'length < 1 or r'length < 1) then
2913
      result := NASF;
2914
      c_out  := '0';
2915
    else
2916
      cx (1)     := '0';
2917
      cx (0)     := c_in;
2918
      lresize    := resize (l, left_index, right_index);
2919
      rresize    := resize (r, left_index, right_index);
2920
      lslv       := to_s (lresize);
2921
      rslv       := to_s (rresize);
2922
      result_slv := lslv + rslv + cx;
2923
      c_out      := result_slv(left_index);
2924
      result := to_fixed(result_slv (left_index-right_index-1 downto 0),
2925
                         left_index-1, right_index);
2926
    end if;
2927
  end procedure add_carry;
2928
 
2929
  -- Scales the result by a power of 2.  Width of input = width of output with
2930
  -- the decimal point moved.
2931
  function scalb (y : UNRESOLVED_ufixed; N : INTEGER)
2932
    return UNRESOLVED_ufixed is
2933
    variable result : UNRESOLVED_ufixed (y'high+N downto y'low+N);
2934
  begin
2935
    if y'length < 1 then
2936
      return NAUF;
2937
    else
2938
      result := y;
2939
      return result;
2940
    end if;
2941
  end function scalb;
2942
 
2943
  function scalb (y : UNRESOLVED_ufixed; N : SIGNED)
2944
    return UNRESOLVED_ufixed is
2945
  begin
2946
    return scalb (y => y,
2947
                  N => to_integer(N));
2948
  end function scalb;
2949
 
2950
  function scalb (y : UNRESOLVED_sfixed; N : INTEGER)
2951
    return UNRESOLVED_sfixed is
2952
    variable result : UNRESOLVED_sfixed (y'high+N downto y'low+N);
2953
  begin
2954
    if y'length < 1 then
2955
      return NASF;
2956
    else
2957
      result := y;
2958
      return result;
2959
    end if;
2960
  end function scalb;
2961
 
2962
  function scalb (y : UNRESOLVED_sfixed; N : SIGNED)
2963
    return UNRESOLVED_sfixed is
2964
  begin
2965
    return scalb (y => y,
2966
                  N => to_integer(N));
2967
  end function scalb;
2968
 
2969
  function Is_Negative (arg : UNRESOLVED_sfixed) return BOOLEAN is
2970
  begin
2971
    if to_X01(arg(arg'high)) = '1' then
2972
      return true;
2973
    else
2974
      return false;
2975
    end if;
2976
  end function Is_Negative;
2977
 
2978
  function find_rightmost (arg : UNRESOLVED_ufixed; y : STD_ULOGIC)
2979
    return INTEGER is
2980
  begin
2981
    for_loop : for i in arg'reverse_range loop
2982
      if \?=\ (arg(i), y) = '1' then
2983
        return i;
2984
      end if;
2985
    end loop;
2986
    return arg'high+1;                  -- return out of bounds 'high
2987
  end function find_rightmost;
2988
 
2989
  function find_leftmost (arg : UNRESOLVED_ufixed; y : STD_ULOGIC)
2990
    return INTEGER is
2991
  begin
2992
    for_loop : for i in arg'range loop
2993
      if \?=\ (arg(i), y) = '1' then
2994
        return i;
2995
      end if;
2996
    end loop;
2997
    return arg'low-1;                   -- return out of bounds 'low
2998
  end function find_leftmost;
2999
 
3000
  function find_rightmost (arg : UNRESOLVED_sfixed; y : STD_ULOGIC)
3001
    return INTEGER is
3002
  begin
3003
    for_loop : for i in arg'reverse_range loop
3004
      if \?=\ (arg(i), y) = '1' then
3005
        return i;
3006
      end if;
3007
    end loop;
3008
    return arg'high+1;                  -- return out of bounds 'high
3009
  end function find_rightmost;
3010
 
3011
  function find_leftmost (arg : UNRESOLVED_sfixed; y : STD_ULOGIC)
3012
    return INTEGER is
3013
  begin
3014
    for_loop : for i in arg'range loop
3015
      if \?=\ (arg(i), y) = '1' then
3016
        return i;
3017
      end if;
3018
    end loop;
3019
    return arg'low-1;                   -- return out of bounds 'low
3020
  end function find_leftmost;
3021
 
3022
  function "sll" (ARG : UNRESOLVED_ufixed; COUNT : INTEGER)
3023
    return UNRESOLVED_ufixed is
3024
    variable argslv : UNSIGNED (arg'length-1 downto 0);
3025
    variable result : UNRESOLVED_ufixed (arg'range);
3026
  begin
3027
    argslv := to_uns (arg);
3028
    argslv := argslv sll COUNT;
3029
    result := to_fixed (argslv, result'high, result'low);
3030
    return result;
3031
  end function "sll";
3032
 
3033
  function "srl" (ARG : UNRESOLVED_ufixed; COUNT : INTEGER)
3034
    return UNRESOLVED_ufixed is
3035
    variable argslv : UNSIGNED (arg'length-1 downto 0);
3036
    variable result : UNRESOLVED_ufixed (arg'range);
3037
  begin
3038
    argslv := to_uns (arg);
3039
    argslv := argslv srl COUNT;
3040
    result := to_fixed (argslv, result'high, result'low);
3041
    return result;
3042
  end function "srl";
3043
 
3044
  function "rol" (ARG : UNRESOLVED_ufixed; COUNT : INTEGER)
3045
    return UNRESOLVED_ufixed is
3046
    variable argslv : UNSIGNED (arg'length-1 downto 0);
3047
    variable result : UNRESOLVED_ufixed (arg'range);
3048
  begin
3049
    argslv := to_uns (arg);
3050
    argslv := argslv rol COUNT;
3051
    result := to_fixed (argslv, result'high, result'low);
3052
    return result;
3053
  end function "rol";
3054
 
3055
  function "ror" (ARG : UNRESOLVED_ufixed; COUNT : INTEGER)
3056
    return UNRESOLVED_ufixed is
3057
    variable argslv : UNSIGNED (arg'length-1 downto 0);
3058
    variable result : UNRESOLVED_ufixed (arg'range);
3059
  begin
3060
    argslv := to_uns (arg);
3061
    argslv := argslv ror COUNT;
3062
    result := to_fixed (argslv, result'high, result'low);
3063
    return result;
3064
  end function "ror";
3065
 
3066
  function "sla" (ARG : UNRESOLVED_ufixed; COUNT : INTEGER)
3067
    return UNRESOLVED_ufixed is
3068
    variable argslv : UNSIGNED (arg'length-1 downto 0);
3069
    variable result : UNRESOLVED_ufixed (arg'range);
3070
  begin
3071
    argslv := to_uns (arg);
3072
    -- Arithmetic shift on an unsigned is a logical shift
3073
    argslv := argslv sll COUNT;
3074
    result := to_fixed (argslv, result'high, result'low);
3075
    return result;
3076
  end function "sla";
3077
 
3078
  function "sra" (ARG : UNRESOLVED_ufixed; COUNT : INTEGER)
3079
    return UNRESOLVED_ufixed is
3080
    variable argslv : UNSIGNED (arg'length-1 downto 0);
3081
    variable result : UNRESOLVED_ufixed (arg'range);
3082
  begin
3083
    argslv := to_uns (arg);
3084
    -- Arithmetic shift on an unsigned is a logical shift
3085
    argslv := argslv srl COUNT;
3086
    result := to_fixed (argslv, result'high, result'low);
3087
    return result;
3088
  end function "sra";
3089
 
3090
  function "sll" (ARG : UNRESOLVED_sfixed; COUNT : INTEGER)
3091
    return UNRESOLVED_sfixed is
3092
    variable argslv : SIGNED (arg'length-1 downto 0);
3093
    variable result : UNRESOLVED_sfixed (arg'range);
3094
  begin
3095
    argslv := to_s (arg);
3096
    argslv := argslv sll COUNT;
3097
    result := to_fixed (argslv, result'high, result'low);
3098
    return result;
3099
  end function "sll";
3100
 
3101
  function "srl" (ARG : UNRESOLVED_sfixed; COUNT : INTEGER)
3102
    return UNRESOLVED_sfixed is
3103
    variable argslv : SIGNED (arg'length-1 downto 0);
3104
    variable result : UNRESOLVED_sfixed (arg'range);
3105
  begin
3106
    argslv := to_s (arg);
3107
    argslv := argslv srl COUNT;
3108
    result := to_fixed (argslv, result'high, result'low);
3109
    return result;
3110
  end function "srl";
3111
 
3112
  function "rol" (ARG : UNRESOLVED_sfixed; COUNT : INTEGER)
3113
    return UNRESOLVED_sfixed is
3114
    variable argslv : SIGNED (arg'length-1 downto 0);
3115
    variable result : UNRESOLVED_sfixed (arg'range);
3116
  begin
3117
    argslv := to_s (arg);
3118
    argslv := argslv rol COUNT;
3119
    result := to_fixed (argslv, result'high, result'low);
3120
    return result;
3121
  end function "rol";
3122
 
3123
  function "ror" (ARG : UNRESOLVED_sfixed; COUNT : INTEGER)
3124
    return UNRESOLVED_sfixed is
3125
    variable argslv : SIGNED (arg'length-1 downto 0);
3126
    variable result : UNRESOLVED_sfixed (arg'range);
3127
  begin
3128
    argslv := to_s (arg);
3129
    argslv := argslv ror COUNT;
3130
    result := to_fixed (argslv, result'high, result'low);
3131
    return result;
3132
  end function "ror";
3133
 
3134
  function "sla" (ARG : UNRESOLVED_sfixed; COUNT : INTEGER)
3135
    return UNRESOLVED_sfixed is
3136
    variable argslv : SIGNED (arg'length-1 downto 0);
3137
    variable result : UNRESOLVED_sfixed (arg'range);
3138
  begin
3139
    argslv := to_s (arg);
3140
    if COUNT > 0 then
3141
      -- Arithmetic shift left on a 2's complement number is a logic shift
3142
      argslv := argslv sll COUNT;
3143
    else
3144
      argslv := argslv sra -COUNT;
3145
    end if;
3146
    result := to_fixed (argslv, result'high, result'low);
3147
    return result;
3148
  end function "sla";
3149
 
3150
  function "sra" (ARG : UNRESOLVED_sfixed; COUNT : INTEGER)
3151
    return UNRESOLVED_sfixed is
3152
    variable argslv : SIGNED (arg'length-1 downto 0);
3153
    variable result : UNRESOLVED_sfixed (arg'range);
3154
  begin
3155
    argslv := to_s (arg);
3156
    if COUNT > 0 then
3157
      argslv := argslv sra COUNT;
3158
    else
3159
      -- Arithmetic shift left on a 2's complement number is a logic shift
3160
      argslv := argslv sll -COUNT;
3161
    end if;
3162
    result := to_fixed (argslv, result'high, result'low);
3163
    return result;
3164
  end function "sra";
3165
 
3166
  -- Because some people want the older functions.
3167
  function SHIFT_LEFT (ARG : UNRESOLVED_ufixed; COUNT : NATURAL)
3168
    return UNRESOLVED_ufixed is
3169
  begin
3170
    if (ARG'length < 1) then
3171
      return NAUF;
3172
    end if;
3173
    return ARG sla COUNT;
3174
  end function SHIFT_LEFT;
3175
 
3176
  function SHIFT_RIGHT (ARG : UNRESOLVED_ufixed; COUNT : NATURAL)
3177
    return UNRESOLVED_ufixed is
3178
  begin
3179
    if (ARG'length < 1) then
3180
      return NAUF;
3181
    end if;
3182
    return ARG sra COUNT;
3183
  end function SHIFT_RIGHT;
3184
 
3185
  function SHIFT_LEFT (ARG : UNRESOLVED_sfixed; COUNT : NATURAL)
3186
    return UNRESOLVED_sfixed is
3187
  begin
3188
    if (ARG'length < 1) then
3189
      return NASF;
3190
    end if;
3191
    return ARG sla COUNT;
3192
  end function SHIFT_LEFT;
3193
 
3194
  function SHIFT_RIGHT (ARG : UNRESOLVED_sfixed; COUNT : NATURAL)
3195
    return UNRESOLVED_sfixed is
3196
  begin
3197
    if (ARG'length < 1) then
3198
      return NASF;
3199
    end if;
3200
    return ARG sra COUNT;
3201
  end function SHIFT_RIGHT;
3202
 
3203
  ----------------------------------------------------------------------------
3204
  -- logical functions
3205
  ----------------------------------------------------------------------------
3206
  function "not" (L : UNRESOLVED_ufixed) return UNRESOLVED_ufixed is
3207
    variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0);  -- force downto
3208
  begin
3209
    RESULT := not to_sulv(L);
3210
    return to_ufixed(RESULT, L'high, L'low);
3211
  end function "not";
3212
 
3213
  function "and" (L, R : UNRESOLVED_ufixed) return UNRESOLVED_ufixed is
3214
    variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0);  -- force downto
3215
  begin
3216
    if (L'high = R'high and L'low = R'low) then
3217
      RESULT := to_sulv(L) and to_sulv(R);
3218
    else
3219
      assert NO_WARNING
3220
        report "fixed_pkg:"
3221
        & """and"": Range error L'RANGE /= R'RANGE"
3222
        severity warning;
3223
      RESULT := (others => 'X');
3224
    end if;
3225
    return to_ufixed(RESULT, L'high, L'low);
3226
  end function "and";
3227
 
3228
  function "or" (L, R : UNRESOLVED_ufixed) return UNRESOLVED_ufixed is
3229
    variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0);  -- force downto
3230
  begin
3231
    if (L'high = R'high and L'low = R'low) then
3232
      RESULT := to_sulv(L) or to_sulv(R);
3233
    else
3234
      assert NO_WARNING
3235
        report "fixed_pkg:"
3236
        & """or"": Range error L'RANGE /= R'RANGE"
3237
        severity warning;
3238
      RESULT := (others => 'X');
3239
    end if;
3240
    return to_ufixed(RESULT, L'high, L'low);
3241
  end function "or";
3242
 
3243
  function "nand" (L, R : UNRESOLVED_ufixed) return UNRESOLVED_ufixed is
3244
    variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0);  -- force downto
3245
  begin
3246
    if (L'high = R'high and L'low = R'low) then
3247
      RESULT := to_sulv(L) nand to_sulv(R);
3248
    else
3249
      assert NO_WARNING
3250
        report "fixed_pkg:"
3251
        & """nand"": Range error L'RANGE /= R'RANGE"
3252
        severity warning;
3253
      RESULT := (others => 'X');
3254
    end if;
3255
    return to_ufixed(RESULT, L'high, L'low);
3256
  end function "nand";
3257
 
3258
  function "nor" (L, R : UNRESOLVED_ufixed) return UNRESOLVED_ufixed is
3259
    variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0);  -- force downto
3260
  begin
3261
    if (L'high = R'high and L'low = R'low) then
3262
      RESULT := to_sulv(L) nor to_sulv(R);
3263
    else
3264
      assert NO_WARNING
3265
        report "fixed_pkg:"
3266
        & """nor"": Range error L'RANGE /= R'RANGE"
3267
        severity warning;
3268
      RESULT := (others => 'X');
3269
    end if;
3270
    return to_ufixed(RESULT, L'high, L'low);
3271
  end function "nor";
3272
 
3273
  function "xor" (L, R : UNRESOLVED_ufixed) return UNRESOLVED_ufixed is
3274
    variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0);  -- force downto
3275
  begin
3276
    if (L'high = R'high and L'low = R'low) then
3277
      RESULT := to_sulv(L) xor to_sulv(R);
3278
    else
3279
      assert NO_WARNING
3280
        report "fixed_pkg:"
3281
        & """xor"": Range error L'RANGE /= R'RANGE"
3282
        severity warning;
3283
      RESULT := (others => 'X');
3284
    end if;
3285
    return to_ufixed(RESULT, L'high, L'low);
3286
  end function "xor";
3287
 
3288
  function "xnor" (L, R : UNRESOLVED_ufixed) return UNRESOLVED_ufixed is
3289
    variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0);  -- force downto
3290
  begin
3291
    if (L'high = R'high and L'low = R'low) then
3292
      RESULT := to_sulv(L) xnor to_sulv(R);
3293
    else
3294
      assert NO_WARNING
3295
        report "fixed_pkg:"
3296
        & """xnor"": Range error L'RANGE /= R'RANGE"
3297
        severity warning;
3298
      RESULT := (others => 'X');
3299
    end if;
3300
    return to_ufixed(RESULT, L'high, L'low);
3301
  end function "xnor";
3302
 
3303
  function "not" (L : UNRESOLVED_sfixed) return UNRESOLVED_sfixed is
3304
    variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0);  -- force downto
3305
  begin
3306
    RESULT := not to_sulv(L);
3307
    return to_sfixed(RESULT, L'high, L'low);
3308
  end function "not";
3309
 
3310
  function "and" (L, R : UNRESOLVED_sfixed) return UNRESOLVED_sfixed is
3311
    variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0);  -- force downto
3312
  begin
3313
    if (L'high = R'high and L'low = R'low) then
3314
      RESULT := to_sulv(L) and to_sulv(R);
3315
    else
3316
      assert NO_WARNING
3317
        report "fixed_pkg:"
3318
        & """and"": Range error L'RANGE /= R'RANGE"
3319
        severity warning;
3320
      RESULT := (others => 'X');
3321
    end if;
3322
    return to_sfixed(RESULT, L'high, L'low);
3323
  end function "and";
3324
 
3325
  function "or" (L, R : UNRESOLVED_sfixed) return UNRESOLVED_sfixed is
3326
    variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0);  -- force downto
3327
  begin
3328
    if (L'high = R'high and L'low = R'low) then
3329
      RESULT := to_sulv(L) or to_sulv(R);
3330
    else
3331
      assert NO_WARNING
3332
        report "fixed_pkg:"
3333
        & """or"": Range error L'RANGE /= R'RANGE"
3334
        severity warning;
3335
      RESULT := (others => 'X');
3336
    end if;
3337
    return to_sfixed(RESULT, L'high, L'low);
3338
  end function "or";
3339
 
3340
  function "nand" (L, R : UNRESOLVED_sfixed) return UNRESOLVED_sfixed is
3341
    variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0);  -- force downto
3342
  begin
3343
    if (L'high = R'high and L'low = R'low) then
3344
      RESULT := to_sulv(L) nand to_sulv(R);
3345
    else
3346
      assert NO_WARNING
3347
        report "fixed_pkg:"
3348
        & """nand"": Range error L'RANGE /= R'RANGE"
3349
        severity warning;
3350
      RESULT := (others => 'X');
3351
    end if;
3352
    return to_sfixed(RESULT, L'high, L'low);
3353
  end function "nand";
3354
 
3355
  function "nor" (L, R : UNRESOLVED_sfixed) return UNRESOLVED_sfixed is
3356
    variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0);  -- force downto
3357
  begin
3358
    if (L'high = R'high and L'low = R'low) then
3359
      RESULT := to_sulv(L) nor to_sulv(R);
3360
    else
3361
      assert NO_WARNING
3362
        report "fixed_pkg:"
3363
        & """nor"": Range error L'RANGE /= R'RANGE"
3364
        severity warning;
3365
      RESULT := (others => 'X');
3366
    end if;
3367
    return to_sfixed(RESULT, L'high, L'low);
3368
  end function "nor";
3369
 
3370
  function "xor" (L, R : UNRESOLVED_sfixed) return UNRESOLVED_sfixed is
3371
    variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0);  -- force downto
3372
  begin
3373
    if (L'high = R'high and L'low = R'low) then
3374
      RESULT := to_sulv(L) xor to_sulv(R);
3375
    else
3376
      assert NO_WARNING
3377
        report "fixed_pkg:"
3378
        & """xor"": Range error L'RANGE /= R'RANGE"
3379
        severity warning;
3380
      RESULT := (others => 'X');
3381
    end if;
3382
    return to_sfixed(RESULT, L'high, L'low);
3383
  end function "xor";
3384
 
3385
  function "xnor" (L, R : UNRESOLVED_sfixed) return UNRESOLVED_sfixed is
3386
    variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0);  -- force downto
3387
  begin
3388
    if (L'high = R'high and L'low = R'low) then
3389
      RESULT := to_sulv(L) xnor to_sulv(R);
3390
    else
3391
      assert NO_WARNING
3392
        report "fixed_pkg:"
3393
        & """xnor"": Range error L'RANGE /= R'RANGE"
3394
        severity warning;
3395
      RESULT := (others => 'X');
3396
    end if;
3397
    return to_sfixed(RESULT, L'high, L'low);
3398
  end function "xnor";
3399
 
3400
  -- Vector and std_ulogic functions, same as functions in numeric_std
3401
  function "and" (L : STD_ULOGIC; R : UNRESOLVED_ufixed)
3402
    return UNRESOLVED_ufixed is
3403
    variable result : UNRESOLVED_ufixed (R'range);
3404
  begin
3405
    for i in result'range loop
3406
      result(i) := L and R(i);
3407
    end loop;
3408
    return result;
3409
  end function "and";
3410
 
3411
  function "and" (L : UNRESOLVED_ufixed; R : STD_ULOGIC)
3412
    return UNRESOLVED_ufixed is
3413
    variable result : UNRESOLVED_ufixed (L'range);
3414
  begin
3415
    for i in result'range loop
3416
      result(i) := L(i) and R;
3417
    end loop;
3418
    return result;
3419
  end function "and";
3420
 
3421
  function "or" (L : STD_ULOGIC; R : UNRESOLVED_ufixed)
3422
    return UNRESOLVED_ufixed is
3423
    variable result : UNRESOLVED_ufixed (R'range);
3424
  begin
3425
    for i in result'range loop
3426
      result(i) := L or R(i);
3427
    end loop;
3428
    return result;
3429
  end function "or";
3430
 
3431
  function "or" (L : UNRESOLVED_ufixed; R : STD_ULOGIC)
3432
    return UNRESOLVED_ufixed is
3433
    variable result : UNRESOLVED_ufixed (L'range);
3434
  begin
3435
    for i in result'range loop
3436
      result(i) := L(i) or R;
3437
    end loop;
3438
    return result;
3439
  end function "or";
3440
 
3441
  function "nand" (L : STD_ULOGIC; R : UNRESOLVED_ufixed)
3442
    return UNRESOLVED_ufixed is
3443
    variable result : UNRESOLVED_ufixed (R'range);
3444
  begin
3445
    for i in result'range loop
3446
      result(i) := L nand R(i);
3447
    end loop;
3448
    return result;
3449
  end function "nand";
3450
 
3451
  function "nand" (L : UNRESOLVED_ufixed; R : STD_ULOGIC)
3452
    return UNRESOLVED_ufixed is
3453
    variable result : UNRESOLVED_ufixed (L'range);
3454
  begin
3455
    for i in result'range loop
3456
      result(i) := L(i) nand R;
3457
    end loop;
3458
    return result;
3459
  end function "nand";
3460
 
3461
  function "nor" (L : STD_ULOGIC; R : UNRESOLVED_ufixed)
3462
    return UNRESOLVED_ufixed is
3463
    variable result : UNRESOLVED_ufixed (R'range);
3464
  begin
3465
    for i in result'range loop
3466
      result(i) := L nor R(i);
3467
    end loop;
3468
    return result;
3469
  end function "nor";
3470
 
3471
  function "nor" (L : UNRESOLVED_ufixed; R : STD_ULOGIC)
3472
    return UNRESOLVED_ufixed is
3473
    variable result : UNRESOLVED_ufixed (L'range);
3474
  begin
3475
    for i in result'range loop
3476
      result(i) := L(i) nor R;
3477
    end loop;
3478
    return result;
3479
  end function "nor";
3480
 
3481
  function "xor" (L : STD_ULOGIC; R : UNRESOLVED_ufixed)
3482
    return UNRESOLVED_ufixed is
3483
    variable result : UNRESOLVED_ufixed (R'range);
3484
  begin
3485
    for i in result'range loop
3486
      result(i) := L xor R(i);
3487
    end loop;
3488
    return result;
3489
  end function "xor";
3490
 
3491
  function "xor" (L : UNRESOLVED_ufixed; R : STD_ULOGIC)
3492
    return UNRESOLVED_ufixed is
3493
    variable result : UNRESOLVED_ufixed (L'range);
3494
  begin
3495
    for i in result'range loop
3496
      result(i) := L(i) xor R;
3497
    end loop;
3498
    return result;
3499
  end function "xor";
3500
 
3501
  function "xnor" (L : STD_ULOGIC; R : UNRESOLVED_ufixed)
3502
    return UNRESOLVED_ufixed is
3503
    variable result : UNRESOLVED_ufixed (R'range);
3504
  begin
3505
    for i in result'range loop
3506
      result(i) := L xnor R(i);
3507
    end loop;
3508
    return result;
3509
  end function "xnor";
3510
 
3511
  function "xnor" (L : UNRESOLVED_ufixed; R : STD_ULOGIC)
3512
    return UNRESOLVED_ufixed is
3513
    variable result : UNRESOLVED_ufixed (L'range);
3514
  begin
3515
    for i in result'range loop
3516
      result(i) := L(i) xnor R;
3517
    end loop;
3518
    return result;
3519
  end function "xnor";
3520
 
3521
  function "and" (L : STD_ULOGIC; R : UNRESOLVED_sfixed)
3522
    return UNRESOLVED_sfixed is
3523
    variable result : UNRESOLVED_sfixed (R'range);
3524
  begin
3525
    for i in result'range loop
3526
      result(i) := L and R(i);
3527
    end loop;
3528
    return result;
3529
  end function "and";
3530
 
3531
  function "and" (L : UNRESOLVED_sfixed; R : STD_ULOGIC)
3532
    return UNRESOLVED_sfixed is
3533
    variable result : UNRESOLVED_sfixed (L'range);
3534
  begin
3535
    for i in result'range loop
3536
      result(i) := L(i) and R;
3537
    end loop;
3538
    return result;
3539
  end function "and";
3540
 
3541
  function "or" (L : STD_ULOGIC; R : UNRESOLVED_sfixed)
3542
    return UNRESOLVED_sfixed is
3543
    variable result : UNRESOLVED_sfixed (R'range);
3544
  begin
3545
    for i in result'range loop
3546
      result(i) := L or R(i);
3547
    end loop;
3548
    return result;
3549
  end function "or";
3550
 
3551
  function "or" (L : UNRESOLVED_sfixed; R : STD_ULOGIC)
3552
    return UNRESOLVED_sfixed is
3553
    variable result : UNRESOLVED_sfixed (L'range);
3554
  begin
3555
    for i in result'range loop
3556
      result(i) := L(i) or R;
3557
    end loop;
3558
    return result;
3559
  end function "or";
3560
 
3561
  function "nand" (L : STD_ULOGIC; R : UNRESOLVED_sfixed)
3562
    return UNRESOLVED_sfixed is
3563
    variable result : UNRESOLVED_sfixed (R'range);
3564
  begin
3565
    for i in result'range loop
3566
      result(i) := L nand R(i);
3567
    end loop;
3568
    return result;
3569
  end function "nand";
3570
 
3571
  function "nand" (L : UNRESOLVED_sfixed; R : STD_ULOGIC)
3572
    return UNRESOLVED_sfixed is
3573
    variable result : UNRESOLVED_sfixed (L'range);
3574
  begin
3575
    for i in result'range loop
3576
      result(i) := L(i) nand R;
3577
    end loop;
3578
    return result;
3579
  end function "nand";
3580
 
3581
  function "nor" (L : STD_ULOGIC; R : UNRESOLVED_sfixed)
3582
    return UNRESOLVED_sfixed is
3583
    variable result : UNRESOLVED_sfixed (R'range);
3584
  begin
3585
    for i in result'range loop
3586
      result(i) := L nor R(i);
3587
    end loop;
3588
    return result;
3589
  end function "nor";
3590
 
3591
  function "nor" (L : UNRESOLVED_sfixed; R : STD_ULOGIC)
3592
    return UNRESOLVED_sfixed is
3593
    variable result : UNRESOLVED_sfixed (L'range);
3594
  begin
3595
    for i in result'range loop
3596
      result(i) := L(i) nor R;
3597
    end loop;
3598
    return result;
3599
  end function "nor";
3600
 
3601
  function "xor" (L : STD_ULOGIC; R : UNRESOLVED_sfixed)
3602
    return UNRESOLVED_sfixed is
3603
    variable result : UNRESOLVED_sfixed (R'range);
3604
  begin
3605
    for i in result'range loop
3606
      result(i) := L xor R(i);
3607
    end loop;
3608
    return result;
3609
  end function "xor";
3610
 
3611
  function "xor" (L : UNRESOLVED_sfixed; R : STD_ULOGIC)
3612
    return UNRESOLVED_sfixed is
3613
    variable result : UNRESOLVED_sfixed (L'range);
3614
  begin
3615
    for i in result'range loop
3616
      result(i) := L(i) xor R;
3617
    end loop;
3618
    return result;
3619
  end function "xor";
3620
 
3621
  function "xnor" (L : STD_ULOGIC; R : UNRESOLVED_sfixed)
3622
    return UNRESOLVED_sfixed is
3623
    variable result : UNRESOLVED_sfixed (R'range);
3624
  begin
3625
    for i in result'range loop
3626
      result(i) := L xnor R(i);
3627
    end loop;
3628
    return result;
3629
  end function "xnor";
3630
 
3631
  function "xnor" (L : UNRESOLVED_sfixed; R : STD_ULOGIC)
3632
    return UNRESOLVED_sfixed is
3633
    variable result : UNRESOLVED_sfixed (L'range);
3634
  begin
3635
    for i in result'range loop
3636
      result(i) := L(i) xnor R;
3637
    end loop;
3638
    return result;
3639
  end function "xnor";
3640
 
3641
  -- Reduction operator_reduces
3642
  function and_reduce (l : UNRESOLVED_ufixed) return STD_ULOGIC is
3643
  begin
3644
    return and_reduce (to_sulv(l));
3645
  end function and_reduce;
3646
 
3647
  function nand_reduce (l : UNRESOLVED_ufixed) return STD_ULOGIC is
3648
  begin
3649
    return nand_reduce (to_sulv(l));
3650
  end function nand_reduce;
3651
 
3652
  function or_reduce (l : UNRESOLVED_ufixed) return STD_ULOGIC is
3653
  begin
3654
    return or_reduce (to_sulv(l));
3655
  end function or_reduce;
3656
 
3657
  function nor_reduce (l : UNRESOLVED_ufixed) return STD_ULOGIC is
3658
  begin
3659
    return nor_reduce (to_sulv(l));
3660
  end function nor_reduce;
3661
 
3662
  function xor_reduce (l : UNRESOLVED_ufixed) return STD_ULOGIC is
3663
  begin
3664
    return xor_reduce (to_sulv(l));
3665
  end function xor_reduce;
3666
 
3667
  function xnor_reduce (l : UNRESOLVED_ufixed) return STD_ULOGIC is
3668
  begin
3669
    return xnor_reduce (to_sulv(l));
3670
  end function xnor_reduce;
3671
 
3672
  function and_reduce (l : UNRESOLVED_sfixed) return STD_ULOGIC is
3673
  begin
3674
    return and_reduce (to_sulv(l));
3675
  end function and_reduce;
3676
 
3677
  function nand_reduce (l : UNRESOLVED_sfixed) return STD_ULOGIC is
3678
  begin
3679
    return nand_reduce (to_sulv(l));
3680
  end function nand_reduce;
3681
 
3682
  function or_reduce (l : UNRESOLVED_sfixed) return STD_ULOGIC is
3683
  begin
3684
    return or_reduce (to_sulv(l));
3685
  end function or_reduce;
3686
 
3687
  function nor_reduce (l : UNRESOLVED_sfixed) return STD_ULOGIC is
3688
  begin
3689
    return nor_reduce (to_sulv(l));
3690
  end function nor_reduce;
3691
 
3692
  function xor_reduce (l : UNRESOLVED_sfixed) return STD_ULOGIC is
3693
  begin
3694
    return xor_reduce (to_sulv(l));
3695
  end function xor_reduce;
3696
 
3697
  function xnor_reduce (l : UNRESOLVED_sfixed) return STD_ULOGIC is
3698
  begin
3699
    return xnor_reduce (to_sulv(l));
3700
  end function xnor_reduce;
3701
  -- End reduction operator_reduces
3702
 
3703
  function \?=\ (L, R : UNRESOLVED_ufixed) return STD_ULOGIC is
3704
    constant left_index       : INTEGER := maximum(l'high, r'high);
3705
    constant right_index      : INTEGER := mins(l'low, r'low);
3706
    variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
3707
    variable lslv, rslv       : UNSIGNED (lresize'length-1 downto 0);
3708
  begin  -- ?=
3709
    if ((L'length < 1) or (R'length < 1)) then
3710
      assert NO_WARNING
3711
        report "fixed_pkg:"
3712
        & """?="": null detected, returning X"
3713
        severity warning;
3714
      return 'X';
3715
    else
3716
      lresize := resize (l, left_index, right_index);
3717
      rresize := resize (r, left_index, right_index);
3718
      lslv    := to_uns (lresize);
3719
      rslv    := to_uns (rresize);
3720
      return \?=\ (lslv, rslv);
3721
    end if;
3722
  end function \?=\;
3723
 
3724
  function \?/=\ (L, R : UNRESOLVED_ufixed) return STD_ULOGIC is
3725
    constant left_index       : INTEGER := maximum(l'high, r'high);
3726
    constant right_index      : INTEGER := mins(l'low, r'low);
3727
    variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
3728
    variable lslv, rslv       : UNSIGNED (lresize'length-1 downto 0);
3729
  begin  -- ?/=
3730
    if ((L'length < 1) or (R'length < 1)) then
3731
      assert NO_WARNING
3732
        report "fixed_pkg:"
3733
        & """?/="": null detected, returning X"
3734
        severity warning;
3735
      return 'X';
3736
    else
3737
      lresize := resize (l, left_index, right_index);
3738
      rresize := resize (r, left_index, right_index);
3739
      lslv    := to_uns (lresize);
3740
      rslv    := to_uns (rresize);
3741
      return \?/=\ (lslv, rslv);
3742
    end if;
3743
  end function \?/=\;
3744
 
3745
  function \?>\ (L, R : UNRESOLVED_ufixed) return STD_ULOGIC is
3746
    constant left_index       : INTEGER := maximum(l'high, r'high);
3747
    constant right_index      : INTEGER := mins(l'low, r'low);
3748
    variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
3749
    variable lslv, rslv       : UNSIGNED (lresize'length-1 downto 0);
3750
  begin  -- ?>
3751
    if ((l'length < 1) or (r'length < 1)) then
3752
      assert NO_WARNING
3753
        report "fixed_pkg:"
3754
        & """?>"": null detected, returning X"
3755
        severity warning;
3756
      return 'X';
3757
    else
3758
      lresize := resize (l, left_index, right_index);
3759
      rresize := resize (r, left_index, right_index);
3760
      lslv    := to_uns (lresize);
3761
      rslv    := to_uns (rresize);
3762
      return \?>\ (lslv, rslv);
3763
    end if;
3764
  end function \?>\;
3765
 
3766
  function \?>=\ (L, R : UNRESOLVED_ufixed) return STD_ULOGIC is
3767
    constant left_index       : INTEGER := maximum(l'high, r'high);
3768
    constant right_index      : INTEGER := mins(l'low, r'low);
3769
    variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
3770
    variable lslv, rslv       : UNSIGNED (lresize'length-1 downto 0);
3771
  begin  -- ?>=
3772
    if ((l'length < 1) or (r'length < 1)) then
3773
      assert NO_WARNING
3774
        report "fixed_pkg:"
3775
        & """?>="": null detected, returning X"
3776
        severity warning;
3777
      return 'X';
3778
    else
3779
      lresize := resize (l, left_index, right_index);
3780
      rresize := resize (r, left_index, right_index);
3781
      lslv    := to_uns (lresize);
3782
      rslv    := to_uns (rresize);
3783
      return \?>=\ (lslv, rslv);
3784
    end if;
3785
  end function \?>=\;
3786
 
3787
  function \?<\ (L, R : UNRESOLVED_ufixed) return STD_ULOGIC is
3788
    constant left_index       : INTEGER := maximum(l'high, r'high);
3789
    constant right_index      : INTEGER := mins(l'low, r'low);
3790
    variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
3791
    variable lslv, rslv       : UNSIGNED (lresize'length-1 downto 0);
3792
  begin  -- ?<
3793
    if ((l'length < 1) or (r'length < 1)) then
3794
      assert NO_WARNING
3795
        report "fixed_pkg:"
3796
        & """?<"": null detected, returning X"
3797
        severity warning;
3798
      return 'X';
3799
    else
3800
      lresize := resize (l, left_index, right_index);
3801
      rresize := resize (r, left_index, right_index);
3802
      lslv    := to_uns (lresize);
3803
      rslv    := to_uns (rresize);
3804
      return \?<\ (lslv, rslv);
3805
    end if;
3806
  end function \?<\;
3807
 
3808
  function \?<=\ (L, R : UNRESOLVED_ufixed) return STD_ULOGIC is
3809
    constant left_index       : INTEGER := maximum(l'high, r'high);
3810
    constant right_index      : INTEGER := mins(l'low, r'low);
3811
    variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
3812
    variable lslv, rslv       : UNSIGNED (lresize'length-1 downto 0);
3813
  begin  -- ?<=
3814
    if ((l'length < 1) or (r'length < 1)) then
3815
      assert NO_WARNING
3816
        report "fixed_pkg:"
3817
        & """?<="": null detected, returning X"
3818
        severity warning;
3819
      return 'X';
3820
    else
3821
      lresize := resize (l, left_index, right_index);
3822
      rresize := resize (r, left_index, right_index);
3823
      lslv    := to_uns (lresize);
3824
      rslv    := to_uns (rresize);
3825
      return \?<=\ (lslv, rslv);
3826
    end if;
3827
  end function \?<=\;
3828
 
3829
  function \?=\ (L, R : UNRESOLVED_sfixed) return STD_ULOGIC is
3830
    constant left_index       : INTEGER := maximum(l'high, r'high);
3831
    constant right_index      : INTEGER := mins(l'low, r'low);
3832
    variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
3833
    variable lslv, rslv       : SIGNED (lresize'length-1 downto 0);
3834
  begin  -- ?=
3835
    if ((L'length < 1) or (R'length < 1)) then
3836
      assert NO_WARNING
3837
        report "fixed_pkg:"
3838
        & """?="": null detected, returning X"
3839
        severity warning;
3840
      return 'X';
3841
    else
3842
      lresize := resize (l, left_index, right_index);
3843
      rresize := resize (r, left_index, right_index);
3844
      lslv    := to_s (lresize);
3845
      rslv    := to_s (rresize);
3846
      return \?=\ (lslv, rslv);
3847
    end if;
3848
  end function \?=\;
3849
 
3850
  function \?/=\ (L, R : UNRESOLVED_sfixed) return STD_ULOGIC is
3851
    constant left_index       : INTEGER := maximum(l'high, r'high);
3852
    constant right_index      : INTEGER := mins(l'low, r'low);
3853
    variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
3854
    variable lslv, rslv       : SIGNED (lresize'length-1 downto 0);
3855
  begin  -- ?/=
3856
    if ((L'length < 1) or (R'length < 1)) then
3857
      assert NO_WARNING
3858
        report "fixed_pkg:"
3859
        & """?/="": null detected, returning X"
3860
        severity warning;
3861
      return 'X';
3862
    else
3863
      lresize := resize (l, left_index, right_index);
3864
      rresize := resize (r, left_index, right_index);
3865
      lslv    := to_s (lresize);
3866
      rslv    := to_s (rresize);
3867
      return \?/=\ (lslv, rslv);
3868
    end if;
3869
  end function \?/=\;
3870
 
3871
  function \?>\ (L, R : UNRESOLVED_sfixed) return STD_ULOGIC is
3872
    constant left_index       : INTEGER := maximum(l'high, r'high);
3873
    constant right_index      : INTEGER := mins(l'low, r'low);
3874
    variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
3875
    variable lslv, rslv       : SIGNED (lresize'length-1 downto 0);
3876
  begin  -- ?>
3877
    if ((l'length < 1) or (r'length < 1)) then
3878
      assert NO_WARNING
3879
        report "fixed_pkg:"
3880
        & """?>"": null detected, returning X"
3881
        severity warning;
3882
      return 'X';
3883
    else
3884
      lresize := resize (l, left_index, right_index);
3885
      rresize := resize (r, left_index, right_index);
3886
      lslv    := to_s (lresize);
3887
      rslv    := to_s (rresize);
3888
      return \?>\ (lslv, rslv);
3889
    end if;
3890
  end function \?>\;
3891
 
3892
  function \?>=\ (L, R : UNRESOLVED_sfixed) return STD_ULOGIC is
3893
    constant left_index       : INTEGER := maximum(l'high, r'high);
3894
    constant right_index      : INTEGER := mins(l'low, r'low);
3895
    variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
3896
    variable lslv, rslv       : SIGNED (lresize'length-1 downto 0);
3897
  begin  -- ?>=
3898
    if ((l'length < 1) or (r'length < 1)) then
3899
      assert NO_WARNING
3900
        report "fixed_pkg:"
3901
        & """?>="": null detected, returning X"
3902
        severity warning;
3903
      return 'X';
3904
    else
3905
      lresize := resize (l, left_index, right_index);
3906
      rresize := resize (r, left_index, right_index);
3907
      lslv    := to_s (lresize);
3908
      rslv    := to_s (rresize);
3909
      return \?>=\ (lslv, rslv);
3910
    end if;
3911
  end function \?>=\;
3912
 
3913
  function \?<\ (L, R : UNRESOLVED_sfixed) return STD_ULOGIC is
3914
    constant left_index       : INTEGER := maximum(l'high, r'high);
3915
    constant right_index      : INTEGER := mins(l'low, r'low);
3916
    variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
3917
    variable lslv, rslv       : SIGNED (lresize'length-1 downto 0);
3918
  begin  -- ?<
3919
    if ((l'length < 1) or (r'length < 1)) then
3920
      assert NO_WARNING
3921
        report "fixed_pkg:"
3922
        & """?<"": null detected, returning X"
3923
        severity warning;
3924
      return 'X';
3925
    else
3926
      lresize := resize (l, left_index, right_index);
3927
      rresize := resize (r, left_index, right_index);
3928
      lslv    := to_s (lresize);
3929
      rslv    := to_s (rresize);
3930
      return \?<\ (lslv, rslv);
3931
    end if;
3932
  end function \?<\;
3933
 
3934
  function \?<=\ (L, R : UNRESOLVED_sfixed) return STD_ULOGIC is
3935
    constant left_index       : INTEGER := maximum(l'high, r'high);
3936
    constant right_index      : INTEGER := mins(l'low, r'low);
3937
    variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
3938
    variable lslv, rslv       : SIGNED (lresize'length-1 downto 0);
3939
  begin  -- ?<=
3940
    if ((l'length < 1) or (r'length < 1)) then
3941
      assert NO_WARNING
3942
        report "fixed_pkg:"
3943
        & """?<="": null detected, returning X"
3944
        severity warning;
3945
      return 'X';
3946
    else
3947
      lresize := resize (l, left_index, right_index);
3948
      rresize := resize (r, left_index, right_index);
3949
      lslv    := to_s (lresize);
3950
      rslv    := to_s (rresize);
3951
      return \?<=\ (lslv, rslv);
3952
    end if;
3953
  end function \?<=\;
3954
 
3955
  -- Match function, similar to "std_match" from numeric_std
3956
  function std_match (L, R : UNRESOLVED_ufixed) return BOOLEAN is
3957
  begin
3958
    if (L'high = R'high and L'low = R'low) then
3959
      return std_match(to_sulv(L), to_sulv(R));
3960
    else
3961
      assert NO_WARNING
3962
        report "fixed_pkg:"
3963
        & "STD_MATCH: L'RANGE /= R'RANGE, returning FALSE"
3964
        severity warning;
3965
      return false;
3966
    end if;
3967
  end function std_match;
3968
 
3969
  function std_match (L, R : UNRESOLVED_sfixed) return BOOLEAN is
3970
  begin
3971
    if (L'high = R'high and L'low = R'low) then
3972
      return std_match(to_sulv(L), to_sulv(R));
3973
    else
3974
      assert NO_WARNING
3975
        report "fixed_pkg:"
3976
        & "STD_MATCH: L'RANGE /= R'RANGE, returning FALSE"
3977
        severity warning;
3978
      return false;
3979
    end if;
3980
  end function std_match;
3981
 
3982
  -- compare functions
3983
  function "=" (
3984
    l, r : UNRESOLVED_ufixed)           -- fixed point input
3985
    return BOOLEAN is
3986
    constant left_index       : INTEGER := maximum(l'high, r'high);
3987
    constant right_index      : INTEGER := mins(l'low, r'low);
3988
    variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
3989
    variable lslv, rslv       : UNSIGNED (lresize'length-1 downto 0);
3990
  begin
3991
    if (l'length < 1 or r'length < 1) then
3992
      assert NO_WARNING
3993
        report "fixed_pkg:"
3994
        & """="": null argument detected, returning FALSE"
3995
        severity warning;
3996
      return false;
3997
    elsif (Is_X(l) or Is_X(r)) then
3998
      assert NO_WARNING
3999
        report "fixed_pkg:"
4000
        & """="": metavalue detected, returning FALSE"
4001
        severity warning;
4002
      return false;
4003
    end if;
4004
    lresize := resize (l, left_index, right_index);
4005
    rresize := resize (r, left_index, right_index);
4006
    lslv    := to_uns (lresize);
4007
    rslv    := to_uns (rresize);
4008
    return lslv = rslv;
4009
  end function "=";
4010
 
4011
  function "=" (
4012
    l, r : UNRESOLVED_sfixed)           -- fixed point input
4013
    return BOOLEAN is
4014
    constant left_index       : INTEGER := maximum(l'high, r'high);
4015
    constant right_index      : INTEGER := mins(l'low, r'low);
4016
    variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
4017
    variable lslv, rslv       : SIGNED (lresize'length-1 downto 0);
4018
  begin
4019
    if (l'length < 1 or r'length < 1) then
4020
      assert NO_WARNING
4021
        report "fixed_pkg:"
4022
        & """="": null argument detected, returning FALSE"
4023
        severity warning;
4024
      return false;
4025
    elsif (Is_X(l) or Is_X(r)) then
4026
      assert NO_WARNING
4027
        report "fixed_pkg:"
4028
        & """="": metavalue detected, returning FALSE"
4029
        severity warning;
4030
      return false;
4031
    end if;
4032
    lresize := resize (l, left_index, right_index);
4033
    rresize := resize (r, left_index, right_index);
4034
    lslv    := to_s (lresize);
4035
    rslv    := to_s (rresize);
4036
    return lslv = rslv;
4037
  end function "=";
4038
 
4039
  function "/=" (
4040
    l, r : UNRESOLVED_ufixed)           -- fixed point input
4041
    return BOOLEAN is
4042
    constant left_index       : INTEGER := maximum(l'high, r'high);
4043
    constant right_index      : INTEGER := mins(l'low, r'low);
4044
    variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
4045
    variable lslv, rslv       : UNSIGNED (lresize'length-1 downto 0);
4046
  begin
4047
    if (l'length < 1 or r'length < 1) then
4048
      assert NO_WARNING
4049
        report "fixed_pkg:"
4050
        & """/="": null argument detected, returning TRUE"
4051
        severity warning;
4052
      return true;
4053
    elsif (Is_X(l) or Is_X(r)) then
4054
      assert NO_WARNING
4055
        report "fixed_pkg:"
4056
        & """/="": metavalue detected, returning TRUE"
4057
        severity warning;
4058
      return true;
4059
    end if;
4060
    lresize := resize (l, left_index, right_index);
4061
    rresize := resize (r, left_index, right_index);
4062
    lslv    := to_uns (lresize);
4063
    rslv    := to_uns (rresize);
4064
    return lslv /= rslv;
4065
  end function "/=";
4066
 
4067
  function "/=" (
4068
    l, r : UNRESOLVED_sfixed)           -- fixed point input
4069
    return BOOLEAN is
4070
    constant left_index       : INTEGER := maximum(l'high, r'high);
4071
    constant right_index      : INTEGER := mins(l'low, r'low);
4072
    variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
4073
    variable lslv, rslv       : SIGNED (lresize'length-1 downto 0);
4074
  begin
4075
    if (l'length < 1 or r'length < 1) then
4076
      assert NO_WARNING
4077
        report "fixed_pkg:"
4078
        & """/="": null argument detected, returning TRUE"
4079
        severity warning;
4080
      return true;
4081
    elsif (Is_X(l) or Is_X(r)) then
4082
      assert NO_WARNING
4083
        report "fixed_pkg:"
4084
        & """/="": metavalue detected, returning TRUE"
4085
        severity warning;
4086
      return true;
4087
    end if;
4088
    lresize := resize (l, left_index, right_index);
4089
    rresize := resize (r, left_index, right_index);
4090
    lslv    := to_s (lresize);
4091
    rslv    := to_s (rresize);
4092
    return lslv /= rslv;
4093
  end function "/=";
4094
 
4095
  function ">" (
4096
    l, r : UNRESOLVED_ufixed)           -- fixed point input
4097
    return BOOLEAN is
4098
    constant left_index       : INTEGER := maximum(l'high, r'high);
4099
    constant right_index      : INTEGER := mins(l'low, r'low);
4100
    variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
4101
    variable lslv, rslv       : UNSIGNED (lresize'length-1 downto 0);
4102
  begin
4103
    if (l'length < 1 or r'length < 1) then
4104
      assert NO_WARNING
4105
        report "fixed_pkg:"
4106
        & """>"": null argument detected, returning FALSE"
4107
        severity warning;
4108
      return false;
4109
    elsif (Is_X(l) or Is_X(r)) then
4110
      assert NO_WARNING
4111
        report "fixed_pkg:"
4112
        & """>"": metavalue detected, returning FALSE"
4113
        severity warning;
4114
      return false;
4115
    end if;
4116
    lresize := resize (l, left_index, right_index);
4117
    rresize := resize (r, left_index, right_index);
4118
    lslv    := to_uns (lresize);
4119
    rslv    := to_uns (rresize);
4120
    return lslv > rslv;
4121
  end function ">";
4122
 
4123
  function ">" (
4124
    l, r : UNRESOLVED_sfixed)           -- fixed point input
4125
    return BOOLEAN is
4126
    constant left_index       : INTEGER := maximum(l'high, r'high);
4127
    constant right_index      : INTEGER := mins(l'low, r'low);
4128
    variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
4129
    variable lslv, rslv       : SIGNED (lresize'length-1 downto 0);
4130
  begin
4131
    if (l'length < 1 or r'length < 1) then
4132
      assert NO_WARNING
4133
        report "fixed_pkg:"
4134
        & """>"": null argument detected, returning FALSE"
4135
        severity warning;
4136
      return false;
4137
    elsif (Is_X(l) or Is_X(r)) then
4138
      assert NO_WARNING
4139
        report "fixed_pkg:"
4140
        & """>"": metavalue detected, returning FALSE"
4141
        severity warning;
4142
      return false;
4143
    end if;
4144
    lresize := resize (l, left_index, right_index);
4145
    rresize := resize (r, left_index, right_index);
4146
    lslv    := to_s (lresize);
4147
    rslv    := to_s (rresize);
4148
    return lslv > rslv;
4149
  end function ">";
4150
 
4151
  function "<" (
4152
    l, r : UNRESOLVED_ufixed)           -- fixed point input
4153
    return BOOLEAN is
4154
    constant left_index       : INTEGER := maximum(l'high, r'high);
4155
    constant right_index      : INTEGER := mins(l'low, r'low);
4156
    variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
4157
    variable lslv, rslv       : UNSIGNED (lresize'length-1 downto 0);
4158
  begin
4159
    if (l'length < 1 or r'length < 1) then
4160
      assert NO_WARNING
4161
        report "fixed_pkg:"
4162
        & """<"": null argument detected, returning FALSE"
4163
        severity warning;
4164
      return false;
4165
    elsif (Is_X(l) or Is_X(r)) then
4166
      assert NO_WARNING
4167
        report "fixed_pkg:"
4168
        & """<"": metavalue detected, returning FALSE"
4169
        severity warning;
4170
      return false;
4171
    end if;
4172
    lresize := resize (l, left_index, right_index);
4173
    rresize := resize (r, left_index, right_index);
4174
    lslv    := to_uns (lresize);
4175
    rslv    := to_uns (rresize);
4176
    return lslv < rslv;
4177
  end function "<";
4178
 
4179
  function "<" (
4180
    l, r : UNRESOLVED_sfixed)           -- fixed point input
4181
    return BOOLEAN is
4182
    constant left_index       : INTEGER := maximum(l'high, r'high);
4183
    constant right_index      : INTEGER := mins(l'low, r'low);
4184
    variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
4185
    variable lslv, rslv       : SIGNED (lresize'length-1 downto 0);
4186
  begin
4187
    if (l'length < 1 or r'length < 1) then
4188
      assert NO_WARNING
4189
        report "fixed_pkg:"
4190
        & """<"": null argument detected, returning FALSE"
4191
        severity warning;
4192
      return false;
4193
    elsif (Is_X(l) or Is_X(r)) then
4194
      assert NO_WARNING
4195
        report "fixed_pkg:"
4196
        & """<"": metavalue detected, returning FALSE"
4197
        severity warning;
4198
      return false;
4199
    end if;
4200
    lresize := resize (l, left_index, right_index);
4201
    rresize := resize (r, left_index, right_index);
4202
    lslv    := to_s (lresize);
4203
    rslv    := to_s (rresize);
4204
    return lslv < rslv;
4205
  end function "<";
4206
 
4207
  function ">=" (
4208
    l, r : UNRESOLVED_ufixed)           -- fixed point input
4209
    return BOOLEAN is
4210
    constant left_index       : INTEGER := maximum(l'high, r'high);
4211
    constant right_index      : INTEGER := mins(l'low, r'low);
4212
    variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
4213
    variable lslv, rslv       : UNSIGNED (lresize'length-1 downto 0);
4214
  begin
4215
    if (l'length < 1 or r'length < 1) then
4216
      assert NO_WARNING
4217
        report "fixed_pkg:"
4218
        & """>="": null argument detected, returning FALSE"
4219
        severity warning;
4220
      return false;
4221
    elsif (Is_X(l) or Is_X(r)) then
4222
      assert NO_WARNING
4223
        report "fixed_pkg:"
4224
        & """>="": metavalue detected, returning FALSE"
4225
        severity warning;
4226
      return false;
4227
    end if;
4228
    lresize := resize (l, left_index, right_index);
4229
    rresize := resize (r, left_index, right_index);
4230
    lslv    := to_uns (lresize);
4231
    rslv    := to_uns (rresize);
4232
    return lslv >= rslv;
4233
  end function ">=";
4234
 
4235
  function ">=" (
4236
    l, r : UNRESOLVED_sfixed)           -- fixed point input
4237
    return BOOLEAN is
4238
    constant left_index       : INTEGER := maximum(l'high, r'high);
4239
    constant right_index      : INTEGER := mins(l'low, r'low);
4240
    variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
4241
    variable lslv, rslv       : SIGNED (lresize'length-1 downto 0);
4242
  begin
4243
    if (l'length < 1 or r'length < 1) then
4244
      assert NO_WARNING
4245
        report "fixed_pkg:"
4246
        & """>="": null argument detected, returning FALSE"
4247
        severity warning;
4248
      return false;
4249
    elsif (Is_X(l) or Is_X(r)) then
4250
      assert NO_WARNING
4251
        report "fixed_pkg:"
4252
        & """>="": metavalue detected, returning FALSE"
4253
        severity warning;
4254
      return false;
4255
    end if;
4256
    lresize := resize (l, left_index, right_index);
4257
    rresize := resize (r, left_index, right_index);
4258
    lslv    := to_s (lresize);
4259
    rslv    := to_s (rresize);
4260
    return lslv >= rslv;
4261
  end function ">=";
4262
 
4263
  function "<=" (
4264
    l, r : UNRESOLVED_ufixed)           -- fixed point input
4265
    return BOOLEAN is
4266
    constant left_index       : INTEGER := maximum(l'high, r'high);
4267
    constant right_index      : INTEGER := mins(l'low, r'low);
4268
    variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
4269
    variable lslv, rslv       : UNSIGNED (lresize'length-1 downto 0);
4270
  begin
4271
    if (l'length < 1 or r'length < 1) then
4272
      assert NO_WARNING
4273
        report "fixed_pkg:"
4274
        & """<="": null argument detected, returning FALSE"
4275
        severity warning;
4276
      return false;
4277
    elsif (Is_X(l) or Is_X(r)) then
4278
      assert NO_WARNING
4279
        report "fixed_pkg:"
4280
        & """<="": metavalue detected, returning FALSE"
4281
        severity warning;
4282
      return false;
4283
    end if;
4284
    lresize     := resize (l, left_index, right_index);
4285
    rresize     := resize (r, left_index, right_index);
4286
    lslv        := to_uns (lresize);
4287
    rslv        := to_uns (rresize);
4288
    return lslv <= rslv;
4289
  end function "<=";
4290
 
4291
  function "<=" (
4292
    l, r : UNRESOLVED_sfixed)           -- fixed point input
4293
    return BOOLEAN is
4294
    constant left_index       : INTEGER := maximum(l'high, r'high);
4295
    constant right_index      : INTEGER := mins(l'low, r'low);
4296
    variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
4297
    variable lslv, rslv       : SIGNED (lresize'length-1 downto 0);
4298
  begin
4299
    if (l'length < 1 or r'length < 1) then
4300
      assert NO_WARNING
4301
        report "fixed_pkg:"
4302
        & """<="": null argument detected, returning FALSE"
4303
        severity warning;
4304
      return false;
4305
    elsif (Is_X(l) or Is_X(r)) then
4306
      assert NO_WARNING
4307
        report "fixed_pkg:"
4308
        & """<="": metavalue detected, returning FALSE"
4309
        severity warning;
4310
      return false;
4311
    end if;
4312
    lresize     := resize (l, left_index, right_index);
4313
    rresize     := resize (r, left_index, right_index);
4314
    lslv        := to_s (lresize);
4315
    rslv        := to_s (rresize);
4316
    return lslv <= rslv;
4317
  end function "<=";
4318
 
4319
  -- overloads of the default maximum and minimum functions
4320
  function maximum (l, r : UNRESOLVED_ufixed) return UNRESOLVED_ufixed is
4321
    constant left_index       : INTEGER := maximum(l'high, r'high);
4322
    constant right_index      : INTEGER := mins(l'low, r'low);
4323
    variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
4324
  begin
4325
    if (l'length < 1 or r'length < 1) then
4326
      return NAUF;
4327
    end if;
4328
    lresize := resize (l, left_index, right_index);
4329
    rresize := resize (r, left_index, right_index);
4330
    if lresize > rresize then return lresize;
4331
    else return rresize;
4332
    end if;
4333
  end function maximum;
4334
 
4335
  function maximum (l, r : UNRESOLVED_sfixed) return UNRESOLVED_sfixed is
4336
    constant left_index       : INTEGER := maximum(l'high, r'high);
4337
    constant right_index      : INTEGER := mins(l'low, r'low);
4338
    variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
4339
  begin
4340
    if (l'length < 1 or r'length < 1) then
4341
      return NASF;
4342
    end if;
4343
    lresize := resize (l, left_index, right_index);
4344
    rresize := resize (r, left_index, right_index);
4345
    if lresize > rresize then return lresize;
4346
    else return rresize;
4347
    end if;
4348
  end function maximum;
4349
 
4350
  function minimum (l, r : UNRESOLVED_ufixed) return UNRESOLVED_ufixed is
4351
    constant left_index       : INTEGER := maximum(l'high, r'high);
4352
    constant right_index      : INTEGER := mins(l'low, r'low);
4353
    variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
4354
  begin
4355
    if (l'length < 1 or r'length < 1) then
4356
      return NAUF;
4357
    end if;
4358
    lresize := resize (l, left_index, right_index);
4359
    rresize := resize (r, left_index, right_index);
4360
    if lresize > rresize then return rresize;
4361
    else return lresize;
4362
    end if;
4363
  end function minimum;
4364
 
4365
  function minimum (l, r : UNRESOLVED_sfixed) return UNRESOLVED_sfixed is
4366
    constant left_index       : INTEGER := maximum(l'high, r'high);
4367
    constant right_index      : INTEGER := mins(l'low, r'low);
4368
    variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
4369
  begin
4370
    if (l'length < 1 or r'length < 1) then
4371
      return NASF;
4372
    end if;
4373
    lresize := resize (l, left_index, right_index);
4374
    rresize := resize (r, left_index, right_index);
4375
    if lresize > rresize then return rresize;
4376
    else return lresize;
4377
    end if;
4378
  end function minimum;
4379
 
4380
  function to_ufixed (
4381
    arg                     : NATURAL;  -- integer
4382
    constant left_index     : INTEGER;  -- left index (high index)
4383
    constant right_index    : INTEGER                   := 0;  -- right index
4384
    constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
4385
    constant round_style    : fixed_round_style_type    := fixed_round_style)
4386
    return UNRESOLVED_ufixed is
4387
    constant fw      : INTEGER := mins (right_index, right_index);  -- catch literals
4388
    variable result  : UNRESOLVED_ufixed (left_index downto fw);
4389
    variable sresult : UNRESOLVED_ufixed (left_index downto 0) :=
4390
      (others => '0');  -- integer portion
4391
    variable argx    : NATURAL;         -- internal version of arg
4392
  begin
4393
    if (result'length < 1) then
4394
      return NAUF;
4395
    end if;
4396
    if arg /= 0 then
4397
      argx := arg;
4398
      for I in 0 to sresult'left loop
4399
        if (argx mod 2) = 0 then
4400
          sresult(I) := '0';
4401
        else
4402
          sresult(I) := '1';
4403
        end if;
4404
        argx := argx/2;
4405
      end loop;
4406
      if argx /= 0 then
4407
        assert NO_WARNING
4408
          report "fixed_pkg:"
4409
          & "TO_UFIXED(NATURAL): vector truncated"
4410
          severity warning;
4411
        if overflow_style = fixed_saturate then
4412
          return saturate (left_index, right_index);
4413
        end if;
4414
      end if;
4415
      result := resize (arg            => sresult,
4416
                        left_index     => left_index,
4417
                        right_index    => right_index,
4418
                        round_style    => round_style,
4419
                        overflow_style => overflow_style);
4420
    else
4421
      result := (others => '0');
4422
    end if;
4423
    return result;
4424
  end function to_ufixed;
4425
 
4426
  function to_sfixed (
4427
    arg                     : INTEGER;  -- integer
4428
    constant left_index     : INTEGER;  -- left index (high index)
4429
    constant right_index    : INTEGER                   := 0;  -- right index
4430
    constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
4431
    constant round_style    : fixed_round_style_type    := fixed_round_style)
4432
    return UNRESOLVED_sfixed is
4433
    constant fw      : INTEGER := mins (right_index, right_index);  -- catch literals
4434
    variable result  : UNRESOLVED_sfixed (left_index downto fw);
4435
    variable sresult : UNRESOLVED_sfixed (left_index downto 0) :=
4436
      (others => '0');  -- integer portion
4437
    variable argx    : INTEGER;         -- internal version of arg
4438
    variable sign    : STD_ULOGIC;      -- sign of input
4439
  begin
4440
    if (result'length < 1) then         -- null range
4441
      return NASF;
4442
    end if;
4443
    if arg /= 0 then
4444
      if (arg < 0) then
4445
        sign := '1';
4446
        argx := -(arg + 1);
4447
      else
4448
        sign := '0';
4449
        argx := arg;
4450
      end if;
4451
      for I in 0 to sresult'left loop
4452
        if (argx mod 2) = 0 then
4453
          sresult(I) := sign;
4454
        else
4455
          sresult(I) := not sign;
4456
        end if;
4457
        argx := argx/2;
4458
      end loop;
4459
      if argx /= 0 or left_index < 0 or sign /= sresult(sresult'left) then
4460
        assert NO_WARNING
4461
          report "fixed_pkg:"
4462
          & "TO_SFIXED(INTEGER): vector truncated"
4463
          severity warning;
4464
        if overflow_style = fixed_saturate then                -- saturate
4465
          if arg < 0 then
4466
            result := not saturate (result'high, result'low);  -- underflow
4467
          else
4468
            result := saturate (result'high, result'low);      -- overflow
4469
          end if;
4470
          return result;
4471
        end if;
4472
      end if;
4473
      result := resize (arg            => sresult,
4474
                        left_index     => left_index,
4475
                        right_index    => right_index,
4476
                        round_style    => round_style,
4477
                        overflow_style => overflow_style);
4478
    else
4479
      result := (others => '0');
4480
    end if;
4481
    return result;
4482
  end function to_sfixed;
4483
 
4484
  function to_ufixed (
4485
    arg                     : REAL;     -- real
4486
    constant left_index     : INTEGER;  -- left index (high index)
4487
    constant right_index    : INTEGER;  -- right index
4488
    constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
4489
    constant round_style    : fixed_round_style_type    := fixed_round_style;
4490
    constant guard_bits     : NATURAL                   := fixed_guard_bits)  -- # of guard bits
4491
    return UNRESOLVED_ufixed is
4492
    constant fw              : INTEGER := mins (right_index, right_index);  -- catch literals
4493
    variable result          : UNRESOLVED_ufixed (left_index downto fw) :=
4494
      (others => '0');
4495
    variable Xresult         : UNRESOLVED_ufixed (left_index downto
4496
                                                  fw-guard_bits) :=
4497
      (others => '0');
4498
    variable presult         : REAL;
4499
--    variable overflow_needed : BOOLEAN;
4500
  begin
4501
    -- If negative or null range, return.
4502
    if (left_index < fw) then
4503
      return NAUF;
4504
    end if;
4505
    if (arg < 0.0) then
4506
      report "fixed_pkg:"
4507
        & "TO_UFIXED: Negative argument passed "
4508
        & REAL'image(arg) severity error;
4509
      return result;
4510
    end if;
4511
    presult := arg;
4512
    if presult >= (2.0**(left_index+1)) then
4513
      assert NO_WARNING report "fixed_pkg:"
4514
        & "TO_UFIXED(REAL): vector truncated"
4515
        severity warning;
4516
      if overflow_style = fixed_wrap then
4517
        presult := presult mod (2.0**(left_index+1));  -- wrap
4518
      else
4519
        return saturate (result'high, result'low);
4520
      end if;
4521
    end if;
4522
    for i in Xresult'range loop
4523
      if presult >= 2.0**i then
4524
        Xresult(i) := '1';
4525
        presult    := presult - 2.0**i;
4526
      else
4527
        Xresult(i) := '0';
4528
      end if;
4529
    end loop;
4530
    if guard_bits > 0 and round_style = fixed_round then
4531
      result := round_fixed (arg => Xresult (left_index
4532
                                             downto right_index),
4533
                             remainder => Xresult (right_index-1 downto
4534
                                                   right_index-guard_bits),
4535
                             overflow_style => overflow_style);
4536
    else
4537
      result := Xresult (result'range);
4538
    end if;
4539
    return result;
4540
  end function to_ufixed;
4541
 
4542
  function to_sfixed (
4543
    arg                     : REAL;     -- real
4544
    constant left_index     : INTEGER;  -- left index (high index)
4545
    constant right_index    : INTEGER;  -- right index
4546
    constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
4547
    constant round_style    : fixed_round_style_type    := fixed_round_style;
4548
    constant guard_bits     : NATURAL                   := fixed_guard_bits)  -- # of guard bits
4549
    return UNRESOLVED_sfixed is
4550
    constant fw     : INTEGER := mins (right_index, right_index);  -- catch literals
4551
    variable result : UNRESOLVED_sfixed (left_index downto fw) :=
4552
      (others => '0');
4553
    variable Xresult : UNRESOLVED_sfixed (left_index+1 downto fw-guard_bits) :=
4554
      (others => '0');
4555
    variable presult : REAL;
4556
  begin
4557
    if (left_index < fw) then           -- null range
4558
      return NASF;
4559
    end if;
4560
    if (arg >= (2.0**left_index) or arg < -(2.0**left_index)) then
4561
      assert NO_WARNING report "fixed_pkg:"
4562
        & "TO_SFIXED(REAL): vector truncated"
4563
        severity warning;
4564
      if overflow_style = fixed_saturate then
4565
        if arg < 0.0 then               -- saturate
4566
          result := not saturate (result'high, result'low);        -- underflow
4567
        else
4568
          result := saturate (result'high, result'low);            -- overflow
4569
        end if;
4570
        return result;
4571
      else
4572
        presult := abs(arg) mod (2.0**(left_index+1));             -- wrap
4573
      end if;
4574
    else
4575
      presult := abs(arg);
4576
    end if;
4577
    for i in Xresult'range loop
4578
      if presult >= 2.0**i then
4579
        Xresult(i) := '1';
4580
        presult    := presult - 2.0**i;
4581
      else
4582
        Xresult(i) := '0';
4583
      end if;
4584
    end loop;
4585
    if arg < 0.0 then
4586
      Xresult := to_fixed(-to_s(Xresult), Xresult'high, Xresult'low);
4587
    end if;
4588
    if guard_bits > 0 and round_style = fixed_round then
4589
      result := round_fixed (arg => Xresult (left_index
4590
                                             downto right_index),
4591
                             remainder => Xresult (right_index-1 downto
4592
                                                   right_index-guard_bits),
4593
                             overflow_style => overflow_style);
4594
    else
4595
      result := Xresult (result'range);
4596
    end if;
4597
    return result;
4598
  end function to_sfixed;
4599
 
4600
  function to_ufixed (
4601
    arg                     : UNSIGNED;             -- unsigned
4602
    constant left_index     : INTEGER;  -- left index (high index)
4603
    constant right_index    : INTEGER                   := 0;  -- right index
4604
    constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
4605
    constant round_style    : fixed_round_style_type    := fixed_round_style)
4606
    return UNRESOLVED_ufixed is
4607
    constant ARG_LEFT : INTEGER := ARG'length-1;
4608
    alias XARG        : UNSIGNED(ARG_LEFT downto 0) is ARG;
4609
    variable result   : UNRESOLVED_ufixed (left_index downto right_index);
4610
  begin
4611
    if arg'length < 1 or (left_index < right_index) then
4612
      return NAUF;
4613
    end if;
4614
    result := resize (arg            => UNRESOLVED_ufixed (XARG),
4615
                      left_index     => left_index,
4616
                      right_index    => right_index,
4617
                      round_style    => round_style,
4618
                      overflow_style => overflow_style);
4619
    return result;
4620
  end function to_ufixed;
4621
 
4622
  -- converted version
4623
  function to_ufixed (
4624
    arg : UNSIGNED)          -- unsigned
4625
    return UNRESOLVED_ufixed is
4626
    constant ARG_LEFT : INTEGER := ARG'length-1;
4627
    alias XARG        : UNSIGNED(ARG_LEFT downto 0) is ARG;
4628
  begin
4629
    if arg'length < 1 then
4630
      return NAUF;
4631
    end if;
4632
    return UNRESOLVED_ufixed(xarg);
4633
  end function to_ufixed;
4634
 
4635
  function to_sfixed (
4636
    arg                     : SIGNED;               -- signed
4637
    constant left_index     : INTEGER;  -- left index (high index)
4638
    constant right_index    : INTEGER                   := 0;  -- right index
4639
    constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
4640
    constant round_style    : fixed_round_style_type    := fixed_round_style)
4641
    return UNRESOLVED_sfixed is
4642
    constant ARG_LEFT : INTEGER := ARG'length-1;
4643
    alias XARG        : SIGNED(ARG_LEFT downto 0) is ARG;
4644
    variable result   : UNRESOLVED_sfixed (left_index downto right_index);
4645
  begin
4646
    if arg'length < 1 or (left_index < right_index) then
4647
      return NASF;
4648
    end if;
4649
    result := resize (arg            => UNRESOLVED_sfixed (XARG),
4650
                      left_index     => left_index,
4651
                      right_index    => right_index,
4652
                      round_style    => round_style,
4653
                      overflow_style => overflow_style);
4654
    return result;
4655
  end function to_sfixed;
4656
 
4657
  -- converted version
4658
  function to_sfixed (
4659
    arg : SIGNED)            -- signed
4660
    return UNRESOLVED_sfixed is
4661
    constant ARG_LEFT : INTEGER := ARG'length-1;
4662
    alias XARG        : SIGNED(ARG_LEFT downto 0) is ARG;
4663
  begin
4664
    if arg'length < 1 then
4665
      return NASF;
4666
    end if;
4667
    return UNRESOLVED_sfixed(xarg);
4668
  end function to_sfixed;
4669
 
4670
  function to_sfixed (arg : UNRESOLVED_ufixed) return UNRESOLVED_sfixed is
4671
    variable result : UNRESOLVED_sfixed (arg'high+1 downto arg'low);
4672
  begin
4673
    if arg'length < 1 then
4674
      return NASF;
4675
    end if;
4676
    result (arg'high downto arg'low) := UNRESOLVED_sfixed(cleanvec(arg));
4677
    result (arg'high+1)              := '0';
4678
    return result;
4679
  end function to_sfixed;
4680
 
4681
  -- Because of the fairly complicated sizing rules in the fixed point
4682
  -- packages these functions are provided to compute the result ranges
4683
  -- Example:
4684
  -- signal uf1 : ufixed (3 downto -3);
4685
  -- signal uf2 : ufixed (4 downto -2);
4686
  -- signal uf1multuf2 : ufixed (ufixed_high (3, -3, '*', 4, -2) downto
4687
  --                             ufixed_low (3, -3, '*', 4, -2));
4688
  -- uf1multuf2 <= uf1 * uf2;
4689
  -- Valid characters: '+', '-', '*', '/', 'r' or 'R' (rem), 'm' or 'M' (mod),
4690
  -- '1' (reciprocal), 'A', 'a' (abs), 'N', 'n' (-sfixed)
4691
  function ufixed_high (left_index, right_index   : INTEGER;
4692
                        operation                 : CHARACTER := 'X';
4693
                        left_index2, right_index2 : INTEGER   := 0)
4694
    return INTEGER is
4695
  begin
4696
    case operation is
4697
      when '+'| '-' => return maximum (left_index, left_index2) + 1;
4698
      when '*'      => return left_index + left_index2 + 1;
4699
      when '/'      => return left_index - right_index2;
4700
      when '1'      => return -right_index;                    -- reciprocal
4701
      when 'R'|'r'  => return mins (left_index, left_index2);  -- "rem"
4702
      when 'M'|'m'  => return mins (left_index, left_index2);  -- "mod"
4703
      when others   => return left_index;  -- For abs and default
4704
    end case;
4705
  end function ufixed_high;
4706
 
4707
  function ufixed_low (left_index, right_index   : INTEGER;
4708
                       operation                 : CHARACTER := 'X';
4709
                       left_index2, right_index2 : INTEGER   := 0)
4710
    return INTEGER is
4711
  begin
4712
    case operation is
4713
      when '+'| '-' => return mins (right_index, right_index2);
4714
      when '*'      => return right_index + right_index2;
4715
      when '/'      => return right_index - left_index2 - 1;
4716
      when '1'      => return -left_index - 1;                   -- reciprocal
4717
      when 'R'|'r'  => return mins (right_index, right_index2);  -- "rem"
4718
      when 'M'|'m'  => return mins (right_index, right_index2);  -- "mod"
4719
      when others   => return right_index;  -- for abs and default
4720
    end case;
4721
  end function ufixed_low;
4722
 
4723
  function sfixed_high (left_index, right_index   : INTEGER;
4724
                        operation                 : CHARACTER := 'X';
4725
                        left_index2, right_index2 : INTEGER   := 0)
4726
    return INTEGER is
4727
  begin
4728
    case operation is
4729
      when '+'| '-' => return maximum (left_index, left_index2) + 1;
4730
      when '*'      => return left_index + left_index2 + 1;
4731
      when '/'      => return left_index - right_index2 + 1;
4732
      when '1'      => return -right_index + 1;                -- reciprocal
4733
      when 'R'|'r'  => return mins (left_index, left_index2);  -- "rem"
4734
      when 'M'|'m'  => return left_index2;                     -- "mod"
4735
      when 'A'|'a'  => return left_index + 1;                  -- "abs"
4736
      when 'N'|'n'  => return left_index + 1;                  -- -sfixed
4737
      when others   => return left_index;
4738
    end case;
4739
  end function sfixed_high;
4740
 
4741
  function sfixed_low (left_index, right_index   : INTEGER;
4742
                       operation                 : CHARACTER := 'X';
4743
                       left_index2, right_index2 : INTEGER   := 0)
4744
    return INTEGER is
4745
  begin
4746
    case operation is
4747
      when '+'| '-' => return mins (right_index, right_index2);
4748
      when '*'      => return right_index + right_index2;
4749
      when '/'      => return right_index - left_index2;
4750
      when '1'      => return -left_index;  -- reciprocal
4751
      when 'R'|'r'  => return mins (right_index, right_index2);  -- "rem"
4752
      when 'M'|'m'  => return mins (right_index, right_index2);  -- "mod"
4753
      when others   => return right_index;  -- default for abs, neg and default
4754
    end case;
4755
  end function sfixed_low;
4756
 
4757
  -- Same as above, but using the "size_res" input only for their ranges:
4758
  -- signal uf1multuf2 : ufixed (ufixed_high (uf1, '*', uf2) downto
4759
  --                             ufixed_low (uf1, '*', uf2));
4760
  -- uf1multuf2 <= uf1 * uf2;  
4761
  function ufixed_high (size_res  : UNRESOLVED_ufixed;
4762
                        operation : CHARACTER := 'X';
4763
                        size_res2 : UNRESOLVED_ufixed)
4764
    return INTEGER is
4765
  begin
4766
    return ufixed_high (left_index   => size_res'high,
4767
                        right_index  => size_res'low,
4768
                        operation    => operation,
4769
                        left_index2  => size_res2'high,
4770
                        right_index2 => size_res2'low);
4771
  end function ufixed_high;
4772
 
4773
  function ufixed_low (size_res  : UNRESOLVED_ufixed;
4774
                       operation : CHARACTER := 'X';
4775
                       size_res2 : UNRESOLVED_ufixed)
4776
    return INTEGER is
4777
  begin
4778
    return ufixed_low (left_index   => size_res'high,
4779
                       right_index  => size_res'low,
4780
                       operation    => operation,
4781
                       left_index2  => size_res2'high,
4782
                       right_index2 => size_res2'low);
4783
  end function ufixed_low;
4784
 
4785
  function sfixed_high (size_res  : UNRESOLVED_sfixed;
4786
                        operation : CHARACTER := 'X';
4787
                        size_res2 : UNRESOLVED_sfixed)
4788
    return INTEGER is
4789
  begin
4790
    return sfixed_high (left_index   => size_res'high,
4791
                        right_index  => size_res'low,
4792
                        operation    => operation,
4793
                        left_index2  => size_res2'high,
4794
                        right_index2 => size_res2'low);
4795
  end function sfixed_high;
4796
 
4797
  function sfixed_low (size_res  : UNRESOLVED_sfixed;
4798
                       operation : CHARACTER := 'X';
4799
                       size_res2 : UNRESOLVED_sfixed)
4800
    return INTEGER is
4801
  begin
4802
    return sfixed_low (left_index   => size_res'high,
4803
                       right_index  => size_res'low,
4804
                       operation    => operation,
4805
                       left_index2  => size_res2'high,
4806
                       right_index2 => size_res2'low);
4807
  end function sfixed_low;
4808
 
4809
  -- purpose: returns a saturated number
4810
  function saturate (
4811
    constant left_index  : INTEGER;
4812
    constant right_index : INTEGER)
4813
    return UNRESOLVED_ufixed is
4814
    constant sat : UNRESOLVED_ufixed (left_index downto right_index) :=
4815
      (others => '1');
4816
  begin
4817
    return sat;
4818
  end function saturate;
4819
 
4820
  -- purpose: returns a saturated number
4821
  function saturate (
4822
    constant left_index  : INTEGER;
4823
    constant right_index : INTEGER)
4824
    return UNRESOLVED_sfixed is
4825
    variable sat : UNRESOLVED_sfixed (left_index downto right_index) :=
4826
      (others => '1');
4827
  begin
4828
    -- saturate positive, to saturate negative, just do "not saturate()"
4829
    sat (left_index) := '0';
4830
    return sat;
4831
  end function saturate;
4832
 
4833
  function saturate (
4834
    size_res : UNRESOLVED_ufixed)       -- only the size of this is used
4835
    return UNRESOLVED_ufixed is
4836
  begin
4837
    return saturate (size_res'high, size_res'low);
4838
  end function saturate;
4839
 
4840
  function saturate (
4841
    size_res : UNRESOLVED_sfixed)       -- only the size of this is used
4842
    return UNRESOLVED_sfixed is
4843
  begin
4844
    return saturate (size_res'high, size_res'low);
4845
  end function saturate;
4846
 
4847
  -- As a concession to those who use a graphical DSP environment,
4848
  -- these functions take parameters in those tools format and create
4849
  -- fixed point numbers.  These functions are designed to convert from
4850
  -- a std_logic_vector to the VHDL fixed point format using the conventions
4851
  -- of these packages.  In a pure VHDL environment you should use the
4852
  -- "to_ufixed" and "to_sfixed" routines.
4853
  -- Unsigned fixed point
4854
  function to_UFix (
4855
    arg      : STD_ULOGIC_VECTOR;
4856
    width    : NATURAL;                 -- width of vector
4857
    fraction : NATURAL)                 -- width of fraction
4858
    return UNRESOLVED_ufixed is
4859
    variable result : UNRESOLVED_ufixed (width-fraction-1 downto -fraction);
4860
  begin
4861
    if (arg'length /= result'length) then
4862
      report "fixed_pkg:"
4863
        & "TO_UFIX (STD_ULOGIC_VECTOR) "
4864
        & "Vector lengths do not match.  Input length is "
4865
        & INTEGER'image(arg'length) & " and output will be "
4866
        & INTEGER'image(result'length) & " wide."
4867
        severity error;
4868
      return NAUF;
4869
    else
4870
      result := to_ufixed (arg, result'high, result'low);
4871
      return result;
4872
    end if;
4873
  end function to_UFix;
4874
 
4875
  -- signed fixed point
4876
  function to_SFix (
4877
    arg      : STD_ULOGIC_VECTOR;
4878
    width    : NATURAL;                 -- width of vector
4879
    fraction : NATURAL)                 -- width of fraction
4880
    return UNRESOLVED_sfixed is
4881
    variable result : UNRESOLVED_sfixed (width-fraction-1 downto -fraction);
4882
  begin
4883
    if (arg'length /= result'length) then
4884
      report "fixed_pkg:"
4885
        & "TO_SFIX (STD_ULOGIC_VECTOR) "
4886
        & "Vector lengths do not match.  Input length is "
4887
        & INTEGER'image(arg'length) & " and output will be "
4888
        & INTEGER'image(result'length) & " wide."
4889
        severity error;
4890
      return NASF;
4891
    else
4892
      result := to_sfixed (arg, result'high, result'low);
4893
      return result;
4894
    end if;
4895
  end function to_SFix;
4896
 
4897
  -- finding the bounds of a number.  These functions can be used like this:
4898
  -- signal xxx : ufixed (7 downto -3);
4899
  -- -- Which is the same as "ufixed (UFix_high (11,3) downto UFix_low(11,3))"
4900
  -- signal yyy : ufixed (UFix_high (11, 3, "+", 11, 3)
4901
  --               downto UFix_low(11, 3, "+", 11, 3));
4902
  -- Where "11" is the width of xxx (xxx'length),
4903
  -- and 3 is the lower bound (abs (xxx'low))
4904
  -- In a pure VHDL environment use "ufixed_high" and "ufixed_low"
4905
  function ufix_high (
4906
    width, fraction   : NATURAL;
4907
    operation         : CHARACTER := 'X';
4908
    width2, fraction2 : NATURAL   := 0)
4909
    return INTEGER is
4910
  begin
4911
    return ufixed_high (left_index   => width - 1 - fraction,
4912
                        right_index  => -fraction,
4913
                        operation    => operation,
4914
                        left_index2  => width2 - 1 - fraction2,
4915
                        right_index2 => -fraction2);
4916
  end function ufix_high;
4917
 
4918
  function ufix_low (
4919
    width, fraction   : NATURAL;
4920
    operation         : CHARACTER := 'X';
4921
    width2, fraction2 : NATURAL   := 0)
4922
    return INTEGER is
4923
  begin
4924
    return ufixed_low (left_index   => width - 1 - fraction,
4925
                       right_index  => -fraction,
4926
                       operation    => operation,
4927
                       left_index2  => width2 - 1 - fraction2,
4928
                       right_index2 => -fraction2);
4929
  end function ufix_low;
4930
 
4931
  function sfix_high (
4932
    width, fraction   : NATURAL;
4933
    operation         : CHARACTER := 'X';
4934
    width2, fraction2 : NATURAL   := 0)
4935
    return INTEGER is
4936
  begin
4937
    return sfixed_high (left_index   => width - fraction,
4938
                        right_index  => -fraction,
4939
                        operation    => operation,
4940
                        left_index2  => width2 - fraction2,
4941
                        right_index2 => -fraction2);
4942
  end function sfix_high;
4943
 
4944
  function sfix_low (
4945
    width, fraction   : NATURAL;
4946
    operation         : CHARACTER := 'X';
4947
    width2, fraction2 : NATURAL   := 0)
4948
    return INTEGER is
4949
  begin
4950
    return sfixed_low (left_index   => width - fraction,
4951
                       right_index  => -fraction,
4952
                       operation    => operation,
4953
                       left_index2  => width2 - fraction2,
4954
                       right_index2 => -fraction2);
4955
  end function sfix_low;
4956
 
4957
  function to_unsigned (
4958
    arg                     : UNRESOLVED_ufixed;  -- ufixed point input
4959
    constant size           : NATURAL;            -- length of output
4960
    constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
4961
    constant round_style    : fixed_round_style_type    := fixed_round_style)
4962
    return UNSIGNED is
4963
  begin
4964
    return to_uns(resize (arg            => arg,
4965
                          left_index     => size-1,
4966
                          right_index    => 0,
4967
                          round_style    => round_style,
4968
                          overflow_style => overflow_style));
4969
  end function to_unsigned;
4970
 
4971
  function to_unsigned (
4972
    arg                     : UNRESOLVED_ufixed;    -- ufixed point input
4973
    size_res                : UNSIGNED;  -- length of output
4974
    constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
4975
    constant round_style    : fixed_round_style_type    := fixed_round_style)
4976
    return UNSIGNED is
4977
  begin
4978
    return to_unsigned (arg            => arg,
4979
                        size           => size_res'length,
4980
                        round_style    => round_style,
4981
                        overflow_style => overflow_style);
4982
  end function to_unsigned;
4983
 
4984
  function to_signed (
4985
    arg                     : UNRESOLVED_sfixed;  -- sfixed point input
4986
    constant size           : NATURAL;            -- length of output
4987
    constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
4988
    constant round_style    : fixed_round_style_type    := fixed_round_style)
4989
    return SIGNED is
4990
  begin
4991
    return to_s(resize (arg            => arg,
4992
                        left_index     => size-1,
4993
                        right_index    => 0,
4994
                        round_style    => round_style,
4995
                        overflow_style => overflow_style));
4996
  end function to_signed;
4997
 
4998
  function to_signed (
4999
    arg                     : UNRESOLVED_sfixed;  -- sfixed point input
5000
    size_res                : SIGNED;  -- used for length of output
5001
    constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
5002
    constant round_style    : fixed_round_style_type    := fixed_round_style)
5003
    return SIGNED is
5004
  begin
5005
    return to_signed (arg            => arg,
5006
                      size           => size_res'length,
5007
                      round_style    => round_style,
5008
                      overflow_style => overflow_style);
5009
  end function to_signed;
5010
 
5011
  function to_real (
5012
    arg : UNRESOLVED_ufixed)            -- ufixed point input
5013
    return REAL is
5014
    constant left_index  : INTEGER := arg'high;
5015
    constant right_index : INTEGER := arg'low;
5016
    variable result      : REAL;        -- result
5017
    variable arg_int     : UNRESOLVED_ufixed (left_index downto right_index);
5018
  begin
5019
    if (arg'length < 1) then
5020
      return 0.0;
5021
    end if;
5022
    arg_int := to_x01(cleanvec(arg));
5023
    if (Is_X(arg_int)) then
5024
      assert NO_WARNING
5025
        report "fixed_pkg:"
5026
        & "TO_REAL (ufixed): metavalue detected, returning 0.0"
5027
        severity warning;
5028
      return 0.0;
5029
    end if;
5030
    result := 0.0;
5031
    for i in arg_int'range loop
5032
      if (arg_int(i) = '1') then
5033
        result := result + (2.0**i);
5034
      end if;
5035
    end loop;
5036
    return result;
5037
  end function to_real;
5038
 
5039
  function to_real (
5040
    arg : UNRESOLVED_sfixed)            -- ufixed point input
5041
    return REAL is
5042
    constant left_index  : INTEGER := arg'high;
5043
    constant right_index : INTEGER := arg'low;
5044
    variable result      : REAL;        -- result
5045
    variable arg_int     : UNRESOLVED_sfixed (left_index downto right_index);
5046
    -- unsigned version of argument
5047
    variable arg_uns     : UNRESOLVED_ufixed (left_index downto right_index);
5048
    -- absolute of argument
5049
  begin
5050
    if (arg'length < 1) then
5051
      return 0.0;
5052
    end if;
5053
    arg_int := to_x01(cleanvec(arg));
5054
    if (Is_X(arg_int)) then
5055
      assert NO_WARNING
5056
        report "fixed_pkg:"
5057
        & "TO_REAL (sfixed): metavalue detected, returning 0.0"
5058
        severity warning;
5059
      return 0.0;
5060
    end if;
5061
    arg_uns := to_ufixed (arg_int);
5062
    result  := to_real (arg_uns);
5063
    if (arg_int(arg_int'high) = '1') then
5064
      result := -result;
5065
    end if;
5066
    return result;
5067
  end function to_real;
5068
 
5069
  function to_integer (
5070
    arg                     : UNRESOLVED_ufixed;  -- fixed point input
5071
    constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
5072
    constant round_style    : fixed_round_style_type    := fixed_round_style)
5073
    return NATURAL is
5074
    constant left_index : INTEGER := arg'high;
5075
    variable arg_uns    : UNSIGNED (left_index+1 downto 0)
5076
      := (others => '0');
5077
  begin
5078
    if (arg'length < 1) then
5079
      return 0;
5080
    end if;
5081
    if (Is_X (arg)) then
5082
      assert NO_WARNING
5083
        report "fixed_pkg:"
5084
        & "TO_INTEGER (ufixed): metavalue detected, returning 0"
5085
        severity warning;
5086
      return 0;
5087
    end if;
5088
    if (left_index < -1) then
5089
      return 0;
5090
    end if;
5091
    arg_uns := to_uns(resize (arg            => arg,
5092
                              left_index     => arg_uns'high,
5093
                              right_index    => 0,
5094
                              round_style    => round_style,
5095
                              overflow_style => overflow_style));
5096
    return to_integer (arg_uns);
5097
  end function to_integer;
5098
 
5099
  function to_integer (
5100
    arg                     : UNRESOLVED_sfixed;  -- fixed point input
5101
    constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
5102
    constant round_style    : fixed_round_style_type    := fixed_round_style)
5103
    return INTEGER is
5104
    constant left_index  : INTEGER := arg'high;
5105
    constant right_index : INTEGER := arg'low;
5106
    variable arg_s       : SIGNED (left_index+1 downto 0);
5107
  begin
5108
    if (arg'length < 1) then
5109
      return 0;
5110
    end if;
5111
    if (Is_X (arg)) then
5112
      assert NO_WARNING
5113
        report "fixed_pkg:"
5114
        & "TO_INTEGER (sfixed): metavalue detected, returning 0"
5115
        severity warning;
5116
      return 0;
5117
    end if;
5118
    if (left_index < -1) then
5119
      return 0;
5120
    end if;
5121
    arg_s := to_s(resize (arg            => arg,
5122
                          left_index     => arg_s'high,
5123
                          right_index    => 0,
5124
                          round_style    => round_style,
5125
                          overflow_style => overflow_style));
5126
    return to_integer (arg_s);
5127
  end function to_integer;
5128
 
5129
  function to_01 (
5130
    s             : UNRESOLVED_ufixed;              -- ufixed point input
5131
    constant XMAP : STD_ULOGIC := '0')              -- Map x to
5132
    return UNRESOLVED_ufixed is
5133
    variable result : UNRESOLVED_ufixed (s'range);  -- result
5134
  begin
5135
    if (s'length < 1) then
5136
      assert NO_WARNING
5137
        report "fixed_pkg:"
5138
        & "TO_01(ufixed): null detected, returning NULL"
5139
        severity warning;
5140
      return NAUF;
5141
    end if;
5142
    return to_fixed (to_01(to_uns(s), XMAP), s'high, s'low);
5143
  end function to_01;
5144
 
5145
  function to_01 (
5146
    s             : UNRESOLVED_sfixed;  -- sfixed point input
5147
    constant XMAP : STD_ULOGIC := '0')  -- Map x to
5148
    return UNRESOLVED_sfixed is
5149
    variable result : UNRESOLVED_sfixed (s'range);
5150
  begin
5151
    if (s'length < 1) then
5152
      assert NO_WARNING
5153
        report "fixed_pkg:"
5154
        & "TO_01(sfixed): null detected, returning NULL"
5155
        severity warning;
5156
      return NASF;
5157
    end if;
5158
    return to_fixed (to_01(to_s(s), XMAP), s'high, s'low);
5159
  end function to_01;
5160
 
5161
  function Is_X (
5162
    arg : UNRESOLVED_ufixed)
5163
    return BOOLEAN is
5164
    variable argslv : STD_ULOGIC_VECTOR (arg'length-1 downto 0);  -- slv
5165
  begin
5166
    argslv := to_sulv(arg);
5167
    return Is_X (argslv);
5168
  end function Is_X;
5169
 
5170
  function Is_X (
5171
    arg : UNRESOLVED_sfixed)
5172
    return BOOLEAN is
5173
    variable argslv : STD_ULOGIC_VECTOR (arg'length-1 downto 0);  -- slv
5174
  begin
5175
    argslv := to_sulv(arg);
5176
    return Is_X (argslv);
5177
  end function Is_X;
5178
 
5179
  function To_X01 (
5180
    arg : UNRESOLVED_ufixed)
5181
    return UNRESOLVED_ufixed is
5182
  begin
5183
    return to_ufixed (To_X01(to_sulv(arg)), arg'high, arg'low);
5184
  end function To_X01;
5185
 
5186
  function to_X01 (
5187
    arg : UNRESOLVED_sfixed)
5188
    return UNRESOLVED_sfixed is
5189
  begin
5190
    return to_sfixed (To_X01(to_sulv(arg)), arg'high, arg'low);
5191
  end function To_X01;
5192
 
5193
  function To_X01Z (
5194
    arg : UNRESOLVED_ufixed)
5195
    return UNRESOLVED_ufixed is
5196
  begin
5197
    return to_ufixed (To_X01Z(to_sulv(arg)), arg'high, arg'low);
5198
  end function To_X01Z;
5199
 
5200
  function to_X01Z (
5201
    arg : UNRESOLVED_sfixed)
5202
    return UNRESOLVED_sfixed is
5203
  begin
5204
    return to_sfixed (To_X01Z(to_sulv(arg)), arg'high, arg'low);
5205
  end function To_X01Z;
5206
 
5207
  function To_UX01 (
5208
    arg : UNRESOLVED_ufixed)
5209
    return UNRESOLVED_ufixed is
5210
  begin
5211
    return to_ufixed (To_UX01(to_sulv(arg)), arg'high, arg'low);
5212
  end function To_UX01;
5213
 
5214
  function to_UX01 (
5215
    arg : UNRESOLVED_sfixed)
5216
    return UNRESOLVED_sfixed is
5217
  begin
5218
    return to_sfixed (To_UX01(to_sulv(arg)), arg'high, arg'low);
5219
  end function To_UX01;
5220
 
5221
  function resize (
5222
    arg                     : UNRESOLVED_ufixed;            -- input
5223
    constant left_index     : INTEGER;  -- integer portion
5224
    constant right_index    : INTEGER;  -- size of fraction
5225
    constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
5226
    constant round_style    : fixed_round_style_type    := fixed_round_style)
5227
    return UNRESOLVED_ufixed is
5228
    constant arghigh : INTEGER := maximum (arg'high, arg'low);
5229
    constant arglow  : INTEGER := mine (arg'high, arg'low);
5230
    variable invec   : UNRESOLVED_ufixed (arghigh downto arglow);
5231
    variable result  : UNRESOLVED_ufixed(left_index downto right_index) :=
5232
      (others => '0');
5233
    variable needs_rounding : BOOLEAN := false;
5234
  begin  -- resize
5235
    if (arg'length < 1) or (result'length < 1) then
5236
      return NAUF;
5237
    elsif (invec'length < 1) then
5238
      return result;                    -- string literal value
5239
    else
5240
      invec := cleanvec(arg);
5241
      if (right_index > arghigh) then   -- return top zeros
5242
        needs_rounding := (round_style = fixed_round) and
5243
                          (right_index = arghigh+1);
5244
      elsif (left_index < arglow) then  -- return overflow
5245
        if (overflow_style = fixed_saturate) and
5246
          (or_reduce(to_sulv(invec)) = '1') then
5247
          result := saturate (result'high, result'low);     -- saturate
5248
        end if;
5249
      elsif (arghigh > left_index) then
5250
        -- wrap or saturate?
5251
        if (overflow_style = fixed_saturate and
5252
            or_reduce (to_sulv(invec(arghigh downto left_index+1))) = '1')
5253
        then
5254
          result := saturate (result'high, result'low);     -- saturate
5255
        else
5256
          if (arglow >= right_index) then
5257
            result (left_index downto arglow) :=
5258
              invec(left_index downto arglow);
5259
          else
5260
            result (left_index downto right_index) :=
5261
              invec (left_index downto right_index);
5262
            needs_rounding := (round_style = fixed_round);  -- round
5263
          end if;
5264
        end if;
5265
      else                              -- arghigh <= integer width
5266
        if (arglow >= right_index) then
5267
          result (arghigh downto arglow) := invec;
5268
        else
5269
          result (arghigh downto right_index) :=
5270
            invec (arghigh downto right_index);
5271
          needs_rounding := (round_style = fixed_round);    -- round
5272
        end if;
5273
      end if;
5274
      -- Round result
5275
      if needs_rounding then
5276
        result := round_fixed (arg            => result,
5277
                               remainder      => invec (right_index-1
5278
                                                        downto arglow),
5279
                               overflow_style => overflow_style);
5280
      end if;
5281
      return result;
5282
    end if;
5283
  end function resize;
5284
 
5285
  function resize (
5286
    arg                     : UNRESOLVED_sfixed;          -- input
5287
    constant left_index     : INTEGER;  -- integer portion
5288
    constant right_index    : INTEGER;  -- size of fraction
5289
    constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
5290
    constant round_style    : fixed_round_style_type    := fixed_round_style)
5291
    return UNRESOLVED_sfixed is
5292
    constant arghigh : INTEGER := maximum (arg'high, arg'low);
5293
    constant arglow  : INTEGER := mine (arg'high, arg'low);
5294
    variable invec   : UNRESOLVED_sfixed (arghigh downto arglow);
5295
    variable result  : UNRESOLVED_sfixed(left_index downto right_index) :=
5296
      (others => '0');
5297
    variable reduced        : STD_ULOGIC;
5298
    variable needs_rounding : BOOLEAN := false;           -- rounding
5299
  begin  -- resize
5300
    if (arg'length < 1) or (result'length < 1) then
5301
      return NASF;
5302
    elsif (invec'length < 1) then
5303
      return result;                    -- string literal value
5304
    else
5305
      invec := cleanvec(arg);
5306
      if (right_index > arghigh) then   -- return top zeros
5307
        if (arg'low /= INTEGER'low) then  -- check for a literal
5308
          result := (others => arg(arghigh));             -- sign extend
5309
        end if;
5310
        needs_rounding := (round_style = fixed_round) and
5311
                          (right_index = arghigh+1);
5312
      elsif (left_index < arglow) then  -- return overflow
5313
        if (overflow_style = fixed_saturate) then
5314
          reduced := or_reduce (to_sulv(invec));
5315
          if (reduced = '1') then
5316
            if (invec(arghigh) = '0') then
5317
              -- saturate POSITIVE
5318
              result := saturate (result'high, result'low);
5319
            else
5320
              -- saturate negative
5321
              result := not saturate (result'high, result'low);
5322
            end if;
5323
            -- else return 0 (input was 0)
5324
          end if;
5325
          -- else return 0 (wrap)
5326
        end if;
5327
      elsif (arghigh > left_index) then
5328
        if (invec(arghigh) = '0') then
5329
          reduced := or_reduce (to_sulv(invec(arghigh-1 downto
5330
                                             left_index)));
5331
          if overflow_style = fixed_saturate and reduced = '1' then
5332
            -- saturate positive
5333
            result := saturate (result'high, result'low);
5334
          else
5335
            if (right_index > arglow) then
5336
              result         := invec (left_index downto right_index);
5337
              needs_rounding := (round_style = fixed_round);
5338
            else
5339
              result (left_index downto arglow) :=
5340
                invec (left_index downto arglow);
5341
            end if;
5342
          end if;
5343
        else
5344
          reduced := and_reduce (to_sulv(invec(arghigh-1 downto
5345
                                              left_index)));
5346
          if overflow_style = fixed_saturate and reduced = '0' then
5347
            result := not saturate (result'high, result'low);
5348
          else
5349
            if (right_index > arglow) then
5350
              result         := invec (left_index downto right_index);
5351
              needs_rounding := (round_style = fixed_round);
5352
            else
5353
              result (left_index downto arglow) :=
5354
                invec (left_index downto arglow);
5355
            end if;
5356
          end if;
5357
        end if;
5358
      else                              -- arghigh <= integer width
5359
        if (arglow >= right_index) then
5360
          result (arghigh downto arglow) := invec;
5361
        else
5362
          result (arghigh downto right_index) :=
5363
            invec (arghigh downto right_index);
5364
          needs_rounding := (round_style = fixed_round);  -- round
5365
        end if;
5366
        if (left_index > arghigh) then  -- sign extend
5367
          result(left_index downto arghigh+1) := (others => invec(arghigh));
5368
        end if;
5369
      end if;
5370
      -- Round result
5371
      if (needs_rounding) then
5372
        result := round_fixed (arg            => result,
5373
                               remainder      => invec (right_index-1
5374
                                                        downto arglow),
5375
                               overflow_style => overflow_style);
5376
      end if;
5377
      return result;
5378
    end if;
5379
  end function resize;
5380
 
5381
  -- size_res functions
5382
  -- These functions compute the size from a passed variable named "size_res"
5383
  -- The only part of this variable used it it's size, it is never passed
5384
  -- to a lower level routine.
5385
  function to_ufixed (
5386
    arg      : STD_ULOGIC_VECTOR;       -- shifted vector
5387
    size_res : UNRESOLVED_ufixed)       -- for size only
5388
    return UNRESOLVED_ufixed is
5389
    constant fw     : INTEGER := mine (size_res'low, size_res'low);  -- catch literals
5390
    variable result : UNRESOLVED_ufixed (size_res'left downto fw);
5391
  begin
5392
    if (result'length < 1 or arg'length < 1) then
5393
      return NAUF;
5394
    else
5395
      result := to_ufixed (arg         => arg,
5396
                           left_index  => size_res'high,
5397
                           right_index => size_res'low);
5398
      return result;
5399
    end if;
5400
  end function to_ufixed;
5401
 
5402
  function to_sfixed (
5403
    arg      : STD_ULOGIC_VECTOR;       -- shifted vector
5404
    size_res : UNRESOLVED_sfixed)       -- for size only
5405
    return UNRESOLVED_sfixed is
5406
    constant fw     : INTEGER := mine (size_res'low, size_res'low);  -- catch literals
5407
    variable result : UNRESOLVED_sfixed (size_res'left downto fw);
5408
  begin
5409
    if (result'length < 1 or arg'length < 1) then
5410
      return NASF;
5411
    else
5412
      result := to_sfixed (arg         => arg,
5413
                           left_index  => size_res'high,
5414
                           right_index => size_res'low);
5415
      return result;
5416
    end if;
5417
  end function to_sfixed;
5418
 
5419
  function to_ufixed (
5420
    arg                     : NATURAL;            -- integer
5421
    size_res                : UNRESOLVED_ufixed;  -- for size only
5422
    constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
5423
    constant round_style    : fixed_round_style_type    := fixed_round_style)
5424
    return UNRESOLVED_ufixed is
5425
    constant fw     : INTEGER := mine (size_res'low, size_res'low);  -- catch literals
5426
    variable result : UNRESOLVED_ufixed (size_res'left downto fw);
5427
  begin
5428
    if (result'length < 1) then
5429
      return NAUF;
5430
    else
5431
      result := to_ufixed (arg            => arg,
5432
                           left_index     => size_res'high,
5433
                           right_index    => size_res'low,
5434
                           round_style    => round_style,
5435
                           overflow_style => overflow_style);
5436
      return result;
5437
    end if;
5438
  end function to_ufixed;
5439
 
5440
  function to_sfixed (
5441
    arg                     : INTEGER;            -- integer
5442
    size_res                : UNRESOLVED_sfixed;  -- for size only
5443
    constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
5444
    constant round_style    : fixed_round_style_type    := fixed_round_style)
5445
    return UNRESOLVED_sfixed is
5446
    constant fw     : INTEGER := mine (size_res'low, size_res'low);  -- catch literals
5447
    variable result : UNRESOLVED_sfixed (size_res'left downto fw);
5448
  begin
5449
    if (result'length < 1) then
5450
      return NASF;
5451
    else
5452
      result := to_sfixed (arg            => arg,
5453
                           left_index     => size_res'high,
5454
                           right_index    => size_res'low,
5455
                           round_style    => round_style,
5456
                           overflow_style => overflow_style);
5457
      return result;
5458
    end if;
5459
  end function to_sfixed;
5460
 
5461
  function to_ufixed (
5462
    arg                     : REAL;     -- real
5463
    size_res                : UNRESOLVED_ufixed;  -- for size only
5464
    constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
5465
    constant round_style    : fixed_round_style_type    := fixed_round_style;
5466
    constant guard_bits     : NATURAL                   := fixed_guard_bits)  -- # of guard bits
5467
    return UNRESOLVED_ufixed is
5468
    constant fw     : INTEGER := mine (size_res'low, size_res'low);  -- catch literals
5469
    variable result : UNRESOLVED_ufixed (size_res'left downto fw);
5470
  begin
5471
    if (result'length < 1) then
5472
      return NAUF;
5473
    else
5474
      result := to_ufixed (arg            => arg,
5475
                           left_index     => size_res'high,
5476
                           right_index    => size_res'low,
5477
                           guard_bits     => guard_bits,
5478
                           round_style    => round_style,
5479
                           overflow_style => overflow_style);
5480
      return result;
5481
    end if;
5482
  end function to_ufixed;
5483
 
5484
  function to_sfixed (
5485
    arg                     : REAL;     -- real
5486
    size_res                : UNRESOLVED_sfixed;  -- for size only
5487
    constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
5488
    constant round_style    : fixed_round_style_type    := fixed_round_style;
5489
    constant guard_bits     : NATURAL                   := fixed_guard_bits)  -- # of guard bits
5490
    return UNRESOLVED_sfixed is
5491
    constant fw     : INTEGER := mine (size_res'low, size_res'low);  -- catch literals
5492
    variable result : UNRESOLVED_sfixed (size_res'left downto fw);
5493
  begin
5494
    if (result'length < 1) then
5495
      return NASF;
5496
    else
5497
      result := to_sfixed (arg            => arg,
5498
                           left_index     => size_res'high,
5499
                           right_index    => size_res'low,
5500
                           guard_bits     => guard_bits,
5501
                           round_style    => round_style,
5502
                           overflow_style => overflow_style);
5503
      return result;
5504
    end if;
5505
  end function to_sfixed;
5506
 
5507
  function to_ufixed (
5508
    arg                     : UNSIGNED;  -- unsigned
5509
    size_res                : UNRESOLVED_ufixed;    -- for size only
5510
    constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
5511
    constant round_style    : fixed_round_style_type    := fixed_round_style)
5512
    return UNRESOLVED_ufixed is
5513
    constant fw     : INTEGER := mine (size_res'low, size_res'low);  -- catch literals
5514
    variable result : UNRESOLVED_ufixed (size_res'left downto fw);
5515
  begin
5516
    if (result'length < 1 or arg'length < 1) then
5517
      return NAUF;
5518
    else
5519
      result := to_ufixed (arg            => arg,
5520
                           left_index     => size_res'high,
5521
                           right_index    => size_res'low,
5522
                           round_style    => round_style,
5523
                           overflow_style => overflow_style);
5524
      return result;
5525
    end if;
5526
  end function to_ufixed;
5527
 
5528
  function to_sfixed (
5529
    arg                     : SIGNED;  -- signed
5530
    size_res                : UNRESOLVED_sfixed;  -- for size only
5531
    constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
5532
    constant round_style    : fixed_round_style_type    := fixed_round_style)
5533
    return UNRESOLVED_sfixed is
5534
    constant fw     : INTEGER := mine (size_res'low, size_res'low);  -- catch literals
5535
    variable result : UNRESOLVED_sfixed (size_res'left downto fw);
5536
  begin
5537
    if (result'length < 1 or arg'length < 1) then
5538
      return NASF;
5539
    else
5540
      result := to_sfixed (arg            => arg,
5541
                           left_index     => size_res'high,
5542
                           right_index    => size_res'low,
5543
                           round_style    => round_style,
5544
                           overflow_style => overflow_style);
5545
      return result;
5546
    end if;
5547
  end function to_sfixed;
5548
 
5549
  function resize (
5550
    arg                     : UNRESOLVED_ufixed;  -- input
5551
    size_res                : UNRESOLVED_ufixed;  -- for size only
5552
    constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
5553
    constant round_style    : fixed_round_style_type    := fixed_round_style)
5554
    return UNRESOLVED_ufixed is
5555
    constant fw     : INTEGER := mine (size_res'low, size_res'low);  -- catch literals
5556
    variable result : UNRESOLVED_ufixed (size_res'high downto fw);
5557
  begin
5558
    if (result'length < 1 or arg'length < 1) then
5559
      return NAUF;
5560
    else
5561
      result := resize (arg            => arg,
5562
                        left_index     => size_res'high,
5563
                        right_index    => size_res'low,
5564
                        round_style    => round_style,
5565
                        overflow_style => overflow_style);
5566
      return result;
5567
    end if;
5568
  end function resize;
5569
 
5570
  function resize (
5571
    arg                     : UNRESOLVED_sfixed;  -- input
5572
    size_res                : UNRESOLVED_sfixed;  -- for size only
5573
    constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
5574
    constant round_style    : fixed_round_style_type    := fixed_round_style)
5575
    return UNRESOLVED_sfixed is
5576
    constant fw     : INTEGER := mine (size_res'low, size_res'low);  -- catch literals
5577
    variable result : UNRESOLVED_sfixed (size_res'high downto fw);
5578
  begin
5579
    if (result'length < 1 or arg'length < 1) then
5580
      return NASF;
5581
    else
5582
      result := resize (arg            => arg,
5583
                        left_index     => size_res'high,
5584
                        right_index    => size_res'low,
5585
                        round_style    => round_style,
5586
                        overflow_style => overflow_style);
5587
      return result;
5588
    end if;
5589
  end function resize;
5590
 
5591
  -- Overloaded math functions for real
5592
  function "+" (
5593
    l : UNRESOLVED_ufixed;              -- fixed point input
5594
    r : REAL)
5595
    return UNRESOLVED_ufixed is
5596
  begin
5597
    return (l + to_ufixed (r, l'high, l'low));
5598
  end function "+";
5599
 
5600
  function "+" (
5601
    l : REAL;
5602
    r : UNRESOLVED_ufixed)              -- fixed point input
5603
    return UNRESOLVED_ufixed is
5604
  begin
5605
    return (to_ufixed (l, r'high, r'low) + r);
5606
  end function "+";
5607
 
5608
  function "+" (
5609
    l : UNRESOLVED_sfixed;              -- fixed point input
5610
    r : REAL)
5611
    return UNRESOLVED_sfixed is
5612
  begin
5613
    return (l + to_sfixed (r, l'high, l'low));
5614
  end function "+";
5615
 
5616
  function "+" (
5617
    l : REAL;
5618
    r : UNRESOLVED_sfixed)              -- fixed point input
5619
    return UNRESOLVED_sfixed is
5620
  begin
5621
    return (to_sfixed (l, r'high, r'low) + r);
5622
  end function "+";
5623
 
5624
  function "-" (
5625
    l : UNRESOLVED_ufixed;              -- fixed point input
5626
    r : REAL)
5627
    return UNRESOLVED_ufixed is
5628
  begin
5629
    return (l - to_ufixed (r, l'high, l'low));
5630
  end function "-";
5631
 
5632
  function "-" (
5633
    l : REAL;
5634
    r : UNRESOLVED_ufixed)              -- fixed point input
5635
    return UNRESOLVED_ufixed is
5636
  begin
5637
    return (to_ufixed (l, r'high, r'low) - r);
5638
  end function "-";
5639
 
5640
  function "-" (
5641
    l : UNRESOLVED_sfixed;              -- fixed point input
5642
    r : REAL)
5643
    return UNRESOLVED_sfixed is
5644
  begin
5645
    return (l - to_sfixed (r, l'high, l'low));
5646
  end function "-";
5647
 
5648
  function "-" (
5649
    l : REAL;
5650
    r : UNRESOLVED_sfixed)              -- fixed point input
5651
    return UNRESOLVED_sfixed is
5652
  begin
5653
    return (to_sfixed (l, r'high, r'low) - r);
5654
  end function "-";
5655
 
5656
  function "*" (
5657
    l : UNRESOLVED_ufixed;              -- fixed point input
5658
    r : REAL)
5659
    return UNRESOLVED_ufixed is
5660
  begin
5661
    return (l * to_ufixed (r, l'high, l'low));
5662
  end function "*";
5663
 
5664
  function "*" (
5665
    l : REAL;
5666
    r : UNRESOLVED_ufixed)              -- fixed point input
5667
    return UNRESOLVED_ufixed is
5668
  begin
5669
    return (to_ufixed (l, r'high, r'low) * r);
5670
  end function "*";
5671
 
5672
  function "*" (
5673
    l : UNRESOLVED_sfixed;              -- fixed point input
5674
    r : REAL)
5675
    return UNRESOLVED_sfixed is
5676
  begin
5677
    return (l * to_sfixed (r, l'high, l'low));
5678
  end function "*";
5679
 
5680
  function "*" (
5681
    l : REAL;
5682
    r : UNRESOLVED_sfixed)              -- fixed point input
5683
    return UNRESOLVED_sfixed is
5684
  begin
5685
    return (to_sfixed (l, r'high, r'low) * r);
5686
  end function "*";
5687
 
5688
--  function "/" (
5689
--    l : UNRESOLVED_ufixed;              -- fixed point input
5690
--    r : REAL)
5691
--    return UNRESOLVED_ufixed is
5692
--  begin
5693
--    return (l / to_ufixed (r, l'high, l'low));
5694
--  end function "/";
5695
 
5696
--  function "/" (
5697
--    l : REAL;
5698
--    r : UNRESOLVED_ufixed)              -- fixed point input
5699
--    return UNRESOLVED_ufixed is
5700
--  begin
5701
--    return (to_ufixed (l, r'high, r'low) / r);
5702
--  end function "/";
5703
 
5704
--  function "/" (
5705
--    l : UNRESOLVED_sfixed;              -- fixed point input
5706
--    r : REAL)
5707
--    return UNRESOLVED_sfixed is
5708
--  begin
5709
--    return (l / to_sfixed (r, l'high, l'low));
5710
--  end function "/";
5711
 
5712
--  function "/" (
5713
--    l : REAL;
5714
--    r : UNRESOLVED_sfixed)              -- fixed point input
5715
--    return UNRESOLVED_sfixed is
5716
--  begin
5717
--    return (to_sfixed (l, r'high, r'low) / r);
5718
--  end function "/";
5719
 
5720
--  function "rem" (
5721
--    l : UNRESOLVED_ufixed;              -- fixed point input
5722
--    r : REAL)
5723
--    return UNRESOLVED_ufixed is
5724
--  begin
5725
--    return (l rem to_ufixed (r, l'high, l'low));
5726
--  end function "rem";
5727
 
5728
--  function "rem" (
5729
--    l : REAL;
5730
--    r : UNRESOLVED_ufixed)              -- fixed point input
5731
--    return UNRESOLVED_ufixed is
5732
--  begin
5733
--    return (to_ufixed (l, r'high, r'low) rem r);
5734
--  end function "rem";
5735
 
5736
--  function "rem" (
5737
--    l : UNRESOLVED_sfixed;              -- fixed point input
5738
--    r : REAL)
5739
--    return UNRESOLVED_sfixed is
5740
--  begin
5741
--    return (l rem to_sfixed (r, l'high, l'low));
5742
--  end function "rem";
5743
 
5744
--  function "rem" (
5745
--    l : REAL;
5746
--    r : UNRESOLVED_sfixed)              -- fixed point input
5747
--    return UNRESOLVED_sfixed is
5748
--  begin
5749
--    return (to_sfixed (l, r'high, r'low) rem r);
5750
--  end function "rem";
5751
 
5752
--  function "mod" (
5753
--    l : UNRESOLVED_ufixed;              -- fixed point input
5754
--    r : REAL)
5755
--    return UNRESOLVED_ufixed is
5756
--  begin
5757
--    return (l mod to_ufixed (r, l'high, l'low));
5758
--  end function "mod";
5759
 
5760
--  function "mod" (
5761
--    l : REAL;
5762
--    r : UNRESOLVED_ufixed)              -- fixed point input
5763
--    return UNRESOLVED_ufixed is
5764
--  begin
5765
--    return (to_ufixed (l, r'high, r'low) mod r);
5766
--  end function "mod";
5767
 
5768
--  function "mod" (
5769
--    l : UNRESOLVED_sfixed;              -- fixed point input
5770
--    r : REAL)
5771
--    return UNRESOLVED_sfixed is
5772
--  begin
5773
--    return (l mod to_sfixed (r, l'high, l'low));
5774
--  end function "mod";
5775
 
5776
--  function "mod" (
5777
--    l : REAL;
5778
--    r : UNRESOLVED_sfixed)              -- fixed point input
5779
--    return UNRESOLVED_sfixed is
5780
--  begin
5781
--    return (to_sfixed (l, r'high, r'low) mod r);
5782
--  end function "mod";
5783
 
5784
  -- Overloaded math functions for integers
5785
  function "+" (
5786
    l : UNRESOLVED_ufixed;              -- fixed point input
5787
    r : NATURAL)
5788
    return UNRESOLVED_ufixed is
5789
  begin
5790
    return (l + to_ufixed (r, l'high, 0));
5791
  end function "+";
5792
 
5793
  function "+" (
5794
    l : NATURAL;
5795
    r : UNRESOLVED_ufixed)              -- fixed point input
5796
    return UNRESOLVED_ufixed is
5797
  begin
5798
    return (to_ufixed (l, r'high, 0) + r);
5799
  end function "+";
5800
 
5801
  function "+" (
5802
    l : UNRESOLVED_sfixed;              -- fixed point input
5803
    r : INTEGER)
5804
    return UNRESOLVED_sfixed is
5805
  begin
5806
    return (l + to_sfixed (r, l'high, 0));
5807
  end function "+";
5808
 
5809
  function "+" (
5810
    l : INTEGER;
5811
    r : UNRESOLVED_sfixed)              -- fixed point input
5812
    return UNRESOLVED_sfixed is
5813
  begin
5814
    return (to_sfixed (l, r'high, 0) + r);
5815
  end function "+";
5816
 
5817
  -- Overloaded functions
5818
  function "-" (
5819
    l : UNRESOLVED_ufixed;              -- fixed point input
5820
    r : NATURAL)
5821
    return UNRESOLVED_ufixed is
5822
  begin
5823
    return (l - to_ufixed (r, l'high, 0));
5824
  end function "-";
5825
 
5826
  function "-" (
5827
    l : NATURAL;
5828
    r : UNRESOLVED_ufixed)              -- fixed point input
5829
    return UNRESOLVED_ufixed is
5830
  begin
5831
    return (to_ufixed (l, r'high, 0) - r);
5832
  end function "-";
5833
 
5834
  function "-" (
5835
    l : UNRESOLVED_sfixed;              -- fixed point input
5836
    r : INTEGER)
5837
    return UNRESOLVED_sfixed is
5838
  begin
5839
    return (l - to_sfixed (r, l'high, 0));
5840
  end function "-";
5841
 
5842
  function "-" (
5843
    l : INTEGER;
5844
    r : UNRESOLVED_sfixed)              -- fixed point input
5845
    return UNRESOLVED_sfixed is
5846
  begin
5847
    return (to_sfixed (l, r'high, 0) - r);
5848
  end function "-";
5849
 
5850
  -- Overloaded functions
5851
  function "*" (
5852
    l : UNRESOLVED_ufixed;              -- fixed point input
5853
    r : NATURAL)
5854
    return UNRESOLVED_ufixed is
5855
  begin
5856
    return (l * to_ufixed (r, l'high, 0));
5857
  end function "*";
5858
 
5859
  function "*" (
5860
    l : NATURAL;
5861
    r : UNRESOLVED_ufixed)              -- fixed point input
5862
    return UNRESOLVED_ufixed is
5863
  begin
5864
    return (to_ufixed (l, r'high, 0) * r);
5865
  end function "*";
5866
 
5867
  function "*" (
5868
    l : UNRESOLVED_sfixed;              -- fixed point input
5869
    r : INTEGER)
5870
    return UNRESOLVED_sfixed is
5871
  begin
5872
    return (l * to_sfixed (r, l'high, 0));
5873
  end function "*";
5874
 
5875
  function "*" (
5876
    l : INTEGER;
5877
    r : UNRESOLVED_sfixed)              -- fixed point input
5878
    return UNRESOLVED_sfixed is
5879
  begin
5880
    return (to_sfixed (l, r'high, 0) * r);
5881
  end function "*";
5882
 
5883
  -- Overloaded functions
5884
--  function "/" (
5885
--    l : UNRESOLVED_ufixed;              -- fixed point input
5886
--    r : NATURAL)
5887
--    return UNRESOLVED_ufixed is
5888
--  begin
5889
--    return (l / to_ufixed (r, l'high, 0));
5890
--  end function "/";
5891
 
5892
--  function "/" (
5893
--    l : NATURAL;
5894
--    r : UNRESOLVED_ufixed)              -- fixed point input
5895
--    return UNRESOLVED_ufixed is
5896
--  begin
5897
--    return (to_ufixed (l, r'high, 0) / r);
5898
--  end function "/";
5899
 
5900
--  function "/" (
5901
--    l : UNRESOLVED_sfixed;              -- fixed point input
5902
--    r : INTEGER)
5903
--    return UNRESOLVED_sfixed is
5904
--  begin
5905
--    return (l / to_sfixed (r, l'high, 0));
5906
--  end function "/";
5907
 
5908
--  function "/" (
5909
--    l : INTEGER;
5910
--    r : UNRESOLVED_sfixed)              -- fixed point input
5911
--    return UNRESOLVED_sfixed is
5912
--  begin
5913
--    return (to_sfixed (l, r'high, 0) / r);
5914
--  end function "/";
5915
 
5916
--  function "rem" (
5917
--    l : UNRESOLVED_ufixed;              -- fixed point input
5918
--    r : NATURAL)
5919
--    return UNRESOLVED_ufixed is
5920
--  begin
5921
--    return (l rem to_ufixed (r, l'high, 0));
5922
--  end function "rem";
5923
 
5924
--  function "rem" (
5925
--    l : NATURAL;
5926
--    r : UNRESOLVED_ufixed)              -- fixed point input
5927
--    return UNRESOLVED_ufixed is
5928
--  begin
5929
--    return (to_ufixed (l, r'high, 0) rem r);
5930
--  end function "rem";
5931
 
5932
--  function "rem" (
5933
--    l : UNRESOLVED_sfixed;              -- fixed point input
5934
--    r : INTEGER)
5935
--    return UNRESOLVED_sfixed is
5936
--  begin
5937
--    return (l rem to_sfixed (r, l'high, 0));
5938
--  end function "rem";
5939
 
5940
--  function "rem" (
5941
--    l : INTEGER;
5942
--    r : UNRESOLVED_sfixed)              -- fixed point input
5943
--    return UNRESOLVED_sfixed is
5944
--  begin
5945
--    return (to_sfixed (l, r'high, 0) rem r);
5946
--  end function "rem";
5947
 
5948
--  function "mod" (
5949
--    l : UNRESOLVED_ufixed;              -- fixed point input
5950
--    r : NATURAL)
5951
--    return UNRESOLVED_ufixed is
5952
--  begin
5953
--    return (l mod to_ufixed (r, l'high, 0));
5954
--  end function "mod";
5955
 
5956
--  function "mod" (
5957
--    l : NATURAL;
5958
--    r : UNRESOLVED_ufixed)              -- fixed point input
5959
--    return UNRESOLVED_ufixed is
5960
--  begin
5961
--    return (to_ufixed (l, r'high, 0) mod r);
5962
--  end function "mod";
5963
 
5964
--  function "mod" (
5965
--    l : UNRESOLVED_sfixed;              -- fixed point input
5966
--    r : INTEGER)
5967
--    return UNRESOLVED_sfixed is
5968
--  begin
5969
--    return (l mod to_sfixed (r, l'high, 0));
5970
--  end function "mod";
5971
 
5972
--  function "mod" (
5973
--    l : INTEGER;
5974
--    r : UNRESOLVED_sfixed)              -- fixed point input
5975
--    return UNRESOLVED_sfixed is
5976
--  begin
5977
--    return (to_sfixed (l, r'high, 0) mod r);
5978
--  end function "mod";
5979
 
5980
  -- overloaded ufixed compare functions with integer
5981
  function "=" (
5982
    l : UNRESOLVED_ufixed;
5983
    r : NATURAL)                        -- fixed point input
5984
    return BOOLEAN is
5985
  begin
5986
    return (l = to_ufixed (r, l'high, l'low));
5987
  end function "=";
5988
 
5989
  function "/=" (
5990
    l : UNRESOLVED_ufixed;
5991
    r : NATURAL)                        -- fixed point input
5992
    return BOOLEAN is
5993
  begin
5994
    return (l /= to_ufixed (r, l'high, l'low));
5995
  end function "/=";
5996
 
5997
  function ">=" (
5998
    l : UNRESOLVED_ufixed;
5999
    r : NATURAL)                        -- fixed point input
6000
    return BOOLEAN is
6001
  begin
6002
    return (l >= to_ufixed (r, l'high, l'low));
6003
  end function ">=";
6004
 
6005
  function "<=" (
6006
    l : UNRESOLVED_ufixed;
6007
    r : NATURAL)                        -- fixed point input
6008
    return BOOLEAN is
6009
  begin
6010
    return (l <= to_ufixed (r, l'high, l'low));
6011
  end function "<=";
6012
 
6013
  function ">" (
6014
    l : UNRESOLVED_ufixed;
6015
    r : NATURAL)                        -- fixed point input
6016
    return BOOLEAN is
6017
  begin
6018
    return (l > to_ufixed (r, l'high, l'low));
6019
  end function ">";
6020
 
6021
  function "<" (
6022
    l : UNRESOLVED_ufixed;
6023
    r : NATURAL)                        -- fixed point input
6024
    return BOOLEAN is
6025
  begin
6026
    return (l < to_ufixed (r, l'high, l'low));
6027
  end function "<";
6028
 
6029
  function \?=\ (
6030
    l : UNRESOLVED_ufixed;
6031
    r : NATURAL)                        -- fixed point input
6032
    return STD_ULOGIC is
6033
  begin
6034
    return \?=\ (l,  to_ufixed (r, l'high, l'low));
6035
  end function \?=\;
6036
 
6037
  function \?/=\ (
6038
    l : UNRESOLVED_ufixed;
6039
    r : NATURAL)                        -- fixed point input
6040
    return STD_ULOGIC is
6041
  begin
6042
    return \?/=\ (l,  to_ufixed (r, l'high, l'low));
6043
  end function \?/=\;
6044
 
6045
  function \?>=\ (
6046
    l : UNRESOLVED_ufixed;
6047
    r : NATURAL)                        -- fixed point input
6048
    return STD_ULOGIC is
6049
  begin
6050
    return \?>=\ (l,  to_ufixed (r, l'high, l'low));
6051
  end function \?>=\;
6052
 
6053
  function \?<=\ (
6054
    l : UNRESOLVED_ufixed;
6055
    r : NATURAL)                        -- fixed point input
6056
                 return STD_ULOGIC is
6057
  begin
6058
    return \?<=\ (l,  to_ufixed (r, l'high, l'low));
6059
  end function \?<=\;
6060
 
6061
  function \?>\ (
6062
    l : UNRESOLVED_ufixed;
6063
    r : NATURAL)                        -- fixed point input
6064
    return STD_ULOGIC is
6065
  begin
6066
    return \?>\ (l,  to_ufixed (r, l'high, l'low));
6067
  end function \?>\;
6068
 
6069
  function \?<\ (
6070
    l : UNRESOLVED_ufixed;
6071
    r : NATURAL)                        -- fixed point input
6072
    return STD_ULOGIC is
6073
  begin
6074
    return \?<\ (l,  to_ufixed (r, l'high, l'low));
6075
  end function \?<\;
6076
 
6077
  function maximum (
6078
    l : UNRESOLVED_ufixed;              -- fixed point input
6079
    r : NATURAL)
6080
    return UNRESOLVED_ufixed is
6081
  begin
6082
    return maximum (l, to_ufixed (r, l'high, l'low));
6083
  end function maximum;
6084
 
6085
  function minimum (
6086
    l : UNRESOLVED_ufixed;              -- fixed point input
6087
    r : NATURAL)
6088
    return UNRESOLVED_ufixed is
6089
  begin
6090
    return minimum (l, to_ufixed (r, l'high, l'low));
6091
  end function minimum;
6092
 
6093
  -- NATURAL to ufixed
6094
  function "=" (
6095
    l : NATURAL;
6096
    r : UNRESOLVED_ufixed)              -- fixed point input
6097
    return BOOLEAN is
6098
  begin
6099
    return (to_ufixed (l, r'high, r'low) = r);
6100
  end function "=";
6101
 
6102
  function "/=" (
6103
    l : NATURAL;
6104
    r : UNRESOLVED_ufixed)              -- fixed point input
6105
    return BOOLEAN is
6106
  begin
6107
    return (to_ufixed (l, r'high, r'low) /= r);
6108
  end function "/=";
6109
 
6110
  function ">=" (
6111
    l : NATURAL;
6112
    r : UNRESOLVED_ufixed)              -- fixed point input
6113
    return BOOLEAN is
6114
  begin
6115
    return (to_ufixed (l, r'high, r'low) >= r);
6116
  end function ">=";
6117
 
6118
  function "<=" (
6119
    l : NATURAL;
6120
    r : UNRESOLVED_ufixed)              -- fixed point input
6121
    return BOOLEAN is
6122
  begin
6123
    return (to_ufixed (l, r'high, r'low) <= r);
6124
  end function "<=";
6125
 
6126
  function ">" (
6127
    l : NATURAL;
6128
    r : UNRESOLVED_ufixed)              -- fixed point input
6129
    return BOOLEAN is
6130
  begin
6131
    return (to_ufixed (l, r'high, r'low) > r);
6132
  end function ">";
6133
 
6134
  function "<" (
6135
    l : NATURAL;
6136
    r : UNRESOLVED_ufixed)              -- fixed point input
6137
    return BOOLEAN is
6138
  begin
6139
    return (to_ufixed (l, r'high, r'low) < r);
6140
  end function "<";
6141
 
6142
  function \?=\ (
6143
    l : NATURAL;
6144
    r : UNRESOLVED_ufixed)              -- fixed point input
6145
    return STD_ULOGIC is
6146
  begin
6147
    return \?=\ (to_ufixed (l, r'high, r'low), r);
6148
  end function \?=\;
6149
 
6150
  function \?/=\ (
6151
    l : NATURAL;
6152
    r : UNRESOLVED_ufixed)              -- fixed point input
6153
    return STD_ULOGIC is
6154
  begin
6155
    return \?/=\ (to_ufixed (l, r'high, r'low), r);
6156
  end function \?/=\;
6157
 
6158
  function \?>=\ (
6159
    l : NATURAL;
6160
    r : UNRESOLVED_ufixed)              -- fixed point input
6161
    return STD_ULOGIC is
6162
  begin
6163
    return \?>=\ (to_ufixed (l, r'high, r'low), r);
6164
  end function \?>=\;
6165
 
6166
  function \?<=\ (
6167
    l : NATURAL;
6168
    r : UNRESOLVED_ufixed)              -- fixed point input
6169
                 return STD_ULOGIC is
6170
  begin
6171
    return \?<=\ (to_ufixed (l, r'high, r'low), r);
6172
  end function \?<=\;
6173
 
6174
  function \?>\ (
6175
    l : NATURAL;
6176
    r : UNRESOLVED_ufixed)              -- fixed point input
6177
    return STD_ULOGIC is
6178
  begin
6179
    return \?>\ (to_ufixed (l, r'high, r'low), r);
6180
  end function \?>\;
6181
 
6182
  function \?<\ (
6183
    l : NATURAL;
6184
    r : UNRESOLVED_ufixed)              -- fixed point input
6185
    return STD_ULOGIC is
6186
  begin
6187
    return \?<\ (to_ufixed (l, r'high, r'low), r);
6188
  end function \?<\;
6189
 
6190
  function maximum (
6191
    l : NATURAL;
6192
    r : UNRESOLVED_ufixed)              -- fixed point input
6193
    return UNRESOLVED_ufixed is
6194
  begin
6195
    return maximum (to_ufixed (l, r'high, r'low), r);
6196
  end function maximum;
6197
 
6198
  function minimum (
6199
    l : NATURAL;
6200
    r : UNRESOLVED_ufixed)              -- fixed point input
6201
    return UNRESOLVED_ufixed is
6202
  begin
6203
    return minimum (to_ufixed (l, r'high, r'low), r);
6204
  end function minimum;
6205
 
6206
  -- overloaded ufixed compare functions with real
6207
  function "=" (
6208
    l : UNRESOLVED_ufixed;
6209
    r : REAL)
6210
    return BOOLEAN is
6211
  begin
6212
    return (l = to_ufixed (r, l'high, l'low));
6213
  end function "=";
6214
 
6215
  function "/=" (
6216
    l : UNRESOLVED_ufixed;
6217
    r : REAL)
6218
    return BOOLEAN is
6219
  begin
6220
    return (l /= to_ufixed (r, l'high, l'low));
6221
  end function "/=";
6222
 
6223
  function ">=" (
6224
    l : UNRESOLVED_ufixed;
6225
    r : REAL)
6226
    return BOOLEAN is
6227
  begin
6228
    return (l >= to_ufixed (r, l'high, l'low));
6229
  end function ">=";
6230
 
6231
  function "<=" (
6232
    l : UNRESOLVED_ufixed;
6233
    r : REAL)
6234
    return BOOLEAN is
6235
  begin
6236
    return (l <= to_ufixed (r, l'high, l'low));
6237
  end function "<=";
6238
 
6239
  function ">" (
6240
    l : UNRESOLVED_ufixed;
6241
    r : REAL)
6242
    return BOOLEAN is
6243
  begin
6244
    return (l > to_ufixed (r, l'high, l'low));
6245
  end function ">";
6246
 
6247
  function "<" (
6248
    l : UNRESOLVED_ufixed;
6249
    r : REAL)
6250
    return BOOLEAN is
6251
  begin
6252
    return (l < to_ufixed (r, l'high, l'low));
6253
  end function "<";
6254
 
6255
  function \?=\ (
6256
    l : UNRESOLVED_ufixed;
6257
    r : REAL)
6258
    return STD_ULOGIC is
6259
  begin
6260
    return \?=\ (l,  to_ufixed (r, l'high, l'low));
6261
  end function \?=\;
6262
 
6263
  function \?/=\ (
6264
    l : UNRESOLVED_ufixed;
6265
    r : REAL)
6266
    return STD_ULOGIC is
6267
  begin
6268
    return \?/=\ (l,  to_ufixed (r, l'high, l'low));
6269
  end function \?/=\;
6270
 
6271
  function \?>=\ (
6272
    l : UNRESOLVED_ufixed;
6273
    r : REAL)
6274
    return STD_ULOGIC is
6275
  begin
6276
    return \?>=\ (l,  to_ufixed (r, l'high, l'low));
6277
  end function \?>=\;
6278
 
6279
  function \?<=\ (
6280
    l : UNRESOLVED_ufixed;
6281
    r : REAL)
6282
                 return STD_ULOGIC is
6283
  begin
6284
    return \?<=\ (l,  to_ufixed (r, l'high, l'low));
6285
  end function \?<=\;
6286
 
6287
  function \?>\ (
6288
    l : UNRESOLVED_ufixed;
6289
    r : REAL)
6290
    return STD_ULOGIC is
6291
  begin
6292
    return \?>\ (l,  to_ufixed (r, l'high, l'low));
6293
  end function \?>\;
6294
 
6295
  function \?<\ (
6296
    l : UNRESOLVED_ufixed;
6297
    r : REAL)
6298
    return STD_ULOGIC is
6299
  begin
6300
    return \?<\ (l,  to_ufixed (r, l'high, l'low));
6301
  end function \?<\;
6302
 
6303
  function maximum (
6304
    l : UNRESOLVED_ufixed;
6305
    r : REAL)
6306
    return UNRESOLVED_ufixed is
6307
  begin
6308
    return maximum (l, to_ufixed (r, l'high, l'low));
6309
  end function maximum;
6310
 
6311
  function minimum (
6312
    l : UNRESOLVED_ufixed;
6313
    r : REAL)
6314
    return UNRESOLVED_ufixed is
6315
  begin
6316
    return minimum (l, to_ufixed (r, l'high, l'low));
6317
  end function minimum;
6318
 
6319
  -- real and ufixed
6320
  function "=" (
6321
    l : REAL;
6322
    r : UNRESOLVED_ufixed)              -- fixed point input
6323
    return BOOLEAN is
6324
  begin
6325
    return (to_ufixed (l, r'high, r'low) = r);
6326
  end function "=";
6327
 
6328
  function "/=" (
6329
    l : REAL;
6330
    r : UNRESOLVED_ufixed)              -- fixed point input
6331
    return BOOLEAN is
6332
  begin
6333
    return (to_ufixed (l, r'high, r'low) /= r);
6334
  end function "/=";
6335
 
6336
  function ">=" (
6337
    l : REAL;
6338
    r : UNRESOLVED_ufixed)              -- fixed point input
6339
    return BOOLEAN is
6340
  begin
6341
    return (to_ufixed (l, r'high, r'low) >= r);
6342
  end function ">=";
6343
 
6344
  function "<=" (
6345
    l : REAL;
6346
    r : UNRESOLVED_ufixed)              -- fixed point input
6347
    return BOOLEAN is
6348
  begin
6349
    return (to_ufixed (l, r'high, r'low) <= r);
6350
  end function "<=";
6351
 
6352
  function ">" (
6353
    l : REAL;
6354
    r : UNRESOLVED_ufixed)              -- fixed point input
6355
    return BOOLEAN is
6356
  begin
6357
    return (to_ufixed (l, r'high, r'low) > r);
6358
  end function ">";
6359
 
6360
  function "<" (
6361
    l : REAL;
6362
    r : UNRESOLVED_ufixed)              -- fixed point input
6363
    return BOOLEAN is
6364
  begin
6365
    return (to_ufixed (l, r'high, r'low) < r);
6366
  end function "<";
6367
 
6368
  function \?=\ (
6369
    l : REAL;
6370
    r : UNRESOLVED_ufixed)              -- fixed point input
6371
    return STD_ULOGIC is
6372
  begin
6373
    return \?=\ (to_ufixed (l, r'high, r'low), r);
6374
  end function \?=\;
6375
 
6376
  function \?/=\ (
6377
    l : REAL;
6378
    r : UNRESOLVED_ufixed)              -- fixed point input
6379
    return STD_ULOGIC is
6380
  begin
6381
    return \?/=\ (to_ufixed (l, r'high, r'low), r);
6382
  end function \?/=\;
6383
 
6384
  function \?>=\ (
6385
    l : REAL;
6386
    r : UNRESOLVED_ufixed)              -- fixed point input
6387
    return STD_ULOGIC is
6388
  begin
6389
    return \?>=\ (to_ufixed (l, r'high, r'low), r);
6390
  end function \?>=\;
6391
 
6392
  function \?<=\ (
6393
    l : REAL;
6394
    r : UNRESOLVED_ufixed)              -- fixed point input
6395
                 return STD_ULOGIC is
6396
  begin
6397
    return \?<=\ (to_ufixed (l, r'high, r'low), r);
6398
  end function \?<=\;
6399
 
6400
  function \?>\ (
6401
    l : REAL;
6402
    r : UNRESOLVED_ufixed)              -- fixed point input
6403
    return STD_ULOGIC is
6404
  begin
6405
    return \?>\ (to_ufixed (l, r'high, r'low), r);
6406
  end function \?>\;
6407
 
6408
  function \?<\ (
6409
    l : REAL;
6410
    r : UNRESOLVED_ufixed)              -- fixed point input
6411
    return STD_ULOGIC is
6412
  begin
6413
    return \?<\ (to_ufixed (l, r'high, r'low), r);
6414
  end function \?<\;
6415
 
6416
  function maximum (
6417
    l : REAL;
6418
    r : UNRESOLVED_ufixed)              -- fixed point input
6419
    return UNRESOLVED_ufixed is
6420
  begin
6421
    return maximum (to_ufixed (l, r'high, r'low), r);
6422
  end function maximum;
6423
 
6424
  function minimum (
6425
    l : REAL;
6426
    r : UNRESOLVED_ufixed)              -- fixed point input
6427
    return UNRESOLVED_ufixed is
6428
  begin
6429
    return minimum (to_ufixed (l, r'high, r'low), r);
6430
  end function minimum;
6431
 
6432
  -- overloaded sfixed compare functions with integer
6433
  function "=" (
6434
    l : UNRESOLVED_sfixed;
6435
    r : INTEGER)
6436
    return BOOLEAN is
6437
  begin
6438
    return (l = to_sfixed (r, l'high, l'low));
6439
  end function "=";
6440
 
6441
  function "/=" (
6442
    l : UNRESOLVED_sfixed;
6443
    r : INTEGER)
6444
    return BOOLEAN is
6445
  begin
6446
    return (l /= to_sfixed (r, l'high, l'low));
6447
  end function "/=";
6448
 
6449
  function ">=" (
6450
    l : UNRESOLVED_sfixed;
6451
    r : INTEGER)
6452
    return BOOLEAN is
6453
  begin
6454
    return (l >= to_sfixed (r, l'high, l'low));
6455
  end function ">=";
6456
 
6457
  function "<=" (
6458
    l : UNRESOLVED_sfixed;
6459
    r : INTEGER)
6460
    return BOOLEAN is
6461
  begin
6462
    return (l <= to_sfixed (r, l'high, l'low));
6463
  end function "<=";
6464
 
6465
  function ">" (
6466
    l : UNRESOLVED_sfixed;
6467
    r : INTEGER)
6468
    return BOOLEAN is
6469
  begin
6470
    return (l > to_sfixed (r, l'high, l'low));
6471
  end function ">";
6472
 
6473
  function "<" (
6474
    l : UNRESOLVED_sfixed;
6475
    r : INTEGER)
6476
    return BOOLEAN is
6477
  begin
6478
    return (l < to_sfixed (r, l'high, l'low));
6479
  end function "<";
6480
 
6481
  function \?=\ (
6482
    l : UNRESOLVED_sfixed;
6483
    r : INTEGER)
6484
    return STD_ULOGIC is
6485
  begin
6486
    return \?=\ (l,  to_sfixed (r, l'high, l'low));
6487
  end function \?=\;
6488
 
6489
  function \?/=\ (
6490
    l : UNRESOLVED_sfixed;
6491
    r : INTEGER)
6492
    return STD_ULOGIC is
6493
  begin
6494
    return \?/=\ (l,  to_sfixed (r, l'high, l'low));
6495
  end function \?/=\;
6496
 
6497
  function \?>=\ (
6498
    l : UNRESOLVED_sfixed;
6499
    r : INTEGER)
6500
    return STD_ULOGIC is
6501
  begin
6502
    return \?>=\ (l,  to_sfixed (r, l'high, l'low));
6503
  end function \?>=\;
6504
 
6505
  function \?<=\ (
6506
    l : UNRESOLVED_sfixed;
6507
    r : INTEGER)
6508
                 return STD_ULOGIC is
6509
  begin
6510
    return \?<=\ (l,  to_sfixed (r, l'high, l'low));
6511
  end function \?<=\;
6512
 
6513
  function \?>\ (
6514
    l : UNRESOLVED_sfixed;
6515
    r : INTEGER)
6516
    return STD_ULOGIC is
6517
  begin
6518
    return \?>\ (l,  to_sfixed (r, l'high, l'low));
6519
  end function \?>\;
6520
 
6521
  function \?<\ (
6522
    l : UNRESOLVED_sfixed;
6523
    r : INTEGER)
6524
    return STD_ULOGIC is
6525
  begin
6526
    return \?<\ (l,  to_sfixed (r, l'high, l'low));
6527
  end function \?<\;
6528
 
6529
  function maximum (
6530
    l : UNRESOLVED_sfixed;
6531
    r : INTEGER)
6532
    return UNRESOLVED_sfixed is
6533
  begin
6534
    return maximum (l, to_sfixed (r, l'high, l'low));
6535
  end function maximum;
6536
 
6537
  function minimum (
6538
    l : UNRESOLVED_sfixed;
6539
    r : INTEGER)
6540
    return UNRESOLVED_sfixed is
6541
  begin
6542
    return minimum (l, to_sfixed (r, l'high, l'low));
6543
  end function minimum;
6544
 
6545
  -- integer and sfixed
6546
  function "=" (
6547
    l : INTEGER;
6548
    r : UNRESOLVED_sfixed)              -- fixed point input
6549
    return BOOLEAN is
6550
  begin
6551
    return (to_sfixed (l, r'high, r'low) = r);
6552
  end function "=";
6553
 
6554
  function "/=" (
6555
    l : INTEGER;
6556
    r : UNRESOLVED_sfixed)              -- fixed point input
6557
    return BOOLEAN is
6558
  begin
6559
    return (to_sfixed (l, r'high, r'low) /= r);
6560
  end function "/=";
6561
 
6562
  function ">=" (
6563
    l : INTEGER;
6564
    r : UNRESOLVED_sfixed)              -- fixed point input
6565
    return BOOLEAN is
6566
  begin
6567
    return (to_sfixed (l, r'high, r'low) >= r);
6568
  end function ">=";
6569
 
6570
  function "<=" (
6571
    l : INTEGER;
6572
    r : UNRESOLVED_sfixed)              -- fixed point input
6573
    return BOOLEAN is
6574
  begin
6575
    return (to_sfixed (l, r'high, r'low) <= r);
6576
  end function "<=";
6577
 
6578
  function ">" (
6579
    l : INTEGER;
6580
    r : UNRESOLVED_sfixed)              -- fixed point input
6581
    return BOOLEAN is
6582
  begin
6583
    return (to_sfixed (l, r'high, r'low) > r);
6584
  end function ">";
6585
 
6586
  function "<" (
6587
    l : INTEGER;
6588
    r : UNRESOLVED_sfixed)              -- fixed point input
6589
    return BOOLEAN is
6590
  begin
6591
    return (to_sfixed (l, r'high, r'low) < r);
6592
  end function "<";
6593
 
6594
  function \?=\ (
6595
    l : INTEGER;
6596
    r : UNRESOLVED_sfixed)              -- fixed point input
6597
    return STD_ULOGIC is
6598
  begin
6599
    return \?=\ (to_sfixed (l, r'high, r'low), r);
6600
  end function \?=\;
6601
 
6602
  function \?/=\ (
6603
    l : INTEGER;
6604
    r : UNRESOLVED_sfixed)              -- fixed point input
6605
    return STD_ULOGIC is
6606
  begin
6607
    return \?/=\ (to_sfixed (l, r'high, r'low), r);
6608
  end function \?/=\;
6609
 
6610
  function \?>=\ (
6611
    l : INTEGER;
6612
    r : UNRESOLVED_sfixed)              -- fixed point input
6613
    return STD_ULOGIC is
6614
  begin
6615
    return \?>=\ (to_sfixed (l, r'high, r'low), r);
6616
  end function \?>=\;
6617
 
6618
  function \?<=\ (
6619
    l : INTEGER;
6620
    r : UNRESOLVED_sfixed)              -- fixed point input
6621
                 return STD_ULOGIC is
6622
  begin
6623
    return \?<=\ (to_sfixed (l, r'high, r'low), r);
6624
  end function \?<=\;
6625
 
6626
  function \?>\ (
6627
    l : INTEGER;
6628
    r : UNRESOLVED_sfixed)              -- fixed point input
6629
    return STD_ULOGIC is
6630
  begin
6631
    return \?>\ (to_sfixed (l, r'high, r'low), r);
6632
  end function \?>\;
6633
 
6634
  function \?<\ (
6635
    l : INTEGER;
6636
    r : UNRESOLVED_sfixed)              -- fixed point input
6637
    return STD_ULOGIC is
6638
  begin
6639
    return \?<\ (to_sfixed (l, r'high, r'low), r);
6640
  end function \?<\;
6641
 
6642
  function maximum (
6643
    l : INTEGER;
6644
    r : UNRESOLVED_sfixed)
6645
    return UNRESOLVED_sfixed is
6646
  begin
6647
    return maximum (to_sfixed (l, r'high, r'low), r);
6648
  end function maximum;
6649
 
6650
  function minimum (
6651
    l : INTEGER;
6652
    r : UNRESOLVED_sfixed)
6653
    return UNRESOLVED_sfixed is
6654
  begin
6655
    return minimum (to_sfixed (l, r'high, r'low), r);
6656
  end function minimum;
6657
 
6658
  -- overloaded sfixed compare functions with real
6659
  function "=" (
6660
    l : UNRESOLVED_sfixed;
6661
    r : REAL)
6662
    return BOOLEAN is
6663
  begin
6664
    return (l = to_sfixed (r, l'high, l'low));
6665
  end function "=";
6666
 
6667
  function "/=" (
6668
    l : UNRESOLVED_sfixed;
6669
    r : REAL)
6670
    return BOOLEAN is
6671
  begin
6672
    return (l /= to_sfixed (r, l'high, l'low));
6673
  end function "/=";
6674
 
6675
  function ">=" (
6676
    l : UNRESOLVED_sfixed;
6677
    r : REAL)
6678
    return BOOLEAN is
6679
  begin
6680
    return (l >= to_sfixed (r, l'high, l'low));
6681
  end function ">=";
6682
 
6683
  function "<=" (
6684
    l : UNRESOLVED_sfixed;
6685
    r : REAL)
6686
    return BOOLEAN is
6687
  begin
6688
    return (l <= to_sfixed (r, l'high, l'low));
6689
  end function "<=";
6690
 
6691
  function ">" (
6692
    l : UNRESOLVED_sfixed;
6693
    r : REAL)
6694
    return BOOLEAN is
6695
  begin
6696
    return (l > to_sfixed (r, l'high, l'low));
6697
  end function ">";
6698
 
6699
  function "<" (
6700
    l : UNRESOLVED_sfixed;
6701
    r : REAL)
6702
    return BOOLEAN is
6703
  begin
6704
    return (l < to_sfixed (r, l'high, l'low));
6705
  end function "<";
6706
 
6707
  function \?=\ (
6708
    l : UNRESOLVED_sfixed;
6709
    r : REAL)
6710
    return STD_ULOGIC is
6711
  begin
6712
    return \?=\ (l,  to_sfixed (r, l'high, l'low));
6713
  end function \?=\;
6714
 
6715
  function \?/=\ (
6716
    l : UNRESOLVED_sfixed;
6717
    r : REAL)
6718
    return STD_ULOGIC is
6719
  begin
6720
    return \?/=\ (l,  to_sfixed (r, l'high, l'low));
6721
  end function \?/=\;
6722
 
6723
  function \?>=\ (
6724
    l : UNRESOLVED_sfixed;
6725
    r : REAL)
6726
    return STD_ULOGIC is
6727
  begin
6728
    return \?>=\ (l,  to_sfixed (r, l'high, l'low));
6729
  end function \?>=\;
6730
 
6731
  function \?<=\ (
6732
    l : UNRESOLVED_sfixed;
6733
    r : REAL)
6734
                 return STD_ULOGIC is
6735
  begin
6736
    return \?<=\ (l,  to_sfixed (r, l'high, l'low));
6737
  end function \?<=\;
6738
 
6739
  function \?>\ (
6740
    l : UNRESOLVED_sfixed;
6741
    r : REAL)
6742
    return STD_ULOGIC is
6743
  begin
6744
    return \?>\ (l,  to_sfixed (r, l'high, l'low));
6745
  end function \?>\;
6746
 
6747
  function \?<\ (
6748
    l : UNRESOLVED_sfixed;
6749
    r : REAL)
6750
    return STD_ULOGIC is
6751
  begin
6752
    return \?<\ (l,  to_sfixed (r, l'high, l'low));
6753
  end function \?<\;
6754
 
6755
  function maximum (
6756
    l : UNRESOLVED_sfixed;
6757
    r : REAL)
6758
    return UNRESOLVED_sfixed is
6759
  begin
6760
    return maximum (l, to_sfixed (r, l'high, l'low));
6761
  end function maximum;
6762
 
6763
  function minimum (
6764
    l : UNRESOLVED_sfixed;
6765
    r : REAL)
6766
    return UNRESOLVED_sfixed is
6767
  begin
6768
    return minimum (l, to_sfixed (r, l'high, l'low));
6769
  end function minimum;
6770
 
6771
  -- REAL and sfixed
6772
  function "=" (
6773
    l : REAL;
6774
    r : UNRESOLVED_sfixed)              -- fixed point input
6775
    return BOOLEAN is
6776
  begin
6777
    return (to_sfixed (l, r'high, r'low) = r);
6778
  end function "=";
6779
 
6780
  function "/=" (
6781
    l : REAL;
6782
    r : UNRESOLVED_sfixed)              -- fixed point input
6783
    return BOOLEAN is
6784
  begin
6785
    return (to_sfixed (l, r'high, r'low) /= r);
6786
  end function "/=";
6787
 
6788
  function ">=" (
6789
    l : REAL;
6790
    r : UNRESOLVED_sfixed)              -- fixed point input
6791
    return BOOLEAN is
6792
  begin
6793
    return (to_sfixed (l, r'high, r'low) >= r);
6794
  end function ">=";
6795
 
6796
  function "<=" (
6797
    l : REAL;
6798
    r : UNRESOLVED_sfixed)              -- fixed point input
6799
    return BOOLEAN is
6800
  begin
6801
    return (to_sfixed (l, r'high, r'low) <= r);
6802
  end function "<=";
6803
 
6804
  function ">" (
6805
    l : REAL;
6806
    r : UNRESOLVED_sfixed)              -- fixed point input
6807
    return BOOLEAN is
6808
  begin
6809
    return (to_sfixed (l, r'high, r'low) > r);
6810
  end function ">";
6811
 
6812
  function "<" (
6813
    l : REAL;
6814
    r : UNRESOLVED_sfixed)              -- fixed point input
6815
    return BOOLEAN is
6816
  begin
6817
    return (to_sfixed (l, r'high, r'low) < r);
6818
  end function "<";
6819
 
6820
  function \?=\ (
6821
    l : REAL;
6822
    r : UNRESOLVED_sfixed)              -- fixed point input
6823
    return STD_ULOGIC is
6824
  begin
6825
    return \?=\ (to_sfixed (l, r'high, r'low), r);
6826
  end function \?=\;
6827
 
6828
  function \?/=\ (
6829
    l : REAL;
6830
    r : UNRESOLVED_sfixed)              -- fixed point input
6831
    return STD_ULOGIC is
6832
  begin
6833
    return \?/=\ (to_sfixed (l, r'high, r'low), r);
6834
  end function \?/=\;
6835
 
6836
  function \?>=\ (
6837
    l : REAL;
6838
    r : UNRESOLVED_sfixed)              -- fixed point input
6839
    return STD_ULOGIC is
6840
  begin
6841
    return \?>=\ (to_sfixed (l, r'high, r'low), r);
6842
  end function \?>=\;
6843
 
6844
  function \?<=\ (
6845
    l : REAL;
6846
    r : UNRESOLVED_sfixed)              -- fixed point input
6847
                 return STD_ULOGIC is
6848
  begin
6849
    return \?<=\ (to_sfixed (l, r'high, r'low), r);
6850
  end function \?<=\;
6851
 
6852
  function \?>\ (
6853
    l : REAL;
6854
    r : UNRESOLVED_sfixed)              -- fixed point input
6855
    return STD_ULOGIC is
6856
  begin
6857
    return \?>\ (to_sfixed (l, r'high, r'low), r);
6858
  end function \?>\;
6859
 
6860
  function \?<\ (
6861
    l : REAL;
6862
    r : UNRESOLVED_sfixed)              -- fixed point input
6863
    return STD_ULOGIC is
6864
  begin
6865
    return \?<\ (to_sfixed (l, r'high, r'low), r);
6866
  end function \?<\;
6867
 
6868
  function maximum (
6869
    l : REAL;
6870
    r : UNRESOLVED_sfixed)
6871
    return UNRESOLVED_sfixed is
6872
  begin
6873
    return maximum (to_sfixed (l, r'high, r'low), r);
6874
  end function maximum;
6875
 
6876
  function minimum (
6877
    l : REAL;
6878
    r : UNRESOLVED_sfixed)
6879
    return UNRESOLVED_sfixed is
6880
  begin
6881
    return minimum (to_sfixed (l, r'high, r'low), r);
6882
  end function minimum;
6883
-- rtl_synthesis off
6884
-- pragma synthesis_off
6885
  -- copied from std_logic_textio
6886
  type MVL9plus is ('U', 'X', '0', '1', 'Z', 'W', 'L', 'H', '-', error);
6887
  type char_indexed_by_MVL9 is array (STD_ULOGIC) of CHARACTER;
6888
  type MVL9_indexed_by_char is array (CHARACTER) of STD_ULOGIC;
6889
  type MVL9plus_indexed_by_char is array (CHARACTER) of MVL9plus;
6890
 
6891
  constant MVL9_to_char : char_indexed_by_MVL9 := "UX01ZWLH-";
6892
  constant char_to_MVL9 : MVL9_indexed_by_char :=
6893
    ('U' => 'U', 'X' => 'X', '0' => '0', '1' => '1', 'Z' => 'Z',
6894
     'W' => 'W', 'L' => 'L', 'H' => 'H', '-' => '-', others => 'U');
6895
  constant char_to_MVL9plus : MVL9plus_indexed_by_char :=
6896
    ('U' => 'U', 'X' => 'X', '0' => '0', '1' => '1', 'Z' => 'Z',
6897
     'W' => 'W', 'L' => 'L', 'H' => 'H', '-' => '-', others => error);
6898
  constant NBSP : CHARACTER      := CHARACTER'val(160);  -- space character
6899
  constant NUS  : STRING(2 to 1) := (others => ' ');
6900
 
6901
  -- %%% Replicated Textio functions
6902
  procedure Char2TriBits (C           :     CHARACTER;
6903
                          RESULT      : out STD_ULOGIC_VECTOR(2 downto 0);
6904
                          GOOD        : out BOOLEAN;
6905
                          ISSUE_ERROR : in  BOOLEAN) is
6906
  begin
6907
    case c is
6908
      when '0' => result := o"0"; good := true;
6909
      when '1' => result := o"1"; good := true;
6910
      when '2' => result := o"2"; good := true;
6911
      when '3' => result := o"3"; good := true;
6912
      when '4' => result := o"4"; good := true;
6913
      when '5' => result := o"5"; good := true;
6914
      when '6' => result := o"6"; good := true;
6915
      when '7' => result := o"7"; good := true;
6916
      when 'Z' => result := "ZZZ"; good := true;
6917
      when 'X' => result := "XXX"; good := true;
6918
      when others =>
6919
        assert not ISSUE_ERROR
6920
          report "fixed_pkg:"
6921
          & "OREAD Error: Read a '" & c &
6922
          "', expected an Octal character (0-7)."
6923
          severity error;
6924
        result := "UUU";
6925
        good   := false;
6926
    end case;
6927
  end procedure Char2TriBits;
6928
  -- Hex Read and Write procedures for STD_ULOGIC_VECTOR.
6929
  -- Modified from the original to be more forgiving.
6930
 
6931
  procedure Char2QuadBits (C           :     CHARACTER;
6932
                           RESULT      : out STD_ULOGIC_VECTOR(3 downto 0);
6933
                           GOOD        : out BOOLEAN;
6934
                           ISSUE_ERROR : in  BOOLEAN) is
6935
  begin
6936
    case c is
6937
      when '0'       => result := x"0"; good := true;
6938
      when '1'       => result := x"1"; good := true;
6939
      when '2'       => result := x"2"; good := true;
6940
      when '3'       => result := x"3"; good := true;
6941
      when '4'       => result := x"4"; good := true;
6942
      when '5'       => result := x"5"; good := true;
6943
      when '6'       => result := x"6"; good := true;
6944
      when '7'       => result := x"7"; good := true;
6945
      when '8'       => result := x"8"; good := true;
6946
      when '9'       => result := x"9"; good := true;
6947
      when 'A' | 'a' => result := x"A"; good := true;
6948
      when 'B' | 'b' => result := x"B"; good := true;
6949
      when 'C' | 'c' => result := x"C"; good := true;
6950
      when 'D' | 'd' => result := x"D"; good := true;
6951
      when 'E' | 'e' => result := x"E"; good := true;
6952
      when 'F' | 'f' => result := x"F"; good := true;
6953
      when 'Z'       => result := "ZZZZ"; good := true;
6954
      when 'X'       => result := "XXXX"; good := true;
6955
      when others =>
6956
        assert not ISSUE_ERROR
6957
          report "fixed_pkg:"
6958
          & "HREAD Error: Read a '" & c &
6959
          "', expected a Hex character (0-F)."
6960
          severity error;
6961
        result := "UUUU";
6962
        good   := false;
6963
    end case;
6964
  end procedure Char2QuadBits;
6965
 
6966
  -- purpose: Skips white space
6967
  procedure skip_whitespace (
6968
    L : inout LINE) is
6969
    variable readOk : BOOLEAN;
6970
    variable c : CHARACTER;
6971
  begin
6972
    while L /= null and L.all'length /= 0 loop
6973
      if (L.all(1) = ' ' or L.all(1) = NBSP or L.all(1) = HT) then
6974
        read (l, c, readOk);
6975
      else
6976
        exit;
6977
      end if;
6978
    end loop;
6979
  end procedure skip_whitespace;
6980
 
6981
  function to_ostring (value     : STD_ULOGIC_VECTOR) return STRING is
6982
    constant ne     : INTEGER := (value'length+2)/3;
6983
    variable pad    : STD_ULOGIC_VECTOR(0 to (ne*3 - value'length) - 1);
6984
    variable ivalue : STD_ULOGIC_VECTOR(0 to ne*3 - 1);
6985
    variable result : STRING(1 to ne);
6986
    variable tri    : STD_ULOGIC_VECTOR(0 to 2);
6987
  begin
6988
    if value'length < 1 then
6989
      return NUS;
6990
    else
6991
      if value (value'left) = 'Z' then
6992
        pad := (others => 'Z');
6993
      else
6994
        pad := (others => '0');
6995
      end if;
6996
      ivalue := pad & value;
6997
      for i in 0 to ne-1 loop
6998
        tri := To_X01Z(ivalue(3*i to 3*i+2));
6999
        case tri is
7000
          when o"0"   => result(i+1) := '0';
7001
          when o"1"   => result(i+1) := '1';
7002
          when o"2"   => result(i+1) := '2';
7003
          when o"3"   => result(i+1) := '3';
7004
          when o"4"   => result(i+1) := '4';
7005
          when o"5"   => result(i+1) := '5';
7006
          when o"6"   => result(i+1) := '6';
7007
          when o"7"   => result(i+1) := '7';
7008
          when "ZZZ"  => result(i+1) := 'Z';
7009
          when others => result(i+1) := 'X';
7010
        end case;
7011
      end loop;
7012
      return result;
7013
    end if;
7014
  end function to_ostring;
7015
  -------------------------------------------------------------------   
7016
  function to_hstring (value     : STD_ULOGIC_VECTOR) return STRING is
7017
    constant ne     : INTEGER := (value'length+3)/4;
7018
    variable pad    : STD_ULOGIC_VECTOR(0 to (ne*4 - value'length) - 1);
7019
    variable ivalue : STD_ULOGIC_VECTOR(0 to ne*4 - 1);
7020
    variable result : STRING(1 to ne);
7021
    variable quad   : STD_ULOGIC_VECTOR(0 to 3);
7022
  begin
7023
    if value'length < 1 then
7024
      return NUS;
7025
    else
7026
      if value (value'left) = 'Z' then
7027
        pad := (others => 'Z');
7028
      else
7029
        pad := (others => '0');
7030
      end if;
7031
      ivalue := pad & value;
7032
      for i in 0 to ne-1 loop
7033
        quad := To_X01Z(ivalue(4*i to 4*i+3));
7034
        case quad is
7035
          when x"0"   => result(i+1) := '0';
7036
          when x"1"   => result(i+1) := '1';
7037
          when x"2"   => result(i+1) := '2';
7038
          when x"3"   => result(i+1) := '3';
7039
          when x"4"   => result(i+1) := '4';
7040
          when x"5"   => result(i+1) := '5';
7041
          when x"6"   => result(i+1) := '6';
7042
          when x"7"   => result(i+1) := '7';
7043
          when x"8"   => result(i+1) := '8';
7044
          when x"9"   => result(i+1) := '9';
7045
          when x"A"   => result(i+1) := 'A';
7046
          when x"B"   => result(i+1) := 'B';
7047
          when x"C"   => result(i+1) := 'C';
7048
          when x"D"   => result(i+1) := 'D';
7049
          when x"E"   => result(i+1) := 'E';
7050
          when x"F"   => result(i+1) := 'F';
7051
          when "ZZZZ" => result(i+1) := 'Z';
7052
          when others => result(i+1) := 'X';
7053
        end case;
7054
      end loop;
7055
      return result;
7056
    end if;
7057
  end function to_hstring;
7058
 
7059
 
7060
-- %%% END replicated textio functions
7061
 
7062
  -- purpose: writes fixed point into a line
7063
  procedure write (
7064
    L         : inout LINE;               -- input line
7065
    VALUE     : in    UNRESOLVED_ufixed;  -- fixed point input
7066
    JUSTIFIED : in    SIDE  := right;
7067
    FIELD     : in    WIDTH := 0) is
7068
    variable s     : STRING(1 to value'length +1) := (others => ' ');
7069
    variable sindx : INTEGER;
7070
  begin  -- function write   Example: 0011.1100
7071
    sindx := 1;
7072
    for i in value'high downto value'low loop
7073
      if i = -1 then
7074
        s(sindx) := '.';
7075
        sindx    := sindx + 1;
7076
      end if;
7077
      s(sindx) := MVL9_to_char(STD_ULOGIC(value(i)));
7078
      sindx    := sindx + 1;
7079
    end loop;
7080
    write(l, s, justified, field);
7081
  end procedure write;
7082
 
7083
  -- purpose: writes fixed point into a line
7084
  procedure write (
7085
    L         : inout LINE;               -- input line
7086
    VALUE     : in    UNRESOLVED_sfixed;  -- fixed point input
7087
    JUSTIFIED : in    SIDE  := right;
7088
    FIELD     : in    WIDTH := 0) is
7089
    variable s     : STRING(1 to value'length +1);
7090
    variable sindx : INTEGER;
7091
  begin  -- function write   Example: 0011.1100
7092
    sindx := 1;
7093
    for i in value'high downto value'low loop
7094
      if i = -1 then
7095
        s(sindx) := '.';
7096
        sindx    := sindx + 1;
7097
      end if;
7098
      s(sindx) := MVL9_to_char(STD_ULOGIC(value(i)));
7099
      sindx    := sindx + 1;
7100
    end loop;
7101
    write(l, s, justified, field);
7102
  end procedure write;
7103
 
7104
  procedure READ(L     : inout LINE;
7105
                 VALUE : out   UNRESOLVED_ufixed) is
7106
    -- Possible data:  00000.0000000
7107
    --                 000000000000
7108
    variable c      : CHARACTER;
7109
    variable readOk : BOOLEAN;
7110
    variable i      : INTEGER;          -- index variable
7111
    variable mv : ufixed (VALUE'range);
7112
    variable lastu  : BOOLEAN := false;       -- last character was an "_"
7113
    variable founddot : BOOLEAN := false;  -- found a "."
7114
  begin  -- READ
7115
    VALUE := (VALUE'range => 'U');
7116
    Skip_whitespace (L);
7117
    if VALUE'length > 0 then            -- non Null input string
7118
      read (l, c, readOk);
7119
      i := value'high;
7120
      while i >= VALUE'low loop
7121
        if readOk = false then              -- Bail out if there was a bad read
7122
          report "fixed_pkg:" & "READ(ufixed) "
7123
            & "End of string encountered"
7124
            severity error;
7125
          return;
7126
        elsif c = '_' then
7127
          if i = value'high then
7128
            report "fixed_pkg:" & "READ(ufixed) "
7129
              & "String begins with an ""_""" severity error;
7130
            return;
7131
          elsif lastu then
7132
            report "fixed_pkg:" & "READ(ufixed) "
7133
              & "Two underscores detected in input string ""__"""
7134
              severity error;
7135
            return;
7136
          else
7137
            lastu := true;
7138
          end if;
7139
        elsif c = '.' then                -- binary point
7140
          if founddot then
7141
            report "fixed_pkg:" & "READ(ufixed) "
7142
              & "Two binary points found in input string" severity error;
7143
            return;
7144
          elsif i /= -1 then                 -- Seperator in the wrong spot
7145
            report "fixed_pkg:" & "READ(ufixed) "
7146
              & "Decimal point does not match number format "
7147
              severity error;
7148
            return;
7149
          end if;
7150
          founddot := true;
7151
          lastu := false;
7152
        elsif c = ' ' or c = NBSP or c = HT then  -- reading done.
7153
          report "fixed_pkg:" & "READ(ufixed) "
7154
            & "Short read, Space encounted in input string"
7155
            severity error;
7156
          return;
7157
        elsif char_to_MVL9plus(c) = error then
7158
          report "fixed_pkg:" & "READ(ufixed) "
7159
            & "Character '" &
7160
            c & "' read, expected STD_ULOGIC literal."
7161
            severity error;
7162
          return;
7163
        else
7164
          mv(i) := char_to_MVL9(c);
7165
          i := i - 1;
7166
          if i < mv'low then
7167
            VALUE := mv;
7168
            return;
7169
          end if;
7170
          lastu := false;
7171
        end if;
7172
        read(L, c, readOk);
7173
      end loop;
7174
    end if;
7175
  end procedure READ;
7176
 
7177
  procedure READ(L     : inout LINE;
7178
                 VALUE : out   UNRESOLVED_ufixed;
7179
                 GOOD  : out   BOOLEAN) is
7180
    -- Possible data:  00000.0000000
7181
    --                 000000000000
7182
    variable c      : CHARACTER;
7183
    variable readOk : BOOLEAN;
7184
    variable mv : ufixed (VALUE'range);
7185
    variable i      : INTEGER;          -- index variable
7186
    variable lastu  : BOOLEAN := false;       -- last character was an "_"
7187
    variable founddot : BOOLEAN := false;  -- found a "."
7188
  begin  -- READ
7189
    VALUE := (VALUE'range => 'U');
7190
    Skip_whitespace (L);
7191
    if VALUE'length > 0 then
7192
      read (l, c, readOk);
7193
      i := value'high;
7194
      GOOD := false;
7195
      while i >= VALUE'low loop
7196
        if not readOk then     -- Bail out if there was a bad read
7197
          return;
7198
        elsif c = '_' then
7199
          if i = value'high then          -- Begins with an "_"
7200
            return;
7201
          elsif lastu then               -- "__" detected
7202
            return;
7203
          else
7204
            lastu := true;
7205
          end if;
7206
        elsif c = '.' then                -- binary point
7207
          if founddot then
7208
            return;
7209
          elsif i /= -1 then                 -- Seperator in the wrong spot
7210
            return;
7211
          end if;
7212
          founddot := true;
7213
          lastu := false;
7214
        elsif (char_to_MVL9plus(c) = error) then   -- Illegal character/short read
7215
          return;
7216
        else
7217
          mv(i) := char_to_MVL9(c);
7218
          i := i - 1;
7219
          if i < mv'low then             -- reading done
7220
            GOOD := true;
7221
            VALUE := mv;
7222
            return;
7223
          end if;
7224
          lastu := false;
7225
        end if;
7226
        read(L, c, readOk);
7227
      end loop;
7228
    else
7229
      GOOD := true;                   -- read into a null array
7230
    end if;
7231
  end procedure READ;
7232
 
7233
  procedure READ(L     : inout LINE;
7234
                 VALUE : out   UNRESOLVED_sfixed) is
7235
    variable c      : CHARACTER;
7236
    variable readOk : BOOLEAN;
7237
    variable i      : INTEGER;          -- index variable
7238
    variable mv : sfixed (VALUE'range);
7239
    variable lastu  : BOOLEAN := false;       -- last character was an "_"
7240
    variable founddot : BOOLEAN := false;  -- found a "."
7241
  begin  -- READ
7242
    VALUE := (VALUE'range => 'U');
7243
    Skip_whitespace (L);
7244
    if VALUE'length > 0 then            -- non Null input string
7245
      read (l, c, readOk);
7246
      i := value'high;
7247
      while i >= VALUE'low loop
7248
        if readOk = false then              -- Bail out if there was a bad read
7249
          report "fixed_pkg:" & "READ(sfixed) "
7250
            & "End of string encountered"
7251
            severity error;
7252
          return;
7253
        elsif c = '_' then
7254
          if i = value'high then
7255
            report "fixed_pkg:" & "READ(sfixed) "
7256
              & "String begins with an ""_""" severity error;
7257
            return;
7258
          elsif lastu then
7259
            report "fixed_pkg:" & "READ(sfixed) "
7260
              & "Two underscores detected in input string ""__"""
7261
              severity error;
7262
            return;
7263
          else
7264
            lastu := true;
7265
          end if;
7266
        elsif c = '.' then                -- binary point
7267
          if founddot then
7268
            report "fixed_pkg:" & "READ(sfixed) "
7269
              & "Two binary points found in input string" severity error;
7270
            return;
7271
          elsif i /= -1 then                 -- Seperator in the wrong spot
7272
            report "fixed_pkg:" & "READ(sfixed) "
7273
              & "Decimal point does not match number format "
7274
              severity error;
7275
            return;
7276
          end if;
7277
          founddot := true;
7278
          lastu := false;
7279
        elsif c = ' ' or c = NBSP or c = HT then  -- reading done.
7280
          report "fixed_pkg:" & "READ(sfixed) "
7281
            & "Short read, Space encounted in input string"
7282
            severity error;
7283
          return;
7284
        elsif char_to_MVL9plus(c) = error then
7285
          report "fixed_pkg:" & "READ(sfixed) "
7286
            & "Character '" &
7287
            c & "' read, expected STD_ULOGIC literal."
7288
            severity error;
7289
          return;
7290
        else
7291
          mv(i) := char_to_MVL9(c);
7292
          i := i - 1;
7293
          if i < mv'low then
7294
            VALUE := mv;
7295
            return;
7296
          end if;
7297
          lastu := false;
7298
        end if;
7299
        read(L, c, readOk);
7300
      end loop;
7301
    end if;
7302
  end procedure READ;
7303
 
7304
  procedure READ(L     : inout LINE;
7305
                 VALUE : out   UNRESOLVED_sfixed;
7306
                 GOOD  : out   BOOLEAN) is
7307
    variable value_ufixed : UNRESOLVED_ufixed (VALUE'range);
7308
  begin  -- READ
7309
    READ (L => L, VALUE => value_ufixed, GOOD => GOOD);
7310
    VALUE := UNRESOLVED_sfixed (value_ufixed);
7311
  end procedure READ;
7312
 
7313
  -- octal read and write
7314
  procedure owrite (
7315
    L         : inout LINE;               -- input line
7316
    VALUE     : in    UNRESOLVED_ufixed;  -- fixed point input
7317
    JUSTIFIED : in    SIDE  := right;
7318
    FIELD     : in    WIDTH := 0) is
7319
  begin  -- Example 03.30
7320
    write (L         => L,
7321
           VALUE     => to_ostring (VALUE),
7322
           JUSTIFIED => JUSTIFIED,
7323
           FIELD     => FIELD);
7324
  end procedure owrite;
7325
 
7326
  procedure owrite (
7327
    L         : inout LINE;               -- input line
7328
    VALUE     : in    UNRESOLVED_sfixed;  -- fixed point input
7329
    JUSTIFIED : in    SIDE  := right;
7330
    FIELD     : in    WIDTH := 0) is
7331
  begin  -- Example 03.30
7332
    write (L         => L,
7333
           VALUE     => to_ostring (VALUE),
7334
           JUSTIFIED => JUSTIFIED,
7335
           FIELD     => FIELD);
7336
  end procedure owrite;
7337
 
7338
  -- purpose: Routines common to the OREAD routines
7339
  procedure OREAD_common (
7340
    L                : inout LINE;
7341
    slv              : out   STD_ULOGIC_VECTOR;
7342
    igood            : out   BOOLEAN;
7343
    idex             : out INTEGER;
7344
    constant bpoint : in INTEGER;       -- binary point
7345
    constant message : in    BOOLEAN;
7346
    constant smath   : in    BOOLEAN) is
7347
 
7348
    -- purpose: error message routine
7349
    procedure errmes (
7350
      constant mess : in STRING) is     -- error message
7351
    begin
7352
      if message then
7353
        if smath then
7354
          report "fixed_pkg:"
7355
            & "OREAD(sfixed) "
7356
            & mess
7357
            severity error;
7358
        else
7359
          report "fixed_pkg:"
7360
            & "OREAD(ufixed) "
7361
            & mess
7362
            severity error;
7363
        end if;
7364
      end if;
7365
    end procedure errmes;
7366
    variable xgood : BOOLEAN;
7367
    variable nybble : STD_ULOGIC_VECTOR (2 downto 0);        -- 3 bits
7368
    variable c : CHARACTER;
7369
    variable i : INTEGER;
7370
    variable lastu  : BOOLEAN := false;       -- last character was an "_"
7371
    variable founddot : BOOLEAN := false;  -- found a dot.
7372
  begin
7373
    Skip_whitespace (L);
7374
    if slv'length > 0 then
7375
      i := slv'high;
7376
      read (l, c, xgood);
7377
      while i > 0 loop
7378
        if xgood = false then
7379
          errmes ("Error: end of string encountered");
7380
          exit;
7381
        elsif c = '_' then
7382
          if i = slv'length then
7383
            errmes ("Error: String begins with an ""_""");
7384
            xgood := false;
7385
            exit;
7386
          elsif lastu then
7387
            errmes ("Error: Two underscores detected in input string ""__""");
7388
            xgood := false;
7389
            exit;
7390
          else
7391
            lastu := true;
7392
          end if;
7393
        elsif (c = '.') then
7394
          if (i + 1 /= bpoint) then
7395
            errmes ("encountered ""."" at wrong index");
7396
            xgood := false;
7397
            exit;
7398
          elsif i = slv'length then
7399
            errmes ("encounted a ""."" at the beginning of the line");
7400
            xgood := false;
7401
            exit;
7402
          elsif founddot then
7403
            errmes ("Two ""."" encounted in input string");
7404
            xgood := false;
7405
            exit;
7406
          end if;
7407
          founddot := true;
7408
          lastu := false;
7409
        else
7410
          Char2triBits(c, nybble, xgood, message);
7411
          if not xgood then
7412
            exit;
7413
          end if;
7414
          slv (i downto i-2) := nybble;
7415
          i := i - 3;
7416
          lastu := false;
7417
        end if;
7418
        if i > 0 then
7419
          read (L, c, xgood);
7420
        end if;
7421
      end loop;
7422
      idex := i;
7423
      igood := xgood;
7424
    else
7425
      igood := true;                  -- read into a null array
7426
      idex := -1;
7427
    end if;
7428
  end procedure OREAD_common;
7429
 
7430
  -- Note that for Octal and Hex read, you can not start with a ".",
7431
  -- the read is for numbers formatted "A.BC".  These routines go to
7432
  -- the nearest bounds, so "F.E" will fit into an sfixed (2 downto -3).
7433
  procedure OREAD (L     : inout LINE;
7434
                   VALUE : out   UNRESOLVED_ufixed) is
7435
    constant hbv    : INTEGER := (((maximum(3, (VALUE'high+1))+2)/3)*3)-1;
7436
    constant lbv    : INTEGER := ((mine(0, VALUE'low)-2)/3)*3;
7437
    variable slv    : STD_ULOGIC_VECTOR (hbv-lbv downto 0);  -- high bits
7438
    variable valuex : UNRESOLVED_ufixed (hbv downto lbv);
7439
    variable igood  : BOOLEAN;
7440
    variable i      : INTEGER;
7441
  begin
7442
    VALUE := (VALUE'range => 'U');
7443
    OREAD_common ( L => L,
7444
                   slv => slv,
7445
                   igood => igood,
7446
                   idex => i,
7447
                   bpoint => -lbv,
7448
                   message => true,
7449
                   smath => false);
7450
    if igood then                       -- We did not get another error
7451
      if not ((i = -1) and               -- We read everything, and high bits 0
7452
              (or_reduce (slv(hbv-lbv downto VALUE'high+1-lbv)) = '0')) then
7453
        report "fixed_pkg:"
7454
          & "OREAD(ufixed): Vector truncated."
7455
          severity error;
7456
      else
7457
        if (or_reduce (slv(VALUE'low-lbv-1 downto 0)) = '1') then
7458
          assert NO_WARNING
7459
            report "fixed_pkg:"
7460
            & "OREAD(ufixed): Vector truncated"
7461
            severity warning;
7462
        end if;
7463
        valuex := to_ufixed (slv, hbv, lbv);
7464
        VALUE  := valuex (VALUE'range);
7465
      end if;
7466
    end if;
7467
  end procedure OREAD;
7468
 
7469
  procedure OREAD(L     : inout LINE;
7470
                  VALUE : out   UNRESOLVED_ufixed;
7471
                  GOOD  : out   BOOLEAN) is
7472
    constant hbv    : INTEGER := (((maximum(3, (VALUE'high+1))+2)/3)*3)-1;
7473
    constant lbv    : INTEGER := ((mine(0, VALUE'low)-2)/3)*3;
7474
    variable slv    : STD_ULOGIC_VECTOR (hbv-lbv downto 0);  -- high bits
7475
    variable valuex : UNRESOLVED_ufixed (hbv downto lbv);
7476
    variable igood  : BOOLEAN;
7477
    variable i      : INTEGER;
7478
  begin
7479
    VALUE := (VALUE'range => 'U');
7480
    OREAD_common ( L => L,
7481
                   slv => slv,
7482
                   igood => igood,
7483
                   idex => i,
7484
                   bpoint => -lbv,
7485
                   message => false,
7486
                   smath => false);
7487
    if (igood and                   -- We did not get another error
7488
        (i = -1) and                -- We read everything, and high bits 0
7489
        (or_reduce (slv(hbv-lbv downto VALUE'high+1-lbv)) = '0')) then
7490
      valuex := to_ufixed (slv, hbv, lbv);
7491
      VALUE  := valuex (VALUE'range);
7492
      good := true;
7493
    else
7494
      good := false;
7495
    end if;
7496
  end procedure OREAD;
7497
 
7498
  procedure OREAD(L     : inout LINE;
7499
                  VALUE : out   UNRESOLVED_sfixed) is
7500
    constant hbv    : INTEGER := (((maximum(3, (VALUE'high+1))+2)/3)*3)-1;
7501
    constant lbv    : INTEGER := ((mine(0, VALUE'low)-2)/3)*3;
7502
    variable slv    : STD_ULOGIC_VECTOR (hbv-lbv downto 0);  -- high bits
7503
    variable valuex : UNRESOLVED_sfixed (hbv downto lbv);
7504
    variable igood  : BOOLEAN;
7505
    variable i      : INTEGER;
7506
  begin
7507
    VALUE := (VALUE'range => 'U');
7508
    OREAD_common ( L => L,
7509
                   slv => slv,
7510
                   igood => igood,
7511
                   idex => i,
7512
                   bpoint => -lbv,
7513
                   message => true,
7514
                   smath => true);
7515
    if igood then                       -- We did not get another error
7516
      if not ((i = -1) and               -- We read everything
7517
              ((slv(VALUE'high-lbv) = '0' and      -- sign bits = extra bits
7518
                or_reduce (slv(hbv-lbv downto VALUE'high+1-lbv)) = '0') or
7519
               (slv(VALUE'high-lbv) = '1' and
7520
                and_reduce (slv(hbv-lbv downto VALUE'high+1-lbv)) = '1'))) then
7521
        report "fixed_pkg:"
7522
          & "OREAD(sfixed): Vector truncated."
7523
          severity error;
7524
      else
7525
        if (or_reduce (slv(VALUE'low-lbv-1 downto 0)) = '1') then
7526
          assert NO_WARNING
7527
            report "fixed_pkg:"
7528
            & "OREAD(sfixed): Vector truncated"
7529
            severity warning;
7530
        end if;
7531
        valuex := to_sfixed (slv, hbv, lbv);
7532
        VALUE  := valuex (VALUE'range);
7533
      end if;
7534
    end if;
7535
  end procedure OREAD;
7536
 
7537
  procedure OREAD(L     : inout LINE;
7538
                  VALUE : out   UNRESOLVED_sfixed;
7539
                  GOOD  : out   BOOLEAN) is
7540
    constant hbv    : INTEGER := (((maximum(3, (VALUE'high+1))+2)/3)*3)-1;
7541
    constant lbv    : INTEGER := ((mine(0, VALUE'low)-2)/3)*3;
7542
    variable slv    : STD_ULOGIC_VECTOR (hbv-lbv downto 0);  -- high bits
7543
    variable valuex : UNRESOLVED_sfixed (hbv downto lbv);
7544
    variable igood  : BOOLEAN;
7545
    variable i      : INTEGER;
7546
  begin
7547
    VALUE := (VALUE'range => 'U');
7548
    OREAD_common ( L => L,
7549
                   slv => slv,
7550
                   igood => igood,
7551
                   idex => i,
7552
                   bpoint => -lbv,
7553
                   message => false,
7554
                   smath => true);
7555
    if (igood                       -- We did not get another error
7556
        and (i = -1)                -- We read everything
7557
        and ((slv(VALUE'high-lbv) = '0' and  -- sign bits = extra bits
7558
              or_reduce (slv(hbv-lbv downto VALUE'high+1-lbv)) = '0') or
7559
             (slv(VALUE'high-lbv) = '1' and
7560
              and_reduce (slv(hbv-lbv downto VALUE'high+1-lbv)) = '1'))) then
7561
      valuex := to_sfixed (slv, hbv, lbv);
7562
      VALUE  := valuex (VALUE'range);
7563
      good := true;
7564
    else
7565
      good := false;
7566
    end if;
7567
  end procedure OREAD;
7568
 
7569
  -- hex read and write
7570
  procedure hwrite (
7571
    L         : inout LINE;               -- input line
7572
    VALUE     : in    UNRESOLVED_ufixed;  -- fixed point input
7573
    JUSTIFIED : in    SIDE  := right;
7574
    FIELD     : in    WIDTH := 0) is
7575
  begin  -- Example 03.30
7576
    write (L         => L,
7577
           VALUE     => to_hstring (VALUE),
7578
           JUSTIFIED => JUSTIFIED,
7579
           FIELD     => FIELD);
7580
  end procedure hwrite;
7581
 
7582
  -- purpose: writes fixed point into a line
7583
  procedure hwrite (
7584
    L         : inout LINE;               -- input line
7585
    VALUE     : in    UNRESOLVED_sfixed;  -- fixed point input
7586
    JUSTIFIED : in    SIDE  := right;
7587
    FIELD     : in    WIDTH := 0) is
7588
  begin  -- Example 03.30
7589
    write (L         => L,
7590
           VALUE     => to_hstring (VALUE),
7591
           JUSTIFIED => JUSTIFIED,
7592
           FIELD     => FIELD);
7593
  end procedure hwrite;
7594
 
7595
  -- purpose: Routines common to the OREAD routines
7596
  procedure HREAD_common (
7597
    L                : inout LINE;
7598
    slv              : out   STD_ULOGIC_VECTOR;
7599
    igood            : out   BOOLEAN;
7600
    idex             : out INTEGER;
7601
    constant bpoint : in INTEGER;       -- binary point
7602
    constant message : in    BOOLEAN;
7603
    constant smath   : in    BOOLEAN) is
7604
 
7605
    -- purpose: error message routine
7606
    procedure errmes (
7607
      constant mess : in STRING) is     -- error message
7608
    begin
7609
      if message then
7610
        if smath then
7611
          report "fixed_pkg:"
7612
            & "HREAD(sfixed) "
7613
            & mess
7614
            severity error;
7615
        else
7616
          report "fixed_pkg:"
7617
            & "HREAD(ufixed) "
7618
            & mess
7619
            severity error;
7620
        end if;
7621
      end if;
7622
    end procedure errmes;
7623
    variable xgood : BOOLEAN;
7624
    variable nybble : STD_ULOGIC_VECTOR (3 downto 0);        -- 4 bits
7625
    variable c : CHARACTER;
7626
    variable i : INTEGER;
7627
    variable lastu  : BOOLEAN := false;       -- last character was an "_"
7628
    variable founddot : BOOLEAN := false;  -- found a dot.
7629
  begin
7630
    Skip_whitespace (L);
7631
    if slv'length > 0 then
7632
      i := slv'high;
7633
      read (l, c, xgood);
7634
      while i > 0 loop
7635
        if xgood = false then
7636
          errmes ("Error: end of string encountered");
7637
          exit;
7638
        elsif c = '_' then
7639
          if i = slv'length then
7640
            errmes ("Error: String begins with an ""_""");
7641
            xgood := false;
7642
            exit;
7643
          elsif lastu then
7644
            errmes ("Error: Two underscores detected in input string ""__""");
7645
            xgood := false;
7646
            exit;
7647
          else
7648
            lastu := true;
7649
          end if;
7650
        elsif (c = '.') then
7651
          if (i + 1 /= bpoint) then
7652
            errmes ("encountered ""."" at wrong index");
7653
            xgood := false;
7654
            exit;
7655
          elsif i = slv'length then
7656
            errmes ("encounted a ""."" at the beginning of the line");
7657
            xgood := false;
7658
            exit;
7659
          elsif founddot then
7660
            errmes ("Two ""."" encounted in input string");
7661
            xgood := false;
7662
            exit;
7663
          end if;
7664
          founddot := true;
7665
          lastu := false;
7666
        else
7667
          Char2QuadBits(c, nybble, xgood, message);
7668
          if not xgood then
7669
            exit;
7670
          end if;
7671
          slv (i downto i-3) := nybble;
7672
          i := i - 4;
7673
          lastu := false;
7674
        end if;
7675
        if i > 0 then
7676
          read (L, c, xgood);
7677
        end if;
7678
      end loop;
7679
      idex := i;
7680
      igood := xgood;
7681
    else
7682
      idex := -1;
7683
      igood := true;                    -- read null string
7684
    end if;
7685
  end procedure HREAD_common;
7686
 
7687
  procedure HREAD(L     : inout LINE;
7688
                  VALUE : out   UNRESOLVED_ufixed) is
7689
    constant hbv    : INTEGER := (((maximum(4, (VALUE'high+1))+3)/4)*4)-1;
7690
    constant lbv    : INTEGER := ((mine(0, VALUE'low)-3)/4)*4;
7691
    variable slv    : STD_ULOGIC_VECTOR (hbv-lbv downto 0);  -- high bits
7692
    variable valuex : UNRESOLVED_ufixed (hbv downto lbv);
7693
    variable igood  : BOOLEAN;
7694
    variable i      : INTEGER;
7695
  begin
7696
    VALUE := (VALUE'range => 'U');
7697
    HREAD_common ( L => L,
7698
                   slv => slv,
7699
                   igood => igood,
7700
                   idex => i,
7701
                   bpoint => -lbv,
7702
                   message => false,
7703
                   smath => false);
7704
    if igood then
7705
      if not ((i = -1) and               -- We read everything, and high bits 0
7706
              (or_reduce (slv(hbv-lbv downto VALUE'high+1-lbv)) = '0')) then
7707
        report "fixed_pkg:"
7708
          & "HREAD(ufixed): Vector truncated."
7709
          severity error;
7710
      else
7711
        if (or_reduce (slv(VALUE'low-lbv-1 downto 0)) = '1') then
7712
          assert NO_WARNING
7713
            report "fixed_pkg:"
7714
            & "HREAD(ufixed): Vector truncated"
7715
            severity warning;
7716
        end if;
7717
        valuex := to_ufixed (slv, hbv, lbv);
7718
        VALUE  := valuex (VALUE'range);
7719
      end if;
7720
    end if;
7721
  end procedure HREAD;
7722
 
7723
  procedure HREAD(L     : inout LINE;
7724
                  VALUE : out   UNRESOLVED_ufixed;
7725
                  GOOD  : out   BOOLEAN) is
7726
    constant hbv    : INTEGER := (((maximum(4, (VALUE'high+1))+3)/4)*4)-1;
7727
    constant lbv    : INTEGER := ((mine(0, VALUE'low)-3)/4)*4;
7728
    variable slv    : STD_ULOGIC_VECTOR (hbv-lbv downto 0);  -- high bits
7729
    variable valuex : UNRESOLVED_ufixed (hbv downto lbv);
7730
    variable igood  : BOOLEAN;
7731
    variable i      : INTEGER;
7732
  begin
7733
    VALUE := (VALUE'range => 'U');
7734
    HREAD_common ( L => L,
7735
                   slv => slv,
7736
                   igood => igood,
7737
                   idex => i,
7738
                   bpoint => -lbv,
7739
                   message => false,
7740
                   smath => false);
7741
    if (igood and                   -- We did not get another error
7742
        (i = -1) and                -- We read everything, and high bits 0
7743
        (or_reduce (slv(hbv-lbv downto VALUE'high+1-lbv)) = '0')) then
7744
      valuex := to_ufixed (slv, hbv, lbv);
7745
      VALUE  := valuex (VALUE'range);
7746
      good := true;
7747
    else
7748
      good := false;
7749
    end if;
7750
  end procedure HREAD;
7751
 
7752
  procedure HREAD(L     : inout LINE;
7753
                  VALUE : out   UNRESOLVED_sfixed) is
7754
    constant hbv    : INTEGER := (((maximum(4, (VALUE'high+1))+3)/4)*4)-1;
7755
    constant lbv    : INTEGER := ((mine(0, VALUE'low)-3)/4)*4;
7756
    variable slv    : STD_ULOGIC_VECTOR (hbv-lbv downto 0);  -- high bits
7757
    variable valuex : UNRESOLVED_sfixed (hbv downto lbv);
7758
    variable igood  : BOOLEAN;
7759
    variable i      : INTEGER;
7760
  begin
7761
    VALUE := (VALUE'range => 'U');
7762
    HREAD_common ( L => L,
7763
                   slv => slv,
7764
                   igood => igood,
7765
                   idex => i,
7766
                   bpoint => -lbv,
7767
                   message => true,
7768
                   smath => true);
7769
    if igood then                       -- We did not get another error
7770
      if not ((i = -1)                   -- We read everything
7771
              and ((slv(VALUE'high-lbv) = '0' and  -- sign bits = extra bits
7772
                    or_reduce (slv(hbv-lbv downto VALUE'high+1-lbv)) = '0') or
7773
                   (slv(VALUE'high-lbv) = '1' and
7774
                    and_reduce (slv(hbv-lbv downto VALUE'high+1-lbv)) = '1'))) then
7775
        report "fixed_pkg:"
7776
          & "HREAD(sfixed): Vector truncated."
7777
          severity error;
7778
      else
7779
        if (or_reduce (slv(VALUE'low-lbv-1 downto 0)) = '1') then
7780
          assert NO_WARNING
7781
            report "fixed_pkg:"
7782
            & "HREAD(sfixed): Vector truncated"
7783
            severity warning;
7784
        end if;
7785
        valuex := to_sfixed (slv, hbv, lbv);
7786
        VALUE  := valuex (VALUE'range);
7787
      end if;
7788
    end if;
7789
  end procedure HREAD;
7790
 
7791
  procedure HREAD(L     : inout LINE;
7792
                  VALUE : out   UNRESOLVED_sfixed;
7793
                  GOOD  : out   BOOLEAN) is
7794
    constant hbv    : INTEGER := (((maximum(4, (VALUE'high+1))+3)/4)*4)-1;
7795
    constant lbv    : INTEGER := ((mine(0, VALUE'low)-3)/4)*4;
7796
    variable slv    : STD_ULOGIC_VECTOR (hbv-lbv downto 0);  -- high bits
7797
    variable valuex : UNRESOLVED_sfixed (hbv downto lbv);
7798
    variable igood  : BOOLEAN;
7799
    variable i      : INTEGER;
7800
  begin
7801
    VALUE := (VALUE'range => 'U');
7802
    HREAD_common ( L => L,
7803
                   slv => slv,
7804
                   igood => igood,
7805
                   idex => i,
7806
                   bpoint => -lbv,
7807
                   message => false,
7808
                   smath => true);
7809
    if (igood and                   -- We did not get another error
7810
        (i = -1) and                -- We read everything
7811
        ((slv(VALUE'high-lbv) = '0' and  -- sign bits = extra bits
7812
          or_reduce (slv(hbv-lbv downto VALUE'high+1-lbv)) = '0') or
7813
         (slv(VALUE'high-lbv) = '1' and
7814
          and_reduce (slv(hbv-lbv downto VALUE'high+1-lbv)) = '1'))) then
7815
      valuex := to_sfixed (slv, hbv, lbv);
7816
      VALUE  := valuex (VALUE'range);
7817
      good := true;
7818
    else
7819
      good := false;
7820
    end if;
7821
  end procedure HREAD;
7822
 
7823
  function to_string (value : UNRESOLVED_ufixed) return STRING is
7824
    variable s     : STRING(1 to value'length +1) := (others => ' ');
7825
    variable subval : UNRESOLVED_ufixed (value'high downto -1);
7826
    variable sindx : INTEGER;
7827
  begin
7828
    if value'length < 1 then
7829
      return NUS;
7830
    else
7831
      if value'high < 0 then
7832
        if value(value'high) = 'Z' then
7833
          return to_string (resize (sfixed(value), 0, value'low));
7834
        else
7835
          return to_string (resize (value, 0, value'low));
7836
        end if;
7837
      elsif value'low >= 0 then
7838
        if Is_X (value(value'low)) then
7839
          subval := (others => value(value'low));
7840
          subval (value'range) := value;
7841
          return to_string(subval);
7842
        else
7843
          return to_string (resize (value, value'high, -1));
7844
        end if;
7845
      else
7846
        sindx := 1;
7847
        for i in value'high downto value'low loop
7848
          if i = -1 then
7849
            s(sindx) := '.';
7850
            sindx    := sindx + 1;
7851
          end if;
7852
          s(sindx) := MVL9_to_char(STD_ULOGIC(value(i)));
7853
          sindx    := sindx + 1;
7854
        end loop;
7855
        return s;
7856
      end if;
7857
    end if;
7858
  end function to_string;
7859
 
7860
  function to_string (value : UNRESOLVED_sfixed) return STRING is
7861
    variable s     : STRING(1 to value'length + 1) := (others => ' ');
7862
    variable subval : UNRESOLVED_sfixed (value'high downto -1);
7863
    variable sindx : INTEGER;
7864
  begin
7865
    if value'length < 1 then
7866
      return NUS;
7867
    else
7868
      if value'high < 0 then
7869
        return to_string (resize (value, 0, value'low));
7870
      elsif value'low >= 0 then
7871
        if Is_X (value(value'low)) then
7872
          subval := (others => value(value'low));
7873
          subval (value'range) := value;
7874
          return to_string(subval);
7875
        else
7876
          return to_string (resize (value, value'high, -1));
7877
        end if;
7878
      else
7879
        sindx := 1;
7880
        for i in value'high downto value'low loop
7881
          if i = -1 then
7882
            s(sindx) := '.';
7883
            sindx    := sindx + 1;
7884
          end if;
7885
          s(sindx) := MVL9_to_char(STD_ULOGIC(value(i)));
7886
          sindx    := sindx + 1;
7887
        end loop;
7888
        return s;
7889
      end if;
7890
    end if;
7891
  end function to_string;
7892
 
7893
  function to_ostring (value : UNRESOLVED_ufixed) return STRING is
7894
    constant lne  : INTEGER := (-VALUE'low+2)/3;
7895
    variable subval : UNRESOLVED_ufixed (value'high downto -3);
7896
    variable lpad : STD_ULOGIC_VECTOR (0 to (lne*3 + VALUE'low) -1);
7897
    variable slv : STD_ULOGIC_VECTOR (value'length-1 downto 0);
7898
  begin
7899
    if value'length < 1 then
7900
      return NUS;
7901
    else
7902
      if value'high < 0 then
7903
        if value(value'high) = 'Z' then
7904
          return to_ostring (resize (sfixed(value), 2, value'low));
7905
        else
7906
          return to_ostring (resize (value, 2, value'low));
7907
        end if;
7908
      elsif value'low >= 0 then
7909
        if Is_X (value(value'low)) then
7910
          subval := (others => value(value'low));
7911
          subval (value'range) := value;
7912
          return to_ostring(subval);
7913
        else
7914
          return to_ostring (resize (value, value'high, -3));
7915
        end if;
7916
      else
7917
        slv := to_sulv (value);
7918
        if Is_X (value (value'low)) then
7919
          lpad := (others => value (value'low));
7920
        else
7921
          lpad := (others => '0');
7922
        end if;
7923
        return to_ostring(slv(slv'high downto slv'high-VALUE'high))
7924
          & "."
7925
          & to_ostring(slv(slv'high-VALUE'high-1 downto 0) & lpad);
7926
      end if;
7927
    end if;
7928
  end function to_ostring;
7929
 
7930
  function to_hstring (value : UNRESOLVED_ufixed) return STRING is
7931
    constant lne  : INTEGER := (-VALUE'low+3)/4;
7932
    variable subval : UNRESOLVED_ufixed (value'high downto -4);
7933
    variable lpad : STD_ULOGIC_VECTOR (0 to (lne*4 + VALUE'low) -1);
7934
    variable slv : STD_ULOGIC_VECTOR (value'length-1 downto 0);
7935
  begin
7936
    if value'length < 1 then
7937
      return NUS;
7938
    else
7939
      if value'high < 0 then
7940
        if value(value'high) = 'Z' then
7941
          return to_hstring (resize (sfixed(value), 3, value'low));
7942
        else
7943
          return to_hstring (resize (value, 3, value'low));
7944
        end if;
7945
      elsif value'low >= 0 then
7946
        if Is_X (value(value'low)) then
7947
          subval := (others => value(value'low));
7948
          subval (value'range) := value;
7949
          return to_hstring(subval);
7950
        else
7951
          return to_hstring (resize (value, value'high, -4));
7952
        end if;
7953
      else
7954
        slv := to_sulv (value);
7955
        if Is_X (value (value'low)) then
7956
          lpad := (others => value(value'low));
7957
        else
7958
          lpad := (others => '0');
7959
        end if;
7960
        return to_hstring(slv(slv'high downto slv'high-VALUE'high))
7961
          & "."
7962
          & to_hstring(slv(slv'high-VALUE'high-1 downto 0)&lpad);
7963
      end if;
7964
    end if;
7965
  end function to_hstring;
7966
 
7967
  function to_ostring (value : UNRESOLVED_sfixed) return STRING is
7968
    constant ne   : INTEGER := ((value'high+1)+2)/3;
7969
    variable pad  : STD_ULOGIC_VECTOR(0 to (ne*3 - (value'high+1)) - 1);
7970
    constant lne  : INTEGER := (-VALUE'low+2)/3;
7971
    variable subval : UNRESOLVED_sfixed (value'high downto -3);
7972
    variable lpad : STD_ULOGIC_VECTOR (0 to (lne*3 + VALUE'low) -1);
7973
    variable slv  : STD_ULOGIC_VECTOR (VALUE'high - VALUE'low downto 0);
7974
  begin
7975
    if value'length < 1 then
7976
      return NUS;
7977
    else
7978
      if value'high < 0 then
7979
        return to_ostring (resize (value, 2, value'low));
7980
      elsif value'low >= 0 then
7981
        if Is_X (value(value'low)) then
7982
          subval := (others => value(value'low));
7983
          subval (value'range) := value;
7984
          return to_ostring(subval);
7985
        else
7986
          return to_ostring (resize (value, value'high, -3));
7987
        end if;
7988
      else
7989
        pad := (others => value(value'high));
7990
        slv := to_sulv (value);
7991
        if Is_X (value (value'low)) then
7992
          lpad := (others => value(value'low));
7993
        else
7994
          lpad := (others => '0');
7995
        end if;
7996
        return to_ostring(pad & slv(slv'high downto slv'high-VALUE'high))
7997
          & "."
7998
          & to_ostring(slv(slv'high-VALUE'high-1 downto 0) & lpad);
7999
      end if;
8000
    end if;
8001
  end function to_ostring;
8002
 
8003
  function to_hstring (value : UNRESOLVED_sfixed) return STRING is
8004
    constant ne   : INTEGER := ((value'high+1)+3)/4;
8005
    variable pad  : STD_ULOGIC_VECTOR(0 to (ne*4 - (value'high+1)) - 1);
8006
    constant lne  : INTEGER := (-VALUE'low+3)/4;
8007
    variable subval : UNRESOLVED_sfixed (value'high downto -4);
8008
    variable lpad : STD_ULOGIC_VECTOR (0 to (lne*4 + VALUE'low) -1);
8009
    variable slv  : STD_ULOGIC_VECTOR (value'length-1 downto 0);
8010
  begin
8011
    if value'length < 1 then
8012
      return NUS;
8013
    else
8014
      if value'high < 0 then
8015
        return to_hstring (resize (value, 3, value'low));
8016
      elsif value'low >= 0 then
8017
        if Is_X (value(value'low)) then
8018
          subval := (others => value(value'low));
8019
          subval (value'range) := value;
8020
          return to_hstring(subval);
8021
        else
8022
          return to_hstring (resize (value, value'high, -4));
8023
        end if;
8024
      else
8025
        slv := to_sulv (value);
8026
        pad := (others => value(value'high));
8027
        if Is_X (value (value'low)) then
8028
          lpad := (others => value(value'low));
8029
        else
8030
          lpad := (others => '0');
8031
        end if;
8032
        return to_hstring(pad & slv(slv'high downto slv'high-VALUE'high))
8033
          & "."
8034
          & to_hstring(slv(slv'high-VALUE'high-1 downto 0) & lpad);
8035
      end if;
8036
    end if;
8037
  end function to_hstring;
8038
 
8039
  -- From string functions allow you to convert a string into a fixed
8040
  -- point number.  Example:
8041
  --  signal uf1 : ufixed (3 downto -3);
8042
  --  uf1 <= from_string ("0110.100", uf1'high, uf1'low); -- 6.5
8043
  -- The "." is optional in this syntax, however it exist and is
8044
  -- in the wrong location an error is produced.  Overflow will
8045
  -- result in saturation.
8046
 
8047
  function from_string (
8048
    bstring              : STRING;      -- binary string
8049
    constant left_index  : INTEGER;
8050
    constant right_index : INTEGER)
8051
    return UNRESOLVED_ufixed is
8052
    variable result : UNRESOLVED_ufixed (left_index downto right_index);
8053
    variable L      : LINE;
8054
    variable good   : BOOLEAN;
8055
  begin
8056
    L := new STRING'(bstring);
8057
    read (L, result, good);
8058
    deallocate (L);
8059
    assert (good)
8060
      report "fixed_pkg:"
8061
      & "from_string: Bad string "& bstring severity error;
8062
    return result;
8063
  end function from_string;
8064
 
8065
  -- Octal and hex conversions work as follows:
8066
  -- uf1 <= from_hstring ("6.8", 3, -3); -- 6.5 (bottom zeros dropped)
8067
  -- uf1 <= from_ostring ("06.4", 3, -3); -- 6.5 (top zeros dropped)
8068
  function from_ostring (
8069
    ostring              : STRING;      -- Octal string
8070
    constant left_index  : INTEGER;
8071
    constant right_index : INTEGER)
8072
    return UNRESOLVED_ufixed is
8073
    variable result : UNRESOLVED_ufixed (left_index downto right_index);
8074
    variable L      : LINE;
8075
    variable good   : BOOLEAN;
8076
  begin
8077
    L := new STRING'(ostring);
8078
    oread (L, result, good);
8079
    deallocate (L);
8080
    assert (good)
8081
      report "fixed_pkg:"
8082
      & "from_ostring: Bad string "& ostring severity error;
8083
    return result;
8084
  end function from_ostring;
8085
 
8086
  function from_hstring (
8087
    hstring              : STRING;      -- hex string
8088
    constant left_index  : INTEGER;
8089
    constant right_index : INTEGER)
8090
    return UNRESOLVED_ufixed is
8091
    variable result : UNRESOLVED_ufixed (left_index downto right_index);
8092
    variable L      : LINE;
8093
    variable good   : BOOLEAN;
8094
  begin
8095
    L := new STRING'(hstring);
8096
    hread (L, result, good);
8097
    deallocate (L);
8098
    assert (good)
8099
      report "fixed_pkg:"
8100
      & "from_hstring: Bad string "& hstring severity error;
8101
    return result;
8102
  end function from_hstring;
8103
 
8104
  function from_string (
8105
    bstring              : STRING;      -- binary string
8106
    constant left_index  : INTEGER;
8107
    constant right_index : INTEGER)
8108
    return UNRESOLVED_sfixed is
8109
    variable result : UNRESOLVED_sfixed (left_index downto right_index);
8110
    variable L      : LINE;
8111
    variable good   : BOOLEAN;
8112
  begin
8113
    L := new STRING'(bstring);
8114
    read (L, result, good);
8115
    deallocate (L);
8116
    assert (good)
8117
      report "fixed_pkg:"
8118
      & "from_string: Bad string "& bstring severity error;
8119
    return result;
8120
  end function from_string;
8121
 
8122
  function from_ostring (
8123
    ostring              : STRING;      -- Octal string
8124
    constant left_index  : INTEGER;
8125
    constant right_index : INTEGER)
8126
    return UNRESOLVED_sfixed is
8127
    variable result : UNRESOLVED_sfixed (left_index downto right_index);
8128
    variable L      : LINE;
8129
    variable good   : BOOLEAN;
8130
  begin
8131
    L := new STRING'(ostring);
8132
    oread (L, result, good);
8133
    deallocate (L);
8134
    assert (good)
8135
      report "fixed_pkg:"
8136
      & "from_ostring: Bad string "& ostring severity error;
8137
    return result;
8138
  end function from_ostring;
8139
 
8140
  function from_hstring (
8141
    hstring              : STRING;      -- hex string
8142
    constant left_index  : INTEGER;
8143
    constant right_index : INTEGER)
8144
    return UNRESOLVED_sfixed is
8145
    variable result : UNRESOLVED_sfixed (left_index downto right_index);
8146
    variable L      : LINE;
8147
    variable good   : BOOLEAN;
8148
  begin
8149
    L := new STRING'(hstring);
8150
    hread (L, result, good);
8151
    deallocate (L);
8152
    assert (good)
8153
      report "fixed_pkg:"
8154
      & "from_hstring: Bad string "& hstring severity error;
8155
    return result;
8156
  end function from_hstring;
8157
 
8158
  -- Same as above, "size_res" is used for it's range only.
8159
  function from_string (
8160
    bstring  : STRING;                  -- binary string
8161
    size_res : UNRESOLVED_ufixed)
8162
    return UNRESOLVED_ufixed is
8163
  begin
8164
    return from_string (bstring, size_res'high, size_res'low);
8165
  end function from_string;
8166
 
8167
  function from_ostring (
8168
    ostring  : STRING;                  -- Octal string
8169
    size_res : UNRESOLVED_ufixed)
8170
    return UNRESOLVED_ufixed is
8171
  begin
8172
    return from_ostring (ostring, size_res'high, size_res'low);
8173
  end function from_ostring;
8174
 
8175
  function from_hstring (
8176
    hstring  : STRING;                  -- hex string
8177
    size_res : UNRESOLVED_ufixed)
8178
    return UNRESOLVED_ufixed is
8179
  begin
8180
    return from_hstring(hstring, size_res'high, size_res'low);
8181
  end function from_hstring;
8182
 
8183
  function from_string (
8184
    bstring  : STRING;                  -- binary string
8185
    size_res : UNRESOLVED_sfixed)
8186
    return UNRESOLVED_sfixed is
8187
  begin
8188
    return from_string (bstring, size_res'high, size_res'low);
8189
  end function from_string;
8190
 
8191
  function from_ostring (
8192
    ostring  : STRING;                  -- Octal string
8193
    size_res : UNRESOLVED_sfixed)
8194
    return UNRESOLVED_sfixed is
8195
  begin
8196
    return from_ostring (ostring, size_res'high, size_res'low);
8197
  end function from_ostring;
8198
 
8199
  function from_hstring (
8200
    hstring  : STRING;                  -- hex string
8201
    size_res : UNRESOLVED_sfixed)
8202
    return UNRESOLVED_sfixed is
8203
  begin
8204
    return from_hstring (hstring, size_res'high, size_res'low);
8205
  end function from_hstring;
8206
 
8207
  -- purpose: Calculate the string boundaries
8208
  procedure calculate_string_boundry (
8209
    arg         : in  STRING;           -- input string
8210
    left_index  : out INTEGER;          -- left
8211
    right_index : out INTEGER) is       -- right
8212
    -- examples "10001.111" would return +4, -3
8213
    -- "07X.44" would return +2, -2 (then the octal routine would multiply)
8214
    -- "A_B_._C" would return +1, -1 (then the hex routine would multiply)
8215
    alias xarg : STRING (arg'length downto 1) is arg;  -- make it downto range
8216
    variable l, r : INTEGER;            -- internal indexes
8217
    variable founddot : BOOLEAN := false;
8218
  begin
8219
    if arg'length > 0 then
8220
      l := xarg'high - 1;
8221
      r := 0;
8222
      for i in xarg'range loop
8223
        if xarg(i) = '_' then
8224
          if r = 0 then
8225
            l := l - 1;
8226
          else
8227
            r := r + 1;
8228
          end if;
8229
        elsif xarg(i) = ' ' or xarg(i) = NBSP or xarg(i) = HT then
8230
          report "fixed_pkg:"
8231
            & "Found a space in the input STRING " & xarg
8232
            severity error;
8233
        elsif xarg(i) = '.' then
8234
          if founddot then
8235
            report "fixed_pkg:"
8236
              & "Found two binary points in input string " & xarg
8237
              severity error;
8238
          else
8239
            l := l - i;
8240
            r := -i + 1;
8241
            founddot := true;
8242
          end if;
8243
        end if;
8244
      end loop;
8245
      left_index := l;
8246
      right_index := r;
8247
    else
8248
      left_index := 0;
8249
      right_index := 0;
8250
    end if;
8251
  end procedure calculate_string_boundry;
8252
 
8253
  -- Direct conversion functions.  Example:
8254
  --  signal uf1 : ufixed (3 downto -3);
8255
  --  uf1 <= from_string ("0110.100"); -- 6.5
8256
  -- In this case the "." is not optional, and the size of
8257
  -- the output must match exactly.
8258
  function from_string (
8259
    bstring : STRING)                      -- binary string
8260
    return UNRESOLVED_ufixed is
8261
    variable left_index, right_index : INTEGER;
8262
  begin
8263
    calculate_string_boundry (bstring, left_index, right_index);
8264
    return from_string (bstring, left_index, right_index);
8265
  end function from_string;
8266
 
8267
  -- Direct octal and hex conversion functions.  In this case
8268
  -- the string lengths must match.  Example:
8269
  -- signal sf1 := sfixed (5 downto -3);
8270
  -- sf1 <= from_ostring ("71.4") -- -6.5
8271
  function from_ostring (
8272
    ostring : STRING)                      -- Octal string
8273
    return UNRESOLVED_ufixed is
8274
    variable left_index, right_index : INTEGER;
8275
  begin
8276
    calculate_string_boundry (ostring, left_index, right_index);
8277
    return from_ostring (ostring, ((left_index+1)*3)-1, right_index*3);
8278
  end function from_ostring;
8279
 
8280
  function from_hstring (
8281
    hstring : STRING)                      -- hex string
8282
    return UNRESOLVED_ufixed is
8283
    variable left_index, right_index : INTEGER;
8284
  begin
8285
    calculate_string_boundry (hstring, left_index, right_index);
8286
    return from_hstring (hstring, ((left_index+1)*4)-1, right_index*4);
8287
  end function from_hstring;
8288
 
8289
  function from_string (
8290
    bstring : STRING)                      -- binary string
8291
    return UNRESOLVED_sfixed is
8292
    variable left_index, right_index : INTEGER;
8293
  begin
8294
    calculate_string_boundry (bstring, left_index, right_index);
8295
    return from_string (bstring, left_index, right_index);
8296
  end function from_string;
8297
 
8298
  function from_ostring (
8299
    ostring : STRING)                      -- Octal string
8300
    return UNRESOLVED_sfixed is
8301
    variable left_index, right_index : INTEGER;
8302
  begin
8303
    calculate_string_boundry (ostring, left_index, right_index);
8304
    return from_ostring (ostring, ((left_index+1)*3)-1, right_index*3);
8305
  end function from_ostring;
8306
 
8307
  function from_hstring (
8308
    hstring : STRING)                      -- hex string
8309
    return UNRESOLVED_sfixed is
8310
    variable left_index, right_index : INTEGER;
8311
  begin
8312
    calculate_string_boundry (hstring, left_index, right_index);
8313
    return from_hstring (hstring, ((left_index+1)*4)-1, right_index*4);
8314
  end function from_hstring;
8315
-- pragma synthesis_on
8316
-- rtl_synthesis on
8317
  -- IN VHDL-2006 std_logic_vector is a subtype of std_ulogic_vector, so these
8318
  -- extra functions are needed for compatability.
8319
  function to_ufixed (
8320
    arg                  : STD_LOGIC_VECTOR;  -- shifted vector
8321
    constant left_index  : INTEGER;
8322
    constant right_index : INTEGER)
8323
    return UNRESOLVED_ufixed is
8324
  begin
8325
    return to_ufixed (
8326
      arg => std_ulogic_vector (arg),
8327
      left_index => left_index,
8328
      right_index => right_index);
8329
  end function to_ufixed;
8330
 
8331
  function to_ufixed (
8332
    arg      : STD_LOGIC_VECTOR;       -- shifted vector
8333
    size_res : UNRESOLVED_ufixed)       -- for size only
8334
    return UNRESOLVED_ufixed is
8335
  begin
8336
    return to_ufixed (
8337
      arg => std_ulogic_vector (arg),
8338
      size_res => size_res);
8339
  end function to_ufixed;
8340
 
8341
  function to_sfixed (
8342
    arg                  : STD_LOGIC_VECTOR;  -- shifted vector
8343
    constant left_index  : INTEGER;
8344
    constant right_index : INTEGER)
8345
    return UNRESOLVED_sfixed is
8346
  begin
8347
    return to_sfixed (
8348
      arg => std_ulogic_vector (arg),
8349
      left_index => left_index,
8350
      right_index => right_index);
8351
  end function to_sfixed;
8352
 
8353
  function to_sfixed (
8354
    arg      : STD_LOGIC_VECTOR;       -- shifted vector
8355
    size_res : UNRESOLVED_sfixed)       -- for size only
8356
    return UNRESOLVED_sfixed is
8357
  begin
8358
    return to_sfixed (
8359
      arg => std_ulogic_vector (arg),
8360
      size_res => size_res);
8361
  end function to_sfixed;
8362
 
8363
  -- unsigned fixed point
8364
  function to_UFix (
8365
    arg      : STD_LOGIC_VECTOR;
8366
    width    : NATURAL;                 -- width of vector
8367
    fraction : NATURAL)                 -- width of fraction
8368
    return UNRESOLVED_ufixed is
8369
  begin
8370
    return to_UFix (
8371
      arg => std_ulogic_vector (arg),
8372
      width => width,
8373
      fraction => fraction);
8374
  end function to_UFix;
8375
 
8376
  -- signed fixed point
8377
  function to_SFix (
8378
    arg      : STD_LOGIC_VECTOR;
8379
    width    : NATURAL;                 -- width of vector
8380
    fraction : NATURAL)                 -- width of fraction
8381
    return UNRESOLVED_sfixed is
8382
  begin
8383
    return to_SFix (
8384
      arg => std_ulogic_vector (arg),
8385
      width => width,
8386
      fraction => fraction);
8387
  end function to_SFix;
8388
 
8389
end package body fixed_pkg;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.