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