1-- -----------------------------------------------------------------
2--
3-- Copyright 2019 IEEE P1076 WG Authors
4--
5-- See the LICENSE file distributed with this work for copyright and
6-- licensing information and the AUTHORS file.
7--
8-- This file to you under the Apache License, Version 2.0 (the "License").
9-- You may obtain a copy of the License at
10--
11--     http://www.apache.org/licenses/LICENSE-2.0
12--
13-- Unless required by applicable law or agreed to in writing, software
14-- distributed under the License is distributed on an "AS IS" BASIS,
15-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
16-- implied.  See the License for the specific language governing
17-- permissions and limitations under the License.
18--
19--   Title     :  Fixed-point package (Generic package body)
20--             :
21--   Library   :  This package shall be compiled into a library
22--             :  symbolically named IEEE.
23--             :
24--   Developers:  Accellera VHDL-TC and IEEE P1076 Working Group
25--             :
26--   Purpose   :  This packages defines basic binary fixed point arithmetic
27--             :  arithmetic functions
28--             :
29--   Note      :  This package may be modified to include additional data
30--             :  required by tools, but it must in no way change the
31--             :  external interfaces or simulation behavior of the
32--             :  description. It is permissible to add comments and/or
33--             :  attributes to the package declarations, but not to change
34--             :  or delete any original lines of the package declaration.
35--             :  The package body may be changed only in accordance with
36--             :  the terms of Clause 16 of this standard.
37--             :
38-- --------------------------------------------------------------------
39-- $Revision: 1220 $
40-- $Date: 2008-04-10 17:16:09 +0930 (Thu, 10 Apr 2008) $
41-- --------------------------------------------------------------------
42
43library IEEE;
44use IEEE.MATH_REAL.all;
45
46package body fixed_generic_pkg is
47  -- Author David Bishop (dbishop@vhdl.org)
48  -- Other contributers: Jim Lewis, Yannick Grugni, Ryan W. Hilton
49  -- null array constants
50  constant NAUF : UNRESOLVED_ufixed (0 downto 1) := (others => '0');
51  constant NASF : UNRESOLVED_sfixed (0 downto 1) := (others => '0');
52  constant NSLV : STD_ULOGIC_VECTOR (0 downto 1) := (others => '0');
53
54  -- This differed constant will tell you if the package body is synthesizable
55  -- or implemented as real numbers, set to "true" if synthesizable.
56  constant fixedsynth_or_real : BOOLEAN := true;
57
58  -- Special version of "minimum" to do some boundary checking without errors
59  function mins (l, r : INTEGER)
60    return INTEGER is
61  begin  -- function mins
62    if (l = INTEGER'low or r = INTEGER'low) then
63      return 0;                         -- error condition, silent
64    end if;
65    return minimum (l, r);
66  end function mins;
67
68  -- Special version of "minimum" to do some boundary checking with errors
69  function mine (l, r : INTEGER)
70    return INTEGER is
71  begin  -- function mine
72    if (l = INTEGER'low or r = INTEGER'low) then
73      report fixed_generic_pkg'instance_name
74        & " Unbounded number passed, was a literal used?"
75        severity error;
76      return 0;
77    end if;
78    return minimum (l, r);
79  end function mine;
80
81  -- The following functions are used only internally.  Every function
82  -- calls "cleanvec" either directly or indirectly.
83  -- purpose: Fixes "downto" problem and resolves meta states
84  function cleanvec (
85    arg : UNRESOLVED_sfixed)            -- input
86    return UNRESOLVED_sfixed
87  is
88  begin  -- function cleanvec
89    assert not (arg'ascending and (arg'low /= INTEGER'low))
90      report fixed_generic_pkg'instance_name
91      & " Vector passed using a ""to"" range, expected is ""downto"""
92      severity error;
93    return arg;
94  end function cleanvec;
95
96  -- purpose: Fixes "downto" problem and resolves meta states
97  function cleanvec (
98    arg : UNRESOLVED_ufixed)            -- input
99    return UNRESOLVED_ufixed
100  is
101  begin  -- function cleanvec
102    assert not (arg'ascending and (arg'low /= INTEGER'low))
103      report fixed_generic_pkg'instance_name
104      & " Vector passed using a ""to"" range, expected is ""downto"""
105      severity error;
106    return arg;
107  end function cleanvec;
108
109  -- Type convert a "unsigned" into a "ufixed", used internally
110  function to_fixed (
111    arg                  : UNRESOLVED_UNSIGNED;  -- shifted vector
112    constant left_index  : INTEGER;
113    constant right_index : INTEGER)
114    return UNRESOLVED_ufixed
115  is
116    variable result : UNRESOLVED_ufixed (left_index downto right_index);
117  begin  -- function to_fixed
118    result := UNRESOLVED_ufixed(arg);
119    return result;
120  end function to_fixed;
121
122  -- Type convert a "signed" into an "sfixed", used internally
123  function to_fixed (
124    arg                  : UNRESOLVED_SIGNED;  -- shifted vector
125    constant left_index  : INTEGER;
126    constant right_index : INTEGER)
127    return UNRESOLVED_sfixed
128  is
129    variable result : UNRESOLVED_sfixed (left_index downto right_index);
130  begin  -- function to_fixed
131    result := UNRESOLVED_sfixed(arg);
132    return result;
133  end function to_fixed;
134
135  -- Type convert a "ufixed" into an "unsigned", used internally
136  function to_uns (
137    arg : UNRESOLVED_ufixed)            -- fp vector
138    return UNRESOLVED_UNSIGNED
139  is
140    subtype t is UNRESOLVED_UNSIGNED(arg'high - arg'low downto 0);
141    variable slv : t;
142  begin  -- function to_uns
143    slv := t(arg);
144    return slv;
145  end function to_uns;
146
147  -- Type convert an "sfixed" into a "signed", used internally
148  function to_s (
149    arg : UNRESOLVED_sfixed)            -- fp vector
150    return UNRESOLVED_SIGNED
151  is
152    subtype t is UNRESOLVED_SIGNED(arg'high - arg'low downto 0);
153    variable slv : t;
154  begin  -- function to_s
155    slv := t(arg);
156    return slv;
157  end function to_s;
158
159  -- adds 1 to the LSB of the number
160  procedure round_up (arg       : in  UNRESOLVED_ufixed;
161                      result    : out UNRESOLVED_ufixed;
162                      overflowx : out BOOLEAN) is
163    variable arguns, resuns : UNRESOLVED_UNSIGNED (arg'high-arg'low+1 downto 0)
164      := (others => '0');
165  begin  -- round_up
166    arguns (arguns'high-1 downto 0) := to_uns (arg);
167    resuns                          := arguns + 1;
168    result := to_fixed(resuns(arg'high-arg'low
169                              downto 0), arg'high, arg'low);
170    overflowx := (resuns(resuns'high) = '1');
171  end procedure round_up;
172
173  -- adds 1 to the LSB of the number
174  procedure round_up (arg       : in  UNRESOLVED_sfixed;
175                      result    : out UNRESOLVED_sfixed;
176                      overflowx : out BOOLEAN) is
177    variable args, ress : UNRESOLVED_SIGNED (arg'high-arg'low+1 downto 0);
178  begin  -- round_up
179    args (args'high-1 downto 0) := to_s (arg);
180    args(args'high)             := arg(arg'high);  -- sign extend
181    ress                        := args + 1;
182    result := to_fixed(ress (ress'high-1
183                             downto 0), arg'high, arg'low);
184    overflowx := ((arg(arg'high) /= ress(ress'high-1))
185                  and (or (STD_ULOGIC_VECTOR(ress)) /= '0'));
186  end procedure round_up;
187
188  -- Rounding - Performs a "round_nearest" (IEEE 754) which rounds up
189  -- when the remainder is > 0.5.  If the remainder IS 0.5 then if the
190  -- bottom bit is a "1" it is rounded, otherwise it remains the same.
191  function round_fixed (arg            : UNRESOLVED_ufixed;
192                        remainder      : UNRESOLVED_ufixed;
193                        overflow_style : fixed_overflow_style_type := fixed_overflow_style)
194    return UNRESOLVED_ufixed
195  is
196    variable rounds         : BOOLEAN;
197    variable round_overflow : BOOLEAN;
198    variable result         : UNRESOLVED_ufixed (arg'range);
199  begin
200    rounds := false;
201    if (remainder'length > 1) then
202      if (remainder (remainder'high) = '1') then
203        rounds := (arg(arg'low) = '1')
204                  or (or (to_sulv(remainder(remainder'high-1 downto
205                                           remainder'low))) = '1');
206      end if;
207    else
208      rounds := (arg(arg'low) = '1') and (remainder (remainder'high) = '1');
209    end if;
210    if rounds then
211      round_up(arg       => arg,
212               result    => result,
213               overflowx => round_overflow);
214    else
215      result := arg;
216    end if;
217    if (overflow_style = fixed_saturate) and round_overflow then
218      result := saturate (result'high, result'low);
219    end if;
220    return result;
221  end function round_fixed;
222
223  -- Rounding case statement
224  function round_fixed (arg            : UNRESOLVED_sfixed;
225                        remainder      : UNRESOLVED_sfixed;
226                        overflow_style : fixed_overflow_style_type := fixed_overflow_style)
227    return UNRESOLVED_sfixed
228  is
229    variable rounds         : BOOLEAN;
230    variable round_overflow : BOOLEAN;
231    variable result         : UNRESOLVED_sfixed (arg'range);
232  begin
233    rounds := false;
234    if (remainder'length > 1) then
235      if (remainder (remainder'high) = '1') then
236        rounds := (arg(arg'low) = '1')
237                  or (or (to_sulv(remainder(remainder'high-1 downto
238                                           remainder'low))) = '1');
239      end if;
240    else
241      rounds := (arg(arg'low) = '1') and (remainder (remainder'high) = '1');
242    end if;
243    if rounds then
244      round_up(arg       => arg,
245               result    => result,
246               overflowx => round_overflow);
247    else
248      result := arg;
249    end if;
250    if round_overflow then
251      if (overflow_style = fixed_saturate) then
252        if arg(arg'high) = '0' then
253          result := saturate (result'high, result'low);
254        else
255          result := not saturate (result'high, result'low);
256        end if;
257        -- Sign bit not fixed when wrapping
258      end if;
259    end if;
260    return result;
261  end function round_fixed;
262
263  -- converts an sfixed into a ufixed.  The output is the same length as the
264  -- input, because abs("1000") = "1000" = 8.
265  function to_ufixed (
266    arg : UNRESOLVED_sfixed)
267    return UNRESOLVED_ufixed
268  is
269    constant left_index  : INTEGER := arg'high;
270    constant right_index : INTEGER := mine(arg'low, arg'low);
271    variable xarg        : UNRESOLVED_sfixed(left_index+1 downto right_index);
272    variable result      : UNRESOLVED_ufixed(left_index downto right_index);
273  begin
274    if arg'length < 1 then
275      return NAUF;
276    end if;
277    xarg   := abs(arg);
278    result := UNRESOLVED_ufixed (xarg (left_index downto right_index));
279    return result;
280  end function to_ufixed;
281
282-----------------------------------------------------------------------------
283-- Visible functions
284-----------------------------------------------------------------------------
285  -- Conversion functions.  These are needed for synthesis where typically
286  -- the only input and output type is a std_logic_vector.
287  function to_sulv (
288    arg : UNRESOLVED_ufixed)            -- fixed point vector
289    return STD_ULOGIC_VECTOR
290  is
291    variable intermediate_result : UNRESOLVED_ufixed(arg'length-1 downto 0);
292  begin
293    if arg'length < 1 then
294      return NSLV;
295    end if;
296    intermediate_result := arg;
297    return STD_ULOGIC_VECTOR (intermediate_result);
298  end function to_sulv;
299
300  function to_sulv (
301    arg : UNRESOLVED_sfixed)            -- fixed point vector
302    return STD_ULOGIC_VECTOR
303  is
304    variable intermediate_result : UNRESOLVED_sfixed(arg'length-1 downto 0);
305  begin
306    if arg'length < 1 then
307      return NSLV;
308    end if;
309    intermediate_result := arg;
310    return STD_ULOGIC_VECTOR (intermediate_result);
311  end function to_sulv;
312
313  function to_slv (
314    arg : UNRESOLVED_ufixed)            -- fixed point vector
315    return STD_LOGIC_VECTOR is
316  begin
317    return to_sulv(arg);
318  end function to_slv;
319
320  function to_slv (
321    arg : UNRESOLVED_sfixed)            -- fixed point vector
322    return STD_LOGIC_VECTOR is
323  begin
324    return to_sulv(arg);
325  end function to_slv;
326
327  function to_ufixed (
328    arg                  : STD_ULOGIC_VECTOR;  -- shifted vector
329    constant left_index  : INTEGER;
330    constant right_index : INTEGER)
331    return UNRESOLVED_ufixed
332  is
333    variable result : UNRESOLVED_ufixed (left_index downto right_index);
334  begin
335    if (arg'length < 1 or right_index > left_index) then
336      return NAUF;
337    end if;
338    if (arg'length /= result'length) then
339      report fixed_generic_pkg'instance_name & "TO_UFIXED(SLV) "
340        & "Vector lengths do not match.  Input length is "
341        & INTEGER'image(arg'length) & " and output will be "
342        & INTEGER'image(result'length) & " wide."
343        severity error;
344      return NAUF;
345    else
346      result := to_fixed (arg         => UNRESOLVED_UNSIGNED(arg),
347                          left_index  => left_index,
348                          right_index => right_index);
349      return result;
350    end if;
351  end function to_ufixed;
352
353  function to_sfixed (
354    arg                  : STD_ULOGIC_VECTOR;  -- shifted vector
355    constant left_index  : INTEGER;
356    constant right_index : INTEGER)
357    return UNRESOLVED_sfixed
358  is
359    variable result : UNRESOLVED_sfixed (left_index downto right_index);
360  begin
361    if (arg'length < 1 or right_index > left_index) then
362      return NASF;
363    end if;
364    if (arg'length /= result'length) then
365      report fixed_generic_pkg'instance_name & "TO_SFIXED(SLV) "
366        & "Vector lengths do not match.  Input length is "
367        & INTEGER'image(arg'length) & " and output will be "
368        & INTEGER'image(result'length) & " wide."
369        severity error;
370      return NASF;
371    else
372      result := to_fixed (arg         => UNRESOLVED_SIGNED(arg),
373                          left_index  => left_index,
374                          right_index => right_index);
375      return result;
376    end if;
377  end function to_sfixed;
378
379  -- Two's complement number, Grows the vector by 1 bit.
380  -- because "abs (1000.000) = 01000.000" or abs(-16) = 16.
381  function "abs" (
382    arg : UNRESOLVED_sfixed)            -- fixed point input
383    return UNRESOLVED_sfixed
384  is
385    constant left_index  : INTEGER := arg'high;
386    constant right_index : INTEGER := mine(arg'low, arg'low);
387    variable ressns      : UNRESOLVED_SIGNED (arg'length downto 0);
388    variable result      : UNRESOLVED_sfixed (left_index+1 downto right_index);
389  begin
390    if (arg'length < 1 or result'length < 1) then
391      return NASF;
392    end if;
393    ressns (arg'length-1 downto 0) := to_s (cleanvec (arg));
394    ressns (arg'length)            := ressns (arg'length-1);  -- expand sign bit
395    result                         := to_fixed (abs(ressns), left_index+1, right_index);
396    return result;
397  end function "abs";
398
399  -- also grows the vector by 1 bit.
400  function "-" (
401    arg : UNRESOLVED_sfixed)            -- fixed point input
402    return UNRESOLVED_sfixed
403  is
404    constant left_index  : INTEGER := arg'high+1;
405    constant right_index : INTEGER := mine(arg'low, arg'low);
406    variable ressns      : UNRESOLVED_SIGNED (arg'length downto 0);
407    variable result      : UNRESOLVED_sfixed (left_index downto right_index);
408  begin
409    if (arg'length < 1 or result'length < 1) then
410      return NASF;
411    end if;
412    ressns (arg'length-1 downto 0) := to_s (cleanvec(arg));
413    ressns (arg'length)            := ressns (arg'length-1);  -- expand sign bit
414    result                         := to_fixed (-ressns, left_index, right_index);
415    return result;
416  end function "-";
417
418  -- Addition
419  function "+" (
420    l, r : UNRESOLVED_ufixed)    -- ufixed(a downto b) + ufixed(c downto d) =
421    return UNRESOLVED_ufixed     -- ufixed(max(a,c)+1 downto min(b,d))
422  is
423    constant left_index       : INTEGER := maximum(l'high, r'high)+1;
424    constant right_index      : INTEGER := mine(l'low, r'low);
425    variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
426    variable result           : UNRESOLVED_ufixed (left_index downto right_index);
427    variable lslv, rslv : UNRESOLVED_UNSIGNED (left_index-right_index
428                                               downto 0);
429    variable result_slv : UNRESOLVED_UNSIGNED (left_index-right_index
430                                               downto 0);
431  begin
432    if (l'length < 1 or r'length < 1 or result'length < 1) then
433      return NAUF;
434    end if;
435    lresize    := resize (l, left_index, right_index);
436    rresize    := resize (r, left_index, right_index);
437    lslv       := to_uns (lresize);
438    rslv       := to_uns (rresize);
439    result_slv := lslv + rslv;
440    result     := to_fixed(result_slv, left_index, right_index);
441    return result;
442  end function "+";
443
444  function "+" (
445    l, r : UNRESOLVED_sfixed)    -- sfixed(a downto b) + sfixed(c downto d) =
446    return UNRESOLVED_sfixed     -- sfixed(max(a,c)+1 downto min(b,d))
447  is
448    constant left_index       : INTEGER := maximum(l'high, r'high)+1;
449    constant right_index      : INTEGER := mine(l'low, r'low);
450    variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
451    variable result           : UNRESOLVED_sfixed (left_index downto right_index);
452    variable lslv, rslv       : UNRESOLVED_SIGNED (left_index-right_index downto 0);
453    variable result_slv       : UNRESOLVED_SIGNED (left_index-right_index downto 0);
454  begin
455    if (l'length < 1 or r'length < 1 or result'length < 1) then
456      return NASF;
457    end if;
458    lresize    := resize (l, left_index, right_index);
459    rresize    := resize (r, left_index, right_index);
460    lslv       := to_s (lresize);
461    rslv       := to_s (rresize);
462    result_slv := lslv + rslv;
463    result     := to_fixed(result_slv, left_index, right_index);
464    return result;
465  end function "+";
466
467  -- Subtraction
468  function "-" (
469    l, r : UNRESOLVED_ufixed)    -- ufixed(a downto b) - ufixed(c downto d) =
470    return UNRESOLVED_ufixed     -- ufixed(max(a,c)+1 downto min(b,d))
471  is
472    constant left_index       : INTEGER := maximum(l'high, r'high)+1;
473    constant right_index      : INTEGER := mine(l'low, r'low);
474    variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
475    variable result           : UNRESOLVED_ufixed (left_index downto right_index);
476    variable lslv, rslv : UNRESOLVED_UNSIGNED (left_index-right_index
477                                               downto 0);
478    variable result_slv : UNRESOLVED_UNSIGNED (left_index-right_index
479                                               downto 0);
480  begin
481    if (l'length < 1 or r'length < 1 or result'length < 1) then
482      return NAUF;
483    end if;
484    lresize    := resize (l, left_index, right_index);
485    rresize    := resize (r, left_index, right_index);
486    lslv       := to_uns (lresize);
487    rslv       := to_uns (rresize);
488    result_slv := lslv - rslv;
489    result     := to_fixed(result_slv, left_index, right_index);
490    return result;
491  end function "-";
492
493  function "-" (
494    l, r : UNRESOLVED_sfixed)    -- sfixed(a downto b) - sfixed(c downto d) =
495    return UNRESOLVED_sfixed     -- sfixed(max(a,c)+1 downto min(b,d))
496  is
497    constant left_index       : INTEGER := maximum(l'high, r'high)+1;
498    constant right_index      : INTEGER := mine(l'low, r'low);
499    variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
500    variable result           : UNRESOLVED_sfixed (left_index downto right_index);
501    variable lslv, rslv       : UNRESOLVED_SIGNED (left_index-right_index downto 0);
502    variable result_slv       : UNRESOLVED_SIGNED (left_index-right_index downto 0);
503  begin
504    if (l'length < 1 or r'length < 1 or result'length < 1) then
505      return NASF;
506    end if;
507    lresize    := resize (l, left_index, right_index);
508    rresize    := resize (r, left_index, right_index);
509    lslv       := to_s (lresize);
510    rslv       := to_s (rresize);
511    result_slv := lslv - rslv;
512    result     := to_fixed(result_slv, left_index, right_index);
513    return result;
514  end function "-";
515
516  function "*" (
517    l, r : UNRESOLVED_ufixed)    -- ufixed(a downto b) * ufixed(c downto d) =
518    return UNRESOLVED_ufixed     -- ufixed(a+c+1 downto b+d)
519  is
520    variable lslv       : UNRESOLVED_UNSIGNED (l'length-1 downto 0);
521    variable rslv       : UNRESOLVED_UNSIGNED (r'length-1 downto 0);
522    variable result_slv : UNRESOLVED_UNSIGNED (r'length+l'length-1 downto 0);
523    variable result     : UNRESOLVED_ufixed (l'high + r'high+1 downto
524                                             mine(l'low, l'low) + mine(r'low, r'low));
525  begin
526    if (l'length < 1 or r'length < 1 or
527        result'length /= result_slv'length) then
528      return NAUF;
529    end if;
530    lslv       := to_uns (cleanvec(l));
531    rslv       := to_uns (cleanvec(r));
532    result_slv := lslv * rslv;
533    result     := to_fixed (result_slv, result'high, result'low);
534    return result;
535  end function "*";
536
537  function "*" (
538    l, r : UNRESOLVED_sfixed)    -- sfixed(a downto b) * sfixed(c downto d) =
539    return UNRESOLVED_sfixed     -- sfixed(a+c+1 downto b+d)
540  is
541    variable lslv       : UNRESOLVED_SIGNED (l'length-1 downto 0);
542    variable rslv       : UNRESOLVED_SIGNED (r'length-1 downto 0);
543    variable result_slv : UNRESOLVED_SIGNED (r'length+l'length-1 downto 0);
544    variable result     : UNRESOLVED_sfixed (l'high + r'high+1 downto
545                                             mine(l'low, l'low) + mine(r'low, r'low));
546  begin
547    if (l'length < 1 or r'length < 1 or
548        result'length /= result_slv'length) then
549      return NASF;
550    end if;
551    lslv       := to_s (cleanvec(l));
552    rslv       := to_s (cleanvec(r));
553    result_slv := lslv * rslv;
554    result     := to_fixed (result_slv, result'high, result'low);
555    return result;
556  end function "*";
557
558  function "/" (
559    l, r : UNRESOLVED_ufixed)    -- ufixed(a downto b) / ufixed(c downto d) =
560    return UNRESOLVED_ufixed is         --  ufixed(a-d downto b-c-1)
561  begin
562    return divide (l, r);
563  end function "/";
564
565  function "/" (
566    l, r : UNRESOLVED_sfixed)    -- sfixed(a downto b) / sfixed(c downto d) =
567    return UNRESOLVED_sfixed is         -- sfixed(a-d+1 downto b-c)
568  begin
569    return divide (l, r);
570  end function "/";
571
572  -- This version of divide gives the user more control
573  -- ufixed(a downto b) / ufixed(c downto d) = ufixed(a-d downto b-c-1)
574  function divide (
575    l, r                 : UNRESOLVED_ufixed;
576    constant round_style : fixed_round_style_type := fixed_round_style;
577    constant guard_bits  : NATURAL                := fixed_guard_bits)
578    return UNRESOLVED_ufixed
579  is
580    variable result     : UNRESOLVED_ufixed (l'high - mine(r'low, r'low) downto
581                                         mine (l'low, l'low) - r'high -1);
582    variable dresult    : UNRESOLVED_ufixed (result'high downto result'low -guard_bits);
583    variable lresize    : UNRESOLVED_ufixed (l'high downto l'high - dresult'length+1);
584    variable lslv       : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
585    variable rslv       : UNRESOLVED_UNSIGNED (r'length-1 downto 0);
586    variable result_slv : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
587  begin
588    if (l'length < 1 or r'length < 1 or
589        mins(r'low, r'low) /= r'low or mins(l'low, l'low) /= l'low) then
590      return NAUF;
591    end if;
592    lresize := resize (arg            => l,
593                       left_index     => lresize'high,
594                       right_index    => lresize'low,
595                       overflow_style => fixed_wrap,   -- vector only grows
596                       round_style    => fixed_truncate);
597    lslv := to_uns (cleanvec (lresize));
598    rslv := to_uns (cleanvec (r));
599    if (rslv = 0) then
600      report fixed_generic_pkg'instance_name
601        & "DIVIDE(ufixed) Division by zero" severity error;
602      result := saturate (result'high, result'low);    -- saturate
603    else
604      result_slv := lslv / rslv;
605      dresult    := to_fixed (result_slv, dresult'high, dresult'low);
606      result := resize (arg            => dresult,
607                        left_index     => result'high,
608                        right_index    => result'low,
609                        overflow_style => fixed_wrap,  -- overflow impossible
610                        round_style    => round_style);
611    end if;
612    return result;
613  end function divide;
614
615  -- sfixed(a downto b) / sfixed(c downto d) = sfixed(a-d+1 downto b-c)
616  function divide (
617    l, r                 : UNRESOLVED_sfixed;
618    constant round_style : fixed_round_style_type := fixed_round_style;
619    constant guard_bits  : NATURAL                := fixed_guard_bits)
620    return UNRESOLVED_sfixed
621  is
622    variable result     : UNRESOLVED_sfixed (l'high - mine(r'low, r'low) + 1 downto
623                                             mine (l'low, l'low) - r'high);
624    variable dresult    : UNRESOLVED_sfixed (result'high downto result'low-guard_bits);
625    variable lresize    : UNRESOLVED_sfixed (l'high+1 downto l'high+1 -dresult'length+1);
626    variable lslv       : UNRESOLVED_SIGNED (lresize'length-1 downto 0);
627    variable rslv       : UNRESOLVED_SIGNED (r'length-1 downto 0);
628    variable result_slv : UNRESOLVED_SIGNED (lresize'length-1 downto 0);
629  begin
630    if (l'length < 1 or r'length < 1 or
631        mins(r'low, r'low) /= r'low or mins(l'low, l'low) /= l'low) then
632      return NASF;
633    end if;
634    lresize := resize (arg            => l,
635                       left_index     => lresize'high,
636                       right_index    => lresize'low,
637                       overflow_style => fixed_wrap,   -- vector only grows
638                       round_style    => fixed_truncate);
639    lslv := to_s (cleanvec (lresize));
640    rslv := to_s (cleanvec (r));
641    if (rslv = 0) then
642      report fixed_generic_pkg'instance_name
643        & "DIVIDE(sfixed) Division by zero" severity error;
644      result := saturate (result'high, result'low);
645    else
646      result_slv := lslv / rslv;
647      dresult    := to_fixed (result_slv, dresult'high, dresult'low);
648      result := resize (arg            => dresult,
649                        left_index     => result'high,
650                        right_index    => result'low,
651                        overflow_style => fixed_wrap,  -- overflow impossible
652                        round_style    => round_style);
653    end if;
654    return result;
655  end function divide;
656
657  -- 1 / ufixed(a downto b) = ufixed(-b downto -a-1)
658  function reciprocal (
659    arg                  : UNRESOLVED_ufixed;  -- fixed point input
660    constant round_style : fixed_round_style_type := fixed_round_style;
661    constant guard_bits  : NATURAL                := fixed_guard_bits)
662    return UNRESOLVED_ufixed
663  is
664    constant one : UNRESOLVED_ufixed (0 downto 0) := "1";
665  begin
666    return divide (l           => one,
667                   r           => arg,
668                   round_style => round_style,
669                   guard_bits  => guard_bits);
670  end function reciprocal;
671
672  -- 1 / sfixed(a downto b) = sfixed(-b+1 downto -a)
673  function reciprocal (
674    arg                  : UNRESOLVED_sfixed;              -- fixed point input
675    constant round_style : fixed_round_style_type := fixed_round_style;
676    constant guard_bits  : NATURAL                := fixed_guard_bits)
677    return UNRESOLVED_sfixed
678  is
679    constant one     : UNRESOLVED_sfixed (1 downto 0) := "01";  -- extra bit.
680    variable resultx : UNRESOLVED_sfixed (-mine(arg'low, arg'low)+2 downto -arg'high);
681  begin
682    if (arg'length < 1 or resultx'length < 1) then
683      return NASF;
684    else
685      resultx := divide (l           => one,
686                         r           => arg,
687                         round_style => round_style,
688                         guard_bits  => guard_bits);
689      return resultx (resultx'high-1 downto resultx'low);  -- remove extra bit
690    end if;
691  end function reciprocal;
692
693  -- ufixed (a downto b) rem ufixed (c downto d)
694  --        = ufixed (min(a,c) downto min(b,d))
695  function "rem" (
696    l, r : UNRESOLVED_ufixed)           -- fixed point input
697    return UNRESOLVED_ufixed is
698  begin
699    return remainder (l, r);
700  end function "rem";
701
702  -- remainder
703  -- sfixed (a downto b) rem sfixed (c downto d)
704  --        = sfixed (min(a,c) downto min(b,d))
705  function "rem" (
706    l, r : UNRESOLVED_sfixed)           -- fixed point input
707    return UNRESOLVED_sfixed is
708  begin
709    return remainder (l, r);
710  end function "rem";
711
712  -- ufixed (a downto b) rem ufixed (c downto d)
713  --        = ufixed (min(a,c) downto min(b,d))
714  function remainder (
715    l, r                 : UNRESOLVED_ufixed;            -- fixed point input
716    constant round_style : fixed_round_style_type := fixed_round_style;
717    constant guard_bits  : NATURAL                := fixed_guard_bits)
718    return UNRESOLVED_ufixed
719  is
720    variable result     : UNRESOLVED_ufixed (minimum(l'high, r'high) downto
721                                             mine(l'low, r'low));
722    constant rlow : integer := mins(r'low, r'low);
723    variable lresize    : UNRESOLVED_ufixed (maximum(l'high, r'low) downto
724                                             rlow-guard_bits);
725    variable rresize    : UNRESOLVED_ufixed (r'high downto rlow-guard_bits);
726    variable dresult    : UNRESOLVED_ufixed (rresize'range);
727    variable lslv       : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
728    variable rslv       : UNRESOLVED_UNSIGNED (rresize'length-1 downto 0);
729    variable result_slv : UNRESOLVED_UNSIGNED (rslv'range);
730  begin
731    if (l'length < 1 or r'length < 1 or
732        mins(r'low, r'low) /= r'low or mins(l'low, l'low) /= l'low) then
733      return NAUF;
734    end if;
735    lresize := resize (arg            => l,
736                       left_index     => lresize'high,
737                       right_index    => lresize'low,
738                       overflow_style => fixed_wrap,     -- vector only grows
739                       round_style    => fixed_truncate);
740    lslv := to_uns (lresize);
741    rresize := resize (arg            => r,
742                       left_index     => rresize'high,
743                       right_index    => rresize'low,
744                       overflow_style => fixed_wrap,     -- vector only grows
745                       round_style    => fixed_truncate);
746    rslv := to_uns (rresize);
747    if (rslv = 0) then
748      report fixed_generic_pkg'instance_name
749        & "remainder(ufixed) Division by zero" severity error;
750      result := saturate (result'high, result'low);      -- saturate
751    else
752      if (r'low <= l'high) then
753        result_slv := lslv rem rslv;
754        dresult    := to_fixed (result_slv, dresult'high, dresult'low);
755        result := resize (arg            => dresult,
756                          left_index     => result'high,
757                          right_index    => result'low,
758                          overflow_style => fixed_wrap,  -- can't overflow
759                          round_style    => round_style);
760      end if;
761      if l'low < r'low then
762        result(mins(r'low-1, l'high) downto l'low) :=
763          cleanvec(l(mins(r'low-1, l'high) downto l'low));
764      end if;
765    end if;
766    return result;
767  end function remainder;
768
769  -- remainder
770  -- sfixed (a downto b) rem sfixed (c downto d)
771  --        = sfixed (min(a,c) downto min(b,d))
772  function remainder (
773    l, r                 : UNRESOLVED_sfixed;  -- fixed point input
774    constant round_style : fixed_round_style_type := fixed_round_style;
775    constant guard_bits  : NATURAL                := fixed_guard_bits)
776    return UNRESOLVED_sfixed
777  is
778    variable l_abs      : UNRESOLVED_ufixed (l'range);
779    variable r_abs      : UNRESOLVED_ufixed (r'range);
780    variable result     : UNRESOLVED_sfixed (minimum(r'high, l'high) downto
781                                             mine(r'low, l'low));
782    variable neg_result : UNRESOLVED_sfixed (minimum(r'high, l'high)+1 downto
783                                             mins(r'low, l'low));
784  begin
785    if (l'length < 1 or r'length < 1 or
786        mins(r'low, r'low) /= r'low or mins(l'low, l'low) /= l'low) then
787      return NASF;
788    end if;
789    l_abs := to_ufixed (l);
790    r_abs := to_ufixed (r);
791    result := UNRESOLVED_sfixed (remainder (
792      l           => l_abs,
793      r           => r_abs,
794      round_style => round_style));
795    neg_result := -result;
796    if l(l'high) = '1' then
797      result := neg_result(result'range);
798    end if;
799    return result;
800  end function remainder;
801
802  -- modulo
803  -- ufixed (a downto b) mod ufixed (c downto d)
804  --        = ufixed (min(a,c) downto min(b, d))
805  function "mod" (
806    l, r : UNRESOLVED_ufixed)           -- fixed point input
807    return UNRESOLVED_ufixed is
808  begin
809    return modulo (l, r);
810  end function "mod";
811
812  -- sfixed (a downto b) mod sfixed (c downto d)
813  --        = sfixed (c downto min(b, d))
814  function "mod" (
815    l, r : UNRESOLVED_sfixed)           -- fixed point input
816    return UNRESOLVED_sfixed is
817  begin
818    return modulo(l, r);
819  end function "mod";
820
821  -- modulo
822  -- ufixed (a downto b) mod ufixed (c downto d)
823  --        = ufixed (min(a,c) downto min(b, d))
824  function modulo (
825    l, r                 : UNRESOLVED_ufixed;  -- fixed point input
826    constant round_style : fixed_round_style_type := fixed_round_style;
827    constant guard_bits  : NATURAL                := fixed_guard_bits)
828    return UNRESOLVED_ufixed is
829  begin
830    return remainder(l           => l,
831                     r           => r,
832                     round_style => round_style,
833                     guard_bits  => guard_bits);
834  end function modulo;
835
836  -- sfixed (a downto b) mod sfixed (c downto d)
837  --        = sfixed (c downto min(b, d))
838  function modulo (
839    l, r                    : UNRESOLVED_sfixed;  -- fixed point input
840    constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
841    constant round_style    : fixed_round_style_type    := fixed_round_style;
842    constant guard_bits     : NATURAL                   := fixed_guard_bits)
843    return UNRESOLVED_sfixed
844  is
845    variable l_abs : UNRESOLVED_ufixed (l'range);
846    variable r_abs : UNRESOLVED_ufixed (r'range);
847    variable result : UNRESOLVED_sfixed (r'high downto
848                                         mine(r'low, l'low));
849    variable dresult : UNRESOLVED_sfixed (minimum(r'high, l'high)+1 downto
850                                          mins(r'low, l'low));
851    variable dresult_not_zero : BOOLEAN;
852  begin
853    if (l'length < 1 or r'length < 1 or
854        mins(r'low, r'low) /= r'low or mins(l'low, l'low) /= l'low) then
855      return NASF;
856    end if;
857    l_abs := to_ufixed (l);
858    r_abs := to_ufixed (r);
859    dresult := "0" & UNRESOLVED_sfixed(remainder (l           => l_abs,
860                                                  r           => r_abs,
861                                                  round_style => round_style));
862    if (to_s(dresult) = 0) then
863      dresult_not_zero := false;
864    else
865      dresult_not_zero := true;
866    end if;
867    if to_x01(l(l'high)) = '1' and to_x01(r(r'high)) = '0'
868      and dresult_not_zero then
869      result := resize (arg            => r - dresult,
870                        left_index     => result'high,
871                        right_index    => result'low,
872                        overflow_style => overflow_style,
873                        round_style    => round_style);
874    elsif to_x01(l(l'high)) = '1' and to_x01(r(r'high)) = '1' then
875      result := resize (arg            => -dresult,
876                        left_index     => result'high,
877                        right_index    => result'low,
878                        overflow_style => overflow_style,
879                        round_style    => round_style);
880    elsif to_x01(l(l'high)) = '0' and to_x01(r(r'high)) = '1'
881      and dresult_not_zero then
882      result := resize (arg            => dresult + r,
883                        left_index     => result'high,
884                        right_index    => result'low,
885                        overflow_style => overflow_style,
886                        round_style    => round_style);
887    else
888      result := resize (arg            => dresult,
889                        left_index     => result'high,
890                        right_index    => result'low,
891                        overflow_style => overflow_style,
892                        round_style    => round_style);
893    end if;
894    return result;
895  end function modulo;
896
897  -- Procedure for those who need an "accumulator" function
898  procedure add_carry (
899    L, R   : in  UNRESOLVED_ufixed;
900    c_in   : in  STD_ULOGIC;
901    result : out UNRESOLVED_ufixed;
902    c_out  : out STD_ULOGIC) is
903    constant left_index       : INTEGER := maximum(L'high, R'high)+1;
904    constant right_index      : INTEGER := mins(L'low, R'low);
905    variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
906    variable lslv, rslv : UNRESOLVED_UNSIGNED (left_index-right_index
907                                               downto 0);
908    variable result_slv : UNRESOLVED_UNSIGNED (left_index-right_index
909                                               downto 0);
910    variable cx : UNRESOLVED_UNSIGNED (0 downto 0);  -- Carry in
911  begin
912    if (L'length < 1 or R'length < 1) then
913      result := NAUF;
914      c_out  := '0';
915    else
916      cx (0)     := c_in;
917      lresize    := resize (L, left_index, right_index);
918      rresize    := resize (R, left_index, right_index);
919      lslv       := to_uns (lresize);
920      rslv       := to_uns (rresize);
921      result_slv := lslv + rslv + cx;
922      c_out      := result_slv(left_index);
923      result := to_fixed(result_slv (left_index-right_index-1 downto 0),
924                         left_index-1, right_index);
925    end if;
926  end procedure add_carry;
927
928  procedure add_carry (
929    L, R   : in  UNRESOLVED_sfixed;
930    c_in   : in  STD_ULOGIC;
931    result : out UNRESOLVED_sfixed;
932    c_out  : out STD_ULOGIC) is
933    constant left_index       : INTEGER := maximum(L'high, R'high)+1;
934    constant right_index      : INTEGER := mins(L'low, R'low);
935    variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
936    variable lslv, rslv : UNRESOLVED_SIGNED (left_index-right_index
937                                             downto 0);
938    variable result_slv : UNRESOLVED_SIGNED (left_index-right_index
939                                             downto 0);
940    variable cx : UNRESOLVED_SIGNED (1 downto 0);  -- Carry in
941  begin
942    if (L'length < 1 or R'length < 1) then
943      result := NASF;
944      c_out  := '0';
945    else
946      cx (1)     := '0';
947      cx (0)     := c_in;
948      lresize    := resize (L, left_index, right_index);
949      rresize    := resize (R, left_index, right_index);
950      lslv       := to_s (lresize);
951      rslv       := to_s (rresize);
952      result_slv := lslv + rslv + cx;
953      c_out      := result_slv(left_index);
954      result := to_fixed(result_slv (left_index-right_index-1 downto 0),
955                         left_index-1, right_index);
956    end if;
957  end procedure add_carry;
958
959  -- Scales the result by a power of 2.  Width of input = width of output with
960  -- the decimal point moved.
961  function scalb (y : UNRESOLVED_ufixed; N : INTEGER)
962    return UNRESOLVED_ufixed
963  is
964    variable result : UNRESOLVED_ufixed (y'high+N downto y'low+N);
965  begin
966    if y'length < 1 then
967      return NAUF;
968    else
969      result := y;
970      return result;
971    end if;
972  end function scalb;
973
974  function scalb (y : UNRESOLVED_ufixed; N : UNRESOLVED_SIGNED)
975    return UNRESOLVED_ufixed is
976  begin
977    return scalb (y => y,
978                  N => to_integer(N));
979  end function scalb;
980
981  function scalb (y : UNRESOLVED_sfixed; N : INTEGER)
982    return UNRESOLVED_sfixed
983  is
984    variable result : UNRESOLVED_sfixed (y'high+N downto y'low+N);
985  begin
986    if y'length < 1 then
987      return NASF;
988    else
989      result := y;
990      return result;
991    end if;
992  end function scalb;
993
994  function scalb (y : UNRESOLVED_sfixed; N : UNRESOLVED_SIGNED)
995    return UNRESOLVED_sfixed is
996  begin
997    return scalb (y => y,
998                  N => to_integer(N));
999  end function scalb;
1000
1001  function Is_Negative (arg : UNRESOLVED_sfixed) return BOOLEAN is
1002  begin
1003    if to_X01(arg(arg'high)) = '1' then
1004      return true;
1005    else
1006      return false;
1007    end if;
1008  end function Is_Negative;
1009
1010  function find_rightmost (arg : UNRESOLVED_ufixed; y : STD_ULOGIC)
1011    return INTEGER is
1012  begin
1013    for_loop : for i in arg'reverse_range loop
1014      if arg(i) ?= y then
1015        return i;
1016      end if;
1017    end loop;
1018    return arg'high+1;                  -- return out of bounds 'high
1019  end function find_rightmost;
1020
1021  function find_leftmost (arg : UNRESOLVED_ufixed; y : STD_ULOGIC)
1022    return INTEGER is
1023  begin
1024    for_loop : for i in arg'range loop
1025      if arg(i) ?= y then
1026        return i;
1027      end if;
1028    end loop;
1029    return arg'low-1;                   -- return out of bounds 'low
1030  end function find_leftmost;
1031
1032  function find_rightmost (arg : UNRESOLVED_sfixed; y : STD_ULOGIC)
1033    return INTEGER is
1034  begin
1035    for_loop : for i in arg'reverse_range loop
1036      if arg(i) ?= y then
1037        return i;
1038      end if;
1039    end loop;
1040    return arg'high+1;                  -- return out of bounds 'high
1041  end function find_rightmost;
1042
1043  function find_leftmost (arg : UNRESOLVED_sfixed; y : STD_ULOGIC)
1044    return INTEGER is
1045  begin
1046    for_loop : for i in arg'range loop
1047      if arg(i) ?= y then
1048        return i;
1049      end if;
1050    end loop;
1051    return arg'low-1;                   -- return out of bounds 'low
1052  end function find_leftmost;
1053
1054  function "sll" (ARG : UNRESOLVED_ufixed; COUNT : INTEGER)
1055    return UNRESOLVED_ufixed
1056  is
1057    variable argslv : UNRESOLVED_UNSIGNED (ARG'length-1 downto 0);
1058    variable result : UNRESOLVED_ufixed (ARG'range);
1059  begin
1060    argslv := to_uns (ARG);
1061    argslv := argslv sll COUNT;
1062    result := to_fixed (argslv, result'high, result'low);
1063    return result;
1064  end function "sll";
1065
1066  function "srl" (ARG : UNRESOLVED_ufixed; COUNT : INTEGER)
1067    return UNRESOLVED_ufixed
1068  is
1069    variable argslv : UNRESOLVED_UNSIGNED (ARG'length-1 downto 0);
1070    variable result : UNRESOLVED_ufixed (ARG'range);
1071  begin
1072    argslv := to_uns (ARG);
1073    argslv := argslv srl COUNT;
1074    result := to_fixed (argslv, result'high, result'low);
1075    return result;
1076  end function "srl";
1077
1078  function "rol" (ARG : UNRESOLVED_ufixed; COUNT : INTEGER)
1079    return UNRESOLVED_ufixed
1080  is
1081    variable argslv : UNRESOLVED_UNSIGNED (ARG'length-1 downto 0);
1082    variable result : UNRESOLVED_ufixed (ARG'range);
1083  begin
1084    argslv := to_uns (ARG);
1085    argslv := argslv rol COUNT;
1086    result := to_fixed (argslv, result'high, result'low);
1087    return result;
1088  end function "rol";
1089
1090  function "ror" (ARG : UNRESOLVED_ufixed; COUNT : INTEGER)
1091    return UNRESOLVED_ufixed
1092  is
1093    variable argslv : UNRESOLVED_UNSIGNED (ARG'length-1 downto 0);
1094    variable result : UNRESOLVED_ufixed (ARG'range);
1095  begin
1096    argslv := to_uns (ARG);
1097    argslv := argslv ror COUNT;
1098    result := to_fixed (argslv, result'high, result'low);
1099    return result;
1100  end function "ror";
1101
1102  function "sla" (ARG : UNRESOLVED_ufixed; COUNT : INTEGER)
1103    return UNRESOLVED_ufixed
1104  is
1105    variable argslv : UNRESOLVED_UNSIGNED (ARG'length-1 downto 0);
1106    variable result : UNRESOLVED_ufixed (ARG'range);
1107  begin
1108    argslv := to_uns (ARG);
1109    -- Arithmetic shift on an unsigned is a logical shift
1110    argslv := argslv sll COUNT;
1111    result := to_fixed (argslv, result'high, result'low);
1112    return result;
1113  end function "sla";
1114
1115  function "sra" (ARG : UNRESOLVED_ufixed; COUNT : INTEGER)
1116    return UNRESOLVED_ufixed
1117  is
1118    variable argslv : UNRESOLVED_UNSIGNED (ARG'length-1 downto 0);
1119    variable result : UNRESOLVED_ufixed (ARG'range);
1120  begin
1121    argslv := to_uns (ARG);
1122    -- Arithmetic shift on an unsigned is a logical shift
1123    argslv := argslv srl COUNT;
1124    result := to_fixed (argslv, result'high, result'low);
1125    return result;
1126  end function "sra";
1127
1128  function "sll" (ARG : UNRESOLVED_sfixed; COUNT : INTEGER)
1129    return UNRESOLVED_sfixed
1130  is
1131    variable argslv : UNRESOLVED_SIGNED (ARG'length-1 downto 0);
1132    variable result : UNRESOLVED_sfixed (ARG'range);
1133  begin
1134    argslv := to_s (ARG);
1135    argslv := argslv sll COUNT;
1136    result := to_fixed (argslv, result'high, result'low);
1137    return result;
1138  end function "sll";
1139
1140  function "srl" (ARG : UNRESOLVED_sfixed; COUNT : INTEGER)
1141    return UNRESOLVED_sfixed
1142  is
1143    variable argslv : UNRESOLVED_SIGNED (ARG'length-1 downto 0);
1144    variable result : UNRESOLVED_sfixed (ARG'range);
1145  begin
1146    argslv := to_s (ARG);
1147    argslv := argslv srl COUNT;
1148    result := to_fixed (argslv, result'high, result'low);
1149    return result;
1150  end function "srl";
1151
1152  function "rol" (ARG : UNRESOLVED_sfixed; COUNT : INTEGER)
1153    return UNRESOLVED_sfixed
1154  is
1155    variable argslv : UNRESOLVED_SIGNED (ARG'length-1 downto 0);
1156    variable result : UNRESOLVED_sfixed (ARG'range);
1157  begin
1158    argslv := to_s (ARG);
1159    argslv := argslv rol COUNT;
1160    result := to_fixed (argslv, result'high, result'low);
1161    return result;
1162  end function "rol";
1163
1164  function "ror" (ARG : UNRESOLVED_sfixed; COUNT : INTEGER)
1165    return UNRESOLVED_sfixed
1166  is
1167    variable argslv : UNRESOLVED_SIGNED (ARG'length-1 downto 0);
1168    variable result : UNRESOLVED_sfixed (ARG'range);
1169  begin
1170    argslv := to_s (ARG);
1171    argslv := argslv ror COUNT;
1172    result := to_fixed (argslv, result'high, result'low);
1173    return result;
1174  end function "ror";
1175
1176  function "sla" (ARG : UNRESOLVED_sfixed; COUNT : INTEGER)
1177    return UNRESOLVED_sfixed
1178  is
1179    variable argslv : UNRESOLVED_SIGNED (ARG'length-1 downto 0);
1180    variable result : UNRESOLVED_sfixed (ARG'range);
1181  begin
1182    argslv := to_s (ARG);
1183    if COUNT > 0 then
1184      -- Arithmetic shift left on a 2's complement number is a logic shift
1185      argslv := argslv sll COUNT;
1186    else
1187      argslv := argslv sra -COUNT;
1188    end if;
1189    result := to_fixed (argslv, result'high, result'low);
1190    return result;
1191  end function "sla";
1192
1193  function "sra" (ARG : UNRESOLVED_sfixed; COUNT : INTEGER)
1194    return UNRESOLVED_sfixed
1195  is
1196    variable argslv : UNRESOLVED_SIGNED (ARG'length-1 downto 0);
1197    variable result : UNRESOLVED_sfixed (ARG'range);
1198  begin
1199    argslv := to_s (ARG);
1200    if COUNT > 0 then
1201      argslv := argslv sra COUNT;
1202    else
1203      -- Arithmetic shift left on a 2's complement number is a logic shift
1204      argslv := argslv sll -COUNT;
1205    end if;
1206    result := to_fixed (argslv, result'high, result'low);
1207    return result;
1208  end function "sra";
1209
1210  -- Because some people want the older functions.
1211  function SHIFT_LEFT (ARG : UNRESOLVED_ufixed; COUNT : NATURAL)
1212    return UNRESOLVED_ufixed is
1213  begin
1214    if (ARG'length < 1) then
1215      return NAUF;
1216    end if;
1217    return ARG sla COUNT;
1218  end function SHIFT_LEFT;
1219
1220  function SHIFT_RIGHT (ARG : UNRESOLVED_ufixed; COUNT : NATURAL)
1221    return UNRESOLVED_ufixed is
1222  begin
1223    if (ARG'length < 1) then
1224      return NAUF;
1225    end if;
1226    return ARG sra COUNT;
1227  end function SHIFT_RIGHT;
1228
1229  function SHIFT_LEFT (ARG : UNRESOLVED_sfixed; COUNT : NATURAL)
1230    return UNRESOLVED_sfixed is
1231  begin
1232    if (ARG'length < 1) then
1233      return NASF;
1234    end if;
1235    return ARG sla COUNT;
1236  end function SHIFT_LEFT;
1237
1238  function SHIFT_RIGHT (ARG : UNRESOLVED_sfixed; COUNT : NATURAL)
1239    return UNRESOLVED_sfixed is
1240  begin
1241    if (ARG'length < 1) then
1242      return NASF;
1243    end if;
1244    return ARG sra COUNT;
1245  end function SHIFT_RIGHT;
1246
1247  ----------------------------------------------------------------------------
1248  -- logical functions
1249  ----------------------------------------------------------------------------
1250  function "not" (L : UNRESOLVED_ufixed) return UNRESOLVED_ufixed is
1251    variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0);  -- force downto
1252  begin
1253    RESULT := not to_sulv(L);
1254    return to_ufixed(RESULT, L'high, L'low);
1255  end function "not";
1256
1257  function "and" (L, R : UNRESOLVED_ufixed) return UNRESOLVED_ufixed is
1258    variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0);  -- force downto
1259  begin
1260    if (L'high = R'high and L'low = R'low) then
1261      RESULT := to_sulv(L) and to_sulv(R);
1262    else
1263      assert no_warning
1264        report fixed_generic_pkg'instance_name
1265        & """and"": Range error L'RANGE /= R'RANGE"
1266        severity warning;
1267      RESULT := (others => 'X');
1268    end if;
1269    return to_ufixed(RESULT, L'high, L'low);
1270  end function "and";
1271
1272  function "or" (L, R : UNRESOLVED_ufixed) return UNRESOLVED_ufixed is
1273    variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0);  -- force downto
1274  begin
1275    if (L'high = R'high and L'low = R'low) then
1276      RESULT := to_sulv(L) or to_sulv(R);
1277    else
1278      assert no_warning
1279        report fixed_generic_pkg'instance_name
1280        & """or"": Range error L'RANGE /= R'RANGE"
1281        severity warning;
1282      RESULT := (others => 'X');
1283    end if;
1284    return to_ufixed(RESULT, L'high, L'low);
1285  end function "or";
1286
1287  function "nand" (L, R : UNRESOLVED_ufixed) return UNRESOLVED_ufixed is
1288    variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0);  -- force downto
1289  begin
1290    if (L'high = R'high and L'low = R'low) then
1291      RESULT := to_sulv(L) nand to_sulv(R);
1292    else
1293      assert no_warning
1294        report fixed_generic_pkg'instance_name
1295        & """nand"": Range error L'RANGE /= R'RANGE"
1296        severity warning;
1297      RESULT := (others => 'X');
1298    end if;
1299    return to_ufixed(RESULT, L'high, L'low);
1300  end function "nand";
1301
1302  function "nor" (L, R : UNRESOLVED_ufixed) return UNRESOLVED_ufixed is
1303    variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0);  -- force downto
1304  begin
1305    if (L'high = R'high and L'low = R'low) then
1306      RESULT := to_sulv(L) nor to_sulv(R);
1307    else
1308      assert no_warning
1309        report fixed_generic_pkg'instance_name
1310        & """nor"": Range error L'RANGE /= R'RANGE"
1311        severity warning;
1312      RESULT := (others => 'X');
1313    end if;
1314    return to_ufixed(RESULT, L'high, L'low);
1315  end function "nor";
1316
1317  function "xor" (L, R : UNRESOLVED_ufixed) return UNRESOLVED_ufixed is
1318    variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0);  -- force downto
1319  begin
1320    if (L'high = R'high and L'low = R'low) then
1321      RESULT := to_sulv(L) xor to_sulv(R);
1322    else
1323      assert no_warning
1324        report fixed_generic_pkg'instance_name
1325        & """xor"": Range error L'RANGE /= R'RANGE"
1326        severity warning;
1327      RESULT := (others => 'X');
1328    end if;
1329    return to_ufixed(RESULT, L'high, L'low);
1330  end function "xor";
1331
1332  function "xnor" (L, R : UNRESOLVED_ufixed) return UNRESOLVED_ufixed is
1333    variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0);  -- force downto
1334  begin
1335    if (L'high = R'high and L'low = R'low) then
1336      RESULT := to_sulv(L) xnor to_sulv(R);
1337    else
1338      assert no_warning
1339        report fixed_generic_pkg'instance_name
1340        & """xnor"": Range error L'RANGE /= R'RANGE"
1341        severity warning;
1342      RESULT := (others => 'X');
1343    end if;
1344    return to_ufixed(RESULT, L'high, L'low);
1345  end function "xnor";
1346
1347  function "not" (L : UNRESOLVED_sfixed) return UNRESOLVED_sfixed is
1348    variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0);  -- force downto
1349  begin
1350    RESULT := not to_sulv(L);
1351    return to_sfixed(RESULT, L'high, L'low);
1352  end function "not";
1353
1354  function "and" (L, R : UNRESOLVED_sfixed) return UNRESOLVED_sfixed is
1355    variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0);  -- force downto
1356  begin
1357    if (L'high = R'high and L'low = R'low) then
1358      RESULT := to_sulv(L) and to_sulv(R);
1359    else
1360      assert no_warning
1361        report fixed_generic_pkg'instance_name
1362        & """and"": Range error L'RANGE /= R'RANGE"
1363        severity warning;
1364      RESULT := (others => 'X');
1365    end if;
1366    return to_sfixed(RESULT, L'high, L'low);
1367  end function "and";
1368
1369  function "or" (L, R : UNRESOLVED_sfixed) return UNRESOLVED_sfixed is
1370    variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0);  -- force downto
1371  begin
1372    if (L'high = R'high and L'low = R'low) then
1373      RESULT := to_sulv(L) or to_sulv(R);
1374    else
1375      assert no_warning
1376        report fixed_generic_pkg'instance_name
1377        & """or"": Range error L'RANGE /= R'RANGE"
1378        severity warning;
1379      RESULT := (others => 'X');
1380    end if;
1381    return to_sfixed(RESULT, L'high, L'low);
1382  end function "or";
1383
1384  function "nand" (L, R : UNRESOLVED_sfixed) return UNRESOLVED_sfixed is
1385    variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0);  -- force downto
1386  begin
1387    if (L'high = R'high and L'low = R'low) then
1388      RESULT := to_sulv(L) nand to_sulv(R);
1389    else
1390      assert no_warning
1391        report fixed_generic_pkg'instance_name
1392        & """nand"": Range error L'RANGE /= R'RANGE"
1393        severity warning;
1394      RESULT := (others => 'X');
1395    end if;
1396    return to_sfixed(RESULT, L'high, L'low);
1397  end function "nand";
1398
1399  function "nor" (L, R : UNRESOLVED_sfixed) return UNRESOLVED_sfixed is
1400    variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0);  -- force downto
1401  begin
1402    if (L'high = R'high and L'low = R'low) then
1403      RESULT := to_sulv(L) nor to_sulv(R);
1404    else
1405      assert no_warning
1406        report fixed_generic_pkg'instance_name
1407        & """nor"": Range error L'RANGE /= R'RANGE"
1408        severity warning;
1409      RESULT := (others => 'X');
1410    end if;
1411    return to_sfixed(RESULT, L'high, L'low);
1412  end function "nor";
1413
1414  function "xor" (L, R : UNRESOLVED_sfixed) return UNRESOLVED_sfixed is
1415    variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0);  -- force downto
1416  begin
1417    if (L'high = R'high and L'low = R'low) then
1418      RESULT := to_sulv(L) xor to_sulv(R);
1419    else
1420      assert no_warning
1421        report fixed_generic_pkg'instance_name
1422        & """xor"": Range error L'RANGE /= R'RANGE"
1423        severity warning;
1424      RESULT := (others => 'X');
1425    end if;
1426    return to_sfixed(RESULT, L'high, L'low);
1427  end function "xor";
1428
1429  function "xnor" (L, R : UNRESOLVED_sfixed) return UNRESOLVED_sfixed is
1430    variable RESULT : STD_ULOGIC_VECTOR(L'length-1 downto 0);  -- force downto
1431  begin
1432    if (L'high = R'high and L'low = R'low) then
1433      RESULT := to_sulv(L) xnor to_sulv(R);
1434    else
1435      assert no_warning
1436        report fixed_generic_pkg'instance_name
1437        & """xnor"": Range error L'RANGE /= R'RANGE"
1438        severity warning;
1439      RESULT := (others => 'X');
1440    end if;
1441    return to_sfixed(RESULT, L'high, L'low);
1442  end function "xnor";
1443
1444  -- Vector and std_ulogic functions, same as functions in numeric_std
1445  function "and" (L : STD_ULOGIC; R : UNRESOLVED_ufixed)
1446    return UNRESOLVED_ufixed
1447  is
1448    variable result : UNRESOLVED_ufixed (R'range);
1449  begin
1450    for i in result'range loop
1451      result(i) := L and R(i);
1452    end loop;
1453    return result;
1454  end function "and";
1455
1456  function "and" (L : UNRESOLVED_ufixed; R : STD_ULOGIC)
1457    return UNRESOLVED_ufixed
1458  is
1459    variable result : UNRESOLVED_ufixed (L'range);
1460  begin
1461    for i in result'range loop
1462      result(i) := L(i) and R;
1463    end loop;
1464    return result;
1465  end function "and";
1466
1467  function "or" (L : STD_ULOGIC; R : UNRESOLVED_ufixed)
1468    return UNRESOLVED_ufixed
1469  is
1470    variable result : UNRESOLVED_ufixed (R'range);
1471  begin
1472    for i in result'range loop
1473      result(i) := L or R(i);
1474    end loop;
1475    return result;
1476  end function "or";
1477
1478  function "or" (L : UNRESOLVED_ufixed; R : STD_ULOGIC)
1479    return UNRESOLVED_ufixed
1480  is
1481    variable result : UNRESOLVED_ufixed (L'range);
1482  begin
1483    for i in result'range loop
1484      result(i) := L(i) or R;
1485    end loop;
1486    return result;
1487  end function "or";
1488
1489  function "nand" (L : STD_ULOGIC; R : UNRESOLVED_ufixed)
1490    return UNRESOLVED_ufixed
1491  is
1492    variable result : UNRESOLVED_ufixed (R'range);
1493  begin
1494    for i in result'range loop
1495      result(i) := L nand R(i);
1496    end loop;
1497    return result;
1498  end function "nand";
1499
1500  function "nand" (L : UNRESOLVED_ufixed; R : STD_ULOGIC)
1501    return UNRESOLVED_ufixed
1502  is
1503    variable result : UNRESOLVED_ufixed (L'range);
1504  begin
1505    for i in result'range loop
1506      result(i) := L(i) nand R;
1507    end loop;
1508    return result;
1509  end function "nand";
1510
1511  function "nor" (L : STD_ULOGIC; R : UNRESOLVED_ufixed)
1512    return UNRESOLVED_ufixed
1513  is
1514    variable result : UNRESOLVED_ufixed (R'range);
1515  begin
1516    for i in result'range loop
1517      result(i) := L nor R(i);
1518    end loop;
1519    return result;
1520  end function "nor";
1521
1522  function "nor" (L : UNRESOLVED_ufixed; R : STD_ULOGIC)
1523    return UNRESOLVED_ufixed
1524  is
1525    variable result : UNRESOLVED_ufixed (L'range);
1526  begin
1527    for i in result'range loop
1528      result(i) := L(i) nor R;
1529    end loop;
1530    return result;
1531  end function "nor";
1532
1533  function "xor" (L : STD_ULOGIC; R : UNRESOLVED_ufixed)
1534    return UNRESOLVED_ufixed
1535  is
1536    variable result : UNRESOLVED_ufixed (R'range);
1537  begin
1538    for i in result'range loop
1539      result(i) := L xor R(i);
1540    end loop;
1541    return result;
1542  end function "xor";
1543
1544  function "xor" (L : UNRESOLVED_ufixed; R : STD_ULOGIC)
1545    return UNRESOLVED_ufixed
1546  is
1547    variable result : UNRESOLVED_ufixed (L'range);
1548  begin
1549    for i in result'range loop
1550      result(i) := L(i) xor R;
1551    end loop;
1552    return result;
1553  end function "xor";
1554
1555  function "xnor" (L : STD_ULOGIC; R : UNRESOLVED_ufixed)
1556    return UNRESOLVED_ufixed
1557  is
1558    variable result : UNRESOLVED_ufixed (R'range);
1559  begin
1560    for i in result'range loop
1561      result(i) := L xnor R(i);
1562    end loop;
1563    return result;
1564  end function "xnor";
1565
1566  function "xnor" (L : UNRESOLVED_ufixed; R : STD_ULOGIC)
1567    return UNRESOLVED_ufixed
1568  is
1569    variable result : UNRESOLVED_ufixed (L'range);
1570  begin
1571    for i in result'range loop
1572      result(i) := L(i) xnor R;
1573    end loop;
1574    return result;
1575  end function "xnor";
1576
1577  function "and" (L : STD_ULOGIC; R : UNRESOLVED_sfixed)
1578    return UNRESOLVED_sfixed
1579  is
1580    variable result : UNRESOLVED_sfixed (R'range);
1581  begin
1582    for i in result'range loop
1583      result(i) := L and R(i);
1584    end loop;
1585    return result;
1586  end function "and";
1587
1588  function "and" (L : UNRESOLVED_sfixed; R : STD_ULOGIC)
1589    return UNRESOLVED_sfixed
1590  is
1591    variable result : UNRESOLVED_sfixed (L'range);
1592  begin
1593    for i in result'range loop
1594      result(i) := L(i) and R;
1595    end loop;
1596    return result;
1597  end function "and";
1598
1599  function "or" (L : STD_ULOGIC; R : UNRESOLVED_sfixed)
1600    return UNRESOLVED_sfixed
1601  is
1602    variable result : UNRESOLVED_sfixed (R'range);
1603  begin
1604    for i in result'range loop
1605      result(i) := L or R(i);
1606    end loop;
1607    return result;
1608  end function "or";
1609
1610  function "or" (L : UNRESOLVED_sfixed; R : STD_ULOGIC)
1611    return UNRESOLVED_sfixed
1612  is
1613    variable result : UNRESOLVED_sfixed (L'range);
1614  begin
1615    for i in result'range loop
1616      result(i) := L(i) or R;
1617    end loop;
1618    return result;
1619  end function "or";
1620
1621  function "nand" (L : STD_ULOGIC; R : UNRESOLVED_sfixed)
1622    return UNRESOLVED_sfixed
1623  is
1624    variable result : UNRESOLVED_sfixed (R'range);
1625  begin
1626    for i in result'range loop
1627      result(i) := L nand R(i);
1628    end loop;
1629    return result;
1630  end function "nand";
1631
1632  function "nand" (L : UNRESOLVED_sfixed; R : STD_ULOGIC)
1633    return UNRESOLVED_sfixed
1634  is
1635    variable result : UNRESOLVED_sfixed (L'range);
1636  begin
1637    for i in result'range loop
1638      result(i) := L(i) nand R;
1639    end loop;
1640    return result;
1641  end function "nand";
1642
1643  function "nor" (L : STD_ULOGIC; R : UNRESOLVED_sfixed)
1644    return UNRESOLVED_sfixed
1645  is
1646    variable result : UNRESOLVED_sfixed (R'range);
1647  begin
1648    for i in result'range loop
1649      result(i) := L nor R(i);
1650    end loop;
1651    return result;
1652  end function "nor";
1653
1654  function "nor" (L : UNRESOLVED_sfixed; R : STD_ULOGIC)
1655    return UNRESOLVED_sfixed
1656  is
1657    variable result : UNRESOLVED_sfixed (L'range);
1658  begin
1659    for i in result'range loop
1660      result(i) := L(i) nor R;
1661    end loop;
1662    return result;
1663  end function "nor";
1664
1665  function "xor" (L : STD_ULOGIC; R : UNRESOLVED_sfixed)
1666    return UNRESOLVED_sfixed
1667  is
1668    variable result : UNRESOLVED_sfixed (R'range);
1669  begin
1670    for i in result'range loop
1671      result(i) := L xor R(i);
1672    end loop;
1673    return result;
1674  end function "xor";
1675
1676  function "xor" (L : UNRESOLVED_sfixed; R : STD_ULOGIC)
1677    return UNRESOLVED_sfixed
1678  is
1679    variable result : UNRESOLVED_sfixed (L'range);
1680  begin
1681    for i in result'range loop
1682      result(i) := L(i) xor R;
1683    end loop;
1684    return result;
1685  end function "xor";
1686
1687  function "xnor" (L : STD_ULOGIC; R : UNRESOLVED_sfixed)
1688    return UNRESOLVED_sfixed
1689  is
1690    variable result : UNRESOLVED_sfixed (R'range);
1691  begin
1692    for i in result'range loop
1693      result(i) := L xnor R(i);
1694    end loop;
1695    return result;
1696  end function "xnor";
1697
1698  function "xnor" (L : UNRESOLVED_sfixed; R : STD_ULOGIC)
1699    return UNRESOLVED_sfixed
1700  is
1701    variable result : UNRESOLVED_sfixed (L'range);
1702  begin
1703    for i in result'range loop
1704      result(i) := L(i) xnor R;
1705    end loop;
1706    return result;
1707  end function "xnor";
1708
1709  -- Reduction operators
1710  function "and" (l : UNRESOLVED_ufixed) return STD_ULOGIC is
1711  begin
1712    return and to_sulv(l);
1713  end function "and";
1714
1715  function "nand" (l : UNRESOLVED_ufixed) return STD_ULOGIC is
1716  begin
1717    return nand to_sulv(l);
1718  end function "nand";
1719
1720  function "or" (l : UNRESOLVED_ufixed) return STD_ULOGIC is
1721  begin
1722    return or to_sulv(l);
1723  end function "or";
1724
1725  function "nor" (l : UNRESOLVED_ufixed) return STD_ULOGIC is
1726  begin
1727    return nor to_sulv(l);
1728  end function "nor";
1729
1730  function "xor" (l : UNRESOLVED_ufixed) return STD_ULOGIC is
1731  begin
1732    return xor to_sulv(l);
1733  end function "xor";
1734
1735  function "xnor" (l : UNRESOLVED_ufixed) return STD_ULOGIC is
1736  begin
1737    return xnor to_sulv(l);
1738  end function "xnor";
1739
1740  function "and" (l : UNRESOLVED_sfixed) return STD_ULOGIC is
1741  begin
1742    return and to_sulv(l);
1743  end function "and";
1744
1745  function "nand" (l : UNRESOLVED_sfixed) return STD_ULOGIC is
1746  begin
1747    return nand to_sulv(l);
1748  end function "nand";
1749
1750  function "or" (l : UNRESOLVED_sfixed) return STD_ULOGIC is
1751  begin
1752    return or to_sulv(l);
1753  end function "or";
1754
1755  function "nor" (l : UNRESOLVED_sfixed) return STD_ULOGIC is
1756  begin
1757    return nor to_sulv(l);
1758  end function "nor";
1759
1760  function "xor" (l : UNRESOLVED_sfixed) return STD_ULOGIC is
1761  begin
1762    return xor to_sulv(l);
1763  end function "xor";
1764
1765  function "xnor" (l : UNRESOLVED_sfixed) return STD_ULOGIC is
1766  begin
1767    return xnor to_sulv(l);
1768  end function "xnor";
1769  -- End reduction operators
1770
1771  function "?=" (L, R : UNRESOLVED_ufixed) return STD_ULOGIC is
1772    constant left_index       : INTEGER := maximum(L'high, R'high);
1773    constant right_index      : INTEGER := mins(L'low, R'low);
1774    variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
1775    variable lslv, rslv       : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
1776  begin  -- ?=
1777    if ((L'length < 1) or (R'length < 1)) then
1778      assert no_warning
1779        report fixed_generic_pkg'instance_name
1780        & """?="": null detected, returning X"
1781        severity warning;
1782      return 'X';
1783    else
1784      lresize := resize (L, left_index, right_index);
1785      rresize := resize (R, left_index, right_index);
1786      lslv    := to_uns (lresize);
1787      rslv    := to_uns (rresize);
1788      return lslv ?= rslv;
1789    end if;
1790  end function "?=";
1791
1792  function "?/=" (L, R : UNRESOLVED_ufixed) return STD_ULOGIC is
1793    constant left_index       : INTEGER := maximum(L'high, R'high);
1794    constant right_index      : INTEGER := mins(L'low, R'low);
1795    variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
1796    variable lslv, rslv       : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
1797  begin  -- ?/=
1798    if ((L'length < 1) or (R'length < 1)) then
1799      assert no_warning
1800        report fixed_generic_pkg'instance_name
1801        & """?/="": null detected, returning X"
1802        severity warning;
1803      return 'X';
1804    else
1805      lresize := resize (L, left_index, right_index);
1806      rresize := resize (R, left_index, right_index);
1807      lslv    := to_uns (lresize);
1808      rslv    := to_uns (rresize);
1809      return lslv ?/= rslv;
1810    end if;
1811  end function "?/=";
1812
1813  function "?>" (L, R : UNRESOLVED_ufixed) return STD_ULOGIC is
1814    constant left_index       : INTEGER := maximum(L'high, R'high);
1815    constant right_index      : INTEGER := mins(L'low, R'low);
1816    variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
1817    variable lslv, rslv       : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
1818  begin  -- ?>
1819    if ((L'length < 1) or (R'length < 1)) then
1820      assert no_warning
1821        report fixed_generic_pkg'instance_name
1822        & """?>"": null detected, returning X"
1823        severity warning;
1824      return 'X';
1825    else
1826      lresize := resize (L, left_index, right_index);
1827      rresize := resize (R, left_index, right_index);
1828      lslv    := to_uns (lresize);
1829      rslv    := to_uns (rresize);
1830      return lslv ?> rslv;
1831    end if;
1832  end function "?>";
1833
1834  function "?>=" (L, R : UNRESOLVED_ufixed) return STD_ULOGIC is
1835    constant left_index       : INTEGER := maximum(L'high, R'high);
1836    constant right_index      : INTEGER := mins(L'low, R'low);
1837    variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
1838    variable lslv, rslv       : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
1839  begin  -- ?>=
1840    if ((L'length < 1) or (R'length < 1)) then
1841      assert no_warning
1842        report fixed_generic_pkg'instance_name
1843        & """?>="": null detected, returning X"
1844        severity warning;
1845      return 'X';
1846    else
1847      lresize := resize (L, left_index, right_index);
1848      rresize := resize (R, left_index, right_index);
1849      lslv    := to_uns (lresize);
1850      rslv    := to_uns (rresize);
1851      return lslv ?>= rslv;
1852    end if;
1853  end function "?>=";
1854
1855  function "?<" (L, R : UNRESOLVED_ufixed) return STD_ULOGIC is
1856    constant left_index       : INTEGER := maximum(L'high, R'high);
1857    constant right_index      : INTEGER := mins(L'low, R'low);
1858    variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
1859    variable lslv, rslv       : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
1860  begin  -- ?<
1861    if ((L'length < 1) or (R'length < 1)) then
1862      assert no_warning
1863        report fixed_generic_pkg'instance_name
1864        & """?<"": null detected, returning X"
1865        severity warning;
1866      return 'X';
1867    else
1868      lresize := resize (L, left_index, right_index);
1869      rresize := resize (R, left_index, right_index);
1870      lslv    := to_uns (lresize);
1871      rslv    := to_uns (rresize);
1872      return lslv ?< rslv;
1873    end if;
1874  end function "?<";
1875
1876  function "?<=" (L, R : UNRESOLVED_ufixed) return STD_ULOGIC is
1877    constant left_index       : INTEGER := maximum(L'high, R'high);
1878    constant right_index      : INTEGER := mins(L'low, R'low);
1879    variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
1880    variable lslv, rslv       : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
1881  begin  -- ?<=
1882    if ((L'length < 1) or (R'length < 1)) then
1883      assert no_warning
1884        report fixed_generic_pkg'instance_name
1885        & """?<="": null detected, returning X"
1886        severity warning;
1887      return 'X';
1888    else
1889      lresize := resize (L, left_index, right_index);
1890      rresize := resize (R, left_index, right_index);
1891      lslv    := to_uns (lresize);
1892      rslv    := to_uns (rresize);
1893      return lslv ?<= rslv;
1894    end if;
1895  end function "?<=";
1896
1897  function "?=" (L, R : UNRESOLVED_sfixed) return STD_ULOGIC is
1898    constant left_index       : INTEGER := maximum(L'high, R'high);
1899    constant right_index      : INTEGER := mins(L'low, R'low);
1900    variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
1901    variable lslv, rslv       : UNRESOLVED_SIGNED (lresize'length-1 downto 0);
1902  begin  -- ?=
1903    if ((L'length < 1) or (R'length < 1)) then
1904      assert no_warning
1905        report fixed_generic_pkg'instance_name
1906        & """?="": null detected, returning X"
1907        severity warning;
1908      return 'X';
1909    else
1910      lresize := resize (L, left_index, right_index);
1911      rresize := resize (R, left_index, right_index);
1912      lslv    := to_s (lresize);
1913      rslv    := to_s (rresize);
1914      return lslv ?= rslv;
1915    end if;
1916  end function "?=";
1917
1918  function "?/=" (L, R : UNRESOLVED_sfixed) return STD_ULOGIC is
1919    constant left_index       : INTEGER := maximum(L'high, R'high);
1920    constant right_index      : INTEGER := mins(L'low, R'low);
1921    variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
1922    variable lslv, rslv       : UNRESOLVED_SIGNED (lresize'length-1 downto 0);
1923  begin  -- ?/=
1924    if ((L'length < 1) or (R'length < 1)) then
1925      assert no_warning
1926        report fixed_generic_pkg'instance_name
1927        & """?/="": null detected, returning X"
1928        severity warning;
1929      return 'X';
1930    else
1931      lresize := resize (L, left_index, right_index);
1932      rresize := resize (R, left_index, right_index);
1933      lslv    := to_s (lresize);
1934      rslv    := to_s (rresize);
1935      return lslv ?/= rslv;
1936    end if;
1937  end function "?/=";
1938
1939  function "?>" (L, R : UNRESOLVED_sfixed) return STD_ULOGIC is
1940    constant left_index       : INTEGER := maximum(L'high, R'high);
1941    constant right_index      : INTEGER := mins(L'low, R'low);
1942    variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
1943    variable lslv, rslv       : UNRESOLVED_SIGNED (lresize'length-1 downto 0);
1944  begin  -- ?>
1945    if ((L'length < 1) or (R'length < 1)) then
1946      assert no_warning
1947        report fixed_generic_pkg'instance_name
1948        & """?>"": null detected, returning X"
1949        severity warning;
1950      return 'X';
1951    else
1952      lresize := resize (L, left_index, right_index);
1953      rresize := resize (R, left_index, right_index);
1954      lslv    := to_s (lresize);
1955      rslv    := to_s (rresize);
1956      return lslv ?> rslv;
1957    end if;
1958  end function "?>";
1959
1960  function "?>=" (L, R : UNRESOLVED_sfixed) return STD_ULOGIC is
1961    constant left_index       : INTEGER := maximum(L'high, R'high);
1962    constant right_index      : INTEGER := mins(L'low, R'low);
1963    variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
1964    variable lslv, rslv       : UNRESOLVED_SIGNED (lresize'length-1 downto 0);
1965  begin  -- ?>=
1966    if ((L'length < 1) or (R'length < 1)) then
1967      assert no_warning
1968        report fixed_generic_pkg'instance_name
1969        & """?>="": null detected, returning X"
1970        severity warning;
1971      return 'X';
1972    else
1973      lresize := resize (L, left_index, right_index);
1974      rresize := resize (R, left_index, right_index);
1975      lslv    := to_s (lresize);
1976      rslv    := to_s (rresize);
1977      return lslv ?>= rslv;
1978    end if;
1979  end function "?>=";
1980
1981  function "?<" (L, R : UNRESOLVED_sfixed) return STD_ULOGIC is
1982    constant left_index       : INTEGER := maximum(L'high, R'high);
1983    constant right_index      : INTEGER := mins(L'low, R'low);
1984    variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
1985    variable lslv, rslv       : UNRESOLVED_SIGNED (lresize'length-1 downto 0);
1986  begin  -- ?<
1987    if ((L'length < 1) or (R'length < 1)) then
1988      assert no_warning
1989        report fixed_generic_pkg'instance_name
1990        & """?<"": null detected, returning X"
1991        severity warning;
1992      return 'X';
1993    else
1994      lresize := resize (L, left_index, right_index);
1995      rresize := resize (R, left_index, right_index);
1996      lslv    := to_s (lresize);
1997      rslv    := to_s (rresize);
1998      return lslv ?< rslv;
1999    end if;
2000  end function "?<";
2001
2002  function "?<=" (L, R : UNRESOLVED_sfixed) return STD_ULOGIC is
2003    constant left_index       : INTEGER := maximum(L'high, R'high);
2004    constant right_index      : INTEGER := mins(L'low, R'low);
2005    variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
2006    variable lslv, rslv       : UNRESOLVED_SIGNED (lresize'length-1 downto 0);
2007  begin  -- ?<=
2008    if ((L'length < 1) or (R'length < 1)) then
2009      assert no_warning
2010        report fixed_generic_pkg'instance_name
2011        & """?<="": null detected, returning X"
2012        severity warning;
2013      return 'X';
2014    else
2015      lresize := resize (L, left_index, right_index);
2016      rresize := resize (R, left_index, right_index);
2017      lslv    := to_s (lresize);
2018      rslv    := to_s (rresize);
2019      return lslv ?<= rslv;
2020    end if;
2021  end function "?<=";
2022
2023  -- Match function, similar to "std_match" from numeric_std
2024  function std_match (L, R : UNRESOLVED_ufixed) return BOOLEAN is
2025  begin
2026    if (L'high = R'high and L'low = R'low) then
2027      return std_match(to_sulv(L), to_sulv(R));
2028    else
2029      assert no_warning
2030        report fixed_generic_pkg'instance_name
2031        & "STD_MATCH: L'RANGE /= R'RANGE, returning FALSE"
2032        severity warning;
2033      return false;
2034    end if;
2035  end function std_match;
2036
2037  function std_match (L, R : UNRESOLVED_sfixed) return BOOLEAN is
2038  begin
2039    if (L'high = R'high and L'low = R'low) then
2040      return std_match(to_sulv(L), to_sulv(R));
2041    else
2042      assert no_warning
2043        report fixed_generic_pkg'instance_name
2044        & "STD_MATCH: L'RANGE /= R'RANGE, returning FALSE"
2045        severity warning;
2046      return false;
2047    end if;
2048  end function std_match;
2049
2050  -- compare functions
2051  function "=" (
2052    l, r : UNRESOLVED_ufixed)           -- fixed point input
2053    return BOOLEAN
2054  is
2055    constant left_index       : INTEGER := maximum(l'high, r'high);
2056    constant right_index      : INTEGER := mins(l'low, r'low);
2057    variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
2058    variable lslv, rslv       : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
2059  begin
2060    if (l'length < 1 or r'length < 1) then
2061      assert no_warning
2062        report fixed_generic_pkg'instance_name
2063        & """="": null argument detected, returning FALSE"
2064        severity warning;
2065      return false;
2066    elsif (Is_X(l) or Is_X(r)) then
2067      assert no_warning
2068        report fixed_generic_pkg'instance_name
2069        & """="": metavalue detected, returning FALSE"
2070        severity warning;
2071      return false;
2072    end if;
2073    lresize := resize (l, left_index, right_index);
2074    rresize := resize (r, left_index, right_index);
2075    lslv    := to_uns (lresize);
2076    rslv    := to_uns (rresize);
2077    return lslv = rslv;
2078  end function "=";
2079
2080  function "=" (
2081    l, r : UNRESOLVED_sfixed)           -- fixed point input
2082    return BOOLEAN
2083  is
2084    constant left_index       : INTEGER := maximum(l'high, r'high);
2085    constant right_index      : INTEGER := mins(l'low, r'low);
2086    variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
2087    variable lslv, rslv       : UNRESOLVED_SIGNED (lresize'length-1 downto 0);
2088  begin
2089    if (l'length < 1 or r'length < 1) then
2090      assert no_warning
2091        report fixed_generic_pkg'instance_name
2092        & """="": null argument detected, returning FALSE"
2093        severity warning;
2094      return false;
2095    elsif (Is_X(l) or Is_X(r)) then
2096      assert no_warning
2097        report fixed_generic_pkg'instance_name
2098        & """="": metavalue detected, returning FALSE"
2099        severity warning;
2100      return false;
2101    end if;
2102    lresize := resize (l, left_index, right_index);
2103    rresize := resize (r, left_index, right_index);
2104    lslv    := to_s (lresize);
2105    rslv    := to_s (rresize);
2106    return lslv = rslv;
2107  end function "=";
2108
2109  function "/=" (
2110    l, r : UNRESOLVED_ufixed)           -- fixed point input
2111    return BOOLEAN
2112  is
2113    constant left_index       : INTEGER := maximum(l'high, r'high);
2114    constant right_index      : INTEGER := mins(l'low, r'low);
2115    variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
2116    variable lslv, rslv       : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
2117  begin
2118    if (l'length < 1 or r'length < 1) then
2119      assert no_warning
2120        report fixed_generic_pkg'instance_name
2121        & """/="": null argument detected, returning TRUE"
2122        severity warning;
2123      return true;
2124    elsif (Is_X(l) or Is_X(r)) then
2125      assert no_warning
2126        report fixed_generic_pkg'instance_name
2127        & """/="": metavalue detected, returning TRUE"
2128        severity warning;
2129      return true;
2130    end if;
2131    lresize := resize (l, left_index, right_index);
2132    rresize := resize (r, left_index, right_index);
2133    lslv    := to_uns (lresize);
2134    rslv    := to_uns (rresize);
2135    return lslv /= rslv;
2136  end function "/=";
2137
2138  function "/=" (
2139    l, r : UNRESOLVED_sfixed)           -- fixed point input
2140    return BOOLEAN
2141  is
2142    constant left_index       : INTEGER := maximum(l'high, r'high);
2143    constant right_index      : INTEGER := mins(l'low, r'low);
2144    variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
2145    variable lslv, rslv       : UNRESOLVED_SIGNED (lresize'length-1 downto 0);
2146  begin
2147    if (l'length < 1 or r'length < 1) then
2148      assert no_warning
2149        report fixed_generic_pkg'instance_name
2150        & """/="": null argument detected, returning TRUE"
2151        severity warning;
2152      return true;
2153    elsif (Is_X(l) or Is_X(r)) then
2154      assert no_warning
2155        report fixed_generic_pkg'instance_name
2156        & """/="": metavalue detected, returning TRUE"
2157        severity warning;
2158      return true;
2159    end if;
2160    lresize := resize (l, left_index, right_index);
2161    rresize := resize (r, left_index, right_index);
2162    lslv    := to_s (lresize);
2163    rslv    := to_s (rresize);
2164    return lslv /= rslv;
2165  end function "/=";
2166
2167  function ">" (
2168    l, r : UNRESOLVED_ufixed)           -- fixed point input
2169    return BOOLEAN
2170  is
2171    constant left_index       : INTEGER := maximum(l'high, r'high);
2172    constant right_index      : INTEGER := mins(l'low, r'low);
2173    variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
2174    variable lslv, rslv       : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
2175  begin
2176    if (l'length < 1 or r'length < 1) then
2177      assert no_warning
2178        report fixed_generic_pkg'instance_name
2179        & """>"": null argument detected, returning FALSE"
2180        severity warning;
2181      return false;
2182    elsif (Is_X(l) or Is_X(r)) then
2183      assert no_warning
2184        report fixed_generic_pkg'instance_name
2185        & """>"": metavalue detected, returning FALSE"
2186        severity warning;
2187      return false;
2188    end if;
2189    lresize := resize (l, left_index, right_index);
2190    rresize := resize (r, left_index, right_index);
2191    lslv    := to_uns (lresize);
2192    rslv    := to_uns (rresize);
2193    return lslv > rslv;
2194  end function ">";
2195
2196  function ">" (
2197    l, r : UNRESOLVED_sfixed)           -- fixed point input
2198    return BOOLEAN
2199  is
2200    constant left_index       : INTEGER := maximum(l'high, r'high);
2201    constant right_index      : INTEGER := mins(l'low, r'low);
2202    variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
2203    variable lslv, rslv       : UNRESOLVED_SIGNED (lresize'length-1 downto 0);
2204  begin
2205    if (l'length < 1 or r'length < 1) then
2206      assert no_warning
2207        report fixed_generic_pkg'instance_name
2208        & """>"": null argument detected, returning FALSE"
2209        severity warning;
2210      return false;
2211    elsif (Is_X(l) or Is_X(r)) then
2212      assert no_warning
2213        report fixed_generic_pkg'instance_name
2214        & """>"": metavalue detected, returning FALSE"
2215        severity warning;
2216      return false;
2217    end if;
2218    lresize := resize (l, left_index, right_index);
2219    rresize := resize (r, left_index, right_index);
2220    lslv    := to_s (lresize);
2221    rslv    := to_s (rresize);
2222    return lslv > rslv;
2223  end function ">";
2224
2225  function "<" (
2226    l, r : UNRESOLVED_ufixed)           -- fixed point input
2227    return BOOLEAN
2228  is
2229    constant left_index       : INTEGER := maximum(l'high, r'high);
2230    constant right_index      : INTEGER := mins(l'low, r'low);
2231    variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
2232    variable lslv, rslv       : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
2233  begin
2234    if (l'length < 1 or r'length < 1) then
2235      assert no_warning
2236        report fixed_generic_pkg'instance_name
2237        & """<"": null argument detected, returning FALSE"
2238        severity warning;
2239      return false;
2240    elsif (Is_X(l) or Is_X(r)) then
2241      assert no_warning
2242        report fixed_generic_pkg'instance_name
2243        & """<"": metavalue detected, returning FALSE"
2244        severity warning;
2245      return false;
2246    end if;
2247    lresize := resize (l, left_index, right_index);
2248    rresize := resize (r, left_index, right_index);
2249    lslv    := to_uns (lresize);
2250    rslv    := to_uns (rresize);
2251    return lslv < rslv;
2252  end function "<";
2253
2254  function "<" (
2255    l, r : UNRESOLVED_sfixed)           -- fixed point input
2256    return BOOLEAN
2257  is
2258    constant left_index       : INTEGER := maximum(l'high, r'high);
2259    constant right_index      : INTEGER := mins(l'low, r'low);
2260    variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
2261    variable lslv, rslv       : UNRESOLVED_SIGNED (lresize'length-1 downto 0);
2262  begin
2263    if (l'length < 1 or r'length < 1) then
2264      assert no_warning
2265        report fixed_generic_pkg'instance_name
2266        & """<"": null argument detected, returning FALSE"
2267        severity warning;
2268      return false;
2269    elsif (Is_X(l) or Is_X(r)) then
2270      assert no_warning
2271        report fixed_generic_pkg'instance_name
2272        & """<"": metavalue detected, returning FALSE"
2273        severity warning;
2274      return false;
2275    end if;
2276    lresize := resize (l, left_index, right_index);
2277    rresize := resize (r, left_index, right_index);
2278    lslv    := to_s (lresize);
2279    rslv    := to_s (rresize);
2280    return lslv < rslv;
2281  end function "<";
2282
2283  function ">=" (
2284    l, r : UNRESOLVED_ufixed)           -- fixed point input
2285    return BOOLEAN
2286  is
2287    constant left_index       : INTEGER := maximum(l'high, r'high);
2288    constant right_index      : INTEGER := mins(l'low, r'low);
2289    variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
2290    variable lslv, rslv       : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
2291  begin
2292    if (l'length < 1 or r'length < 1) then
2293      assert no_warning
2294        report fixed_generic_pkg'instance_name
2295        & """>="": null argument detected, returning FALSE"
2296        severity warning;
2297      return false;
2298    elsif (Is_X(l) or Is_X(r)) then
2299      assert no_warning
2300        report fixed_generic_pkg'instance_name
2301        & """>="": metavalue detected, returning FALSE"
2302        severity warning;
2303      return false;
2304    end if;
2305    lresize := resize (l, left_index, right_index);
2306    rresize := resize (r, left_index, right_index);
2307    lslv    := to_uns (lresize);
2308    rslv    := to_uns (rresize);
2309    return lslv >= rslv;
2310  end function ">=";
2311
2312  function ">=" (
2313    l, r : UNRESOLVED_sfixed)           -- fixed point input
2314    return BOOLEAN
2315  is
2316    constant left_index       : INTEGER := maximum(l'high, r'high);
2317    constant right_index      : INTEGER := mins(l'low, r'low);
2318    variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
2319    variable lslv, rslv       : UNRESOLVED_SIGNED (lresize'length-1 downto 0);
2320  begin
2321    if (l'length < 1 or r'length < 1) then
2322      assert no_warning
2323        report fixed_generic_pkg'instance_name
2324        & """>="": null argument detected, returning FALSE"
2325        severity warning;
2326      return false;
2327    elsif (Is_X(l) or Is_X(r)) then
2328      assert no_warning
2329        report fixed_generic_pkg'instance_name
2330        & """>="": metavalue detected, returning FALSE"
2331        severity warning;
2332      return false;
2333    end if;
2334    lresize := resize (l, left_index, right_index);
2335    rresize := resize (r, left_index, right_index);
2336    lslv    := to_s (lresize);
2337    rslv    := to_s (rresize);
2338    return lslv >= rslv;
2339  end function ">=";
2340
2341  function "<=" (
2342    l, r : UNRESOLVED_ufixed)           -- fixed point input
2343    return BOOLEAN
2344  is
2345    constant left_index       : INTEGER := maximum(l'high, r'high);
2346    constant right_index      : INTEGER := mins(l'low, r'low);
2347    variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
2348    variable lslv, rslv       : UNRESOLVED_UNSIGNED (lresize'length-1 downto 0);
2349  begin
2350    if (l'length < 1 or r'length < 1) then
2351      assert no_warning
2352        report fixed_generic_pkg'instance_name
2353        & """<="": null argument detected, returning FALSE"
2354        severity warning;
2355      return false;
2356    elsif (Is_X(l) or Is_X(r)) then
2357      assert no_warning
2358        report fixed_generic_pkg'instance_name
2359        & """<="": metavalue detected, returning FALSE"
2360        severity warning;
2361      return false;
2362    end if;
2363    lresize     := resize (l, left_index, right_index);
2364    rresize     := resize (r, left_index, right_index);
2365    lslv        := to_uns (lresize);
2366    rslv        := to_uns (rresize);
2367    return lslv <= rslv;
2368  end function "<=";
2369
2370  function "<=" (
2371    l, r : UNRESOLVED_sfixed)           -- fixed point input
2372    return BOOLEAN
2373  is
2374    constant left_index       : INTEGER := maximum(l'high, r'high);
2375    constant right_index      : INTEGER := mins(l'low, r'low);
2376    variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
2377    variable lslv, rslv       : UNRESOLVED_SIGNED (lresize'length-1 downto 0);
2378  begin
2379    if (l'length < 1 or r'length < 1) then
2380      assert no_warning
2381        report fixed_generic_pkg'instance_name
2382        & """<="": null argument detected, returning FALSE"
2383        severity warning;
2384      return false;
2385    elsif (Is_X(l) or Is_X(r)) then
2386      assert no_warning
2387        report fixed_generic_pkg'instance_name
2388        & """<="": metavalue detected, returning FALSE"
2389        severity warning;
2390      return false;
2391    end if;
2392    lresize     := resize (l, left_index, right_index);
2393    rresize     := resize (r, left_index, right_index);
2394    lslv        := to_s (lresize);
2395    rslv        := to_s (rresize);
2396    return lslv <= rslv;
2397  end function "<=";
2398
2399  -- overloads of the default maximum and minimum functions
2400  function maximum (l, r : UNRESOLVED_ufixed) return UNRESOLVED_ufixed is
2401    constant left_index       : INTEGER := maximum(l'high, r'high);
2402    constant right_index      : INTEGER := mins(l'low, r'low);
2403    variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
2404  begin
2405    if (l'length < 1 or r'length < 1) then
2406      return NAUF;
2407    end if;
2408    lresize := resize (l, left_index, right_index);
2409    rresize := resize (r, left_index, right_index);
2410    return to_fixed(maximum(to_uns(lresize), to_uns(rresize)),
2411                    left_index, right_index);
2412  end function maximum;
2413
2414  function maximum (l, r : UNRESOLVED_sfixed) return UNRESOLVED_sfixed is
2415    constant left_index       : INTEGER := maximum(l'high, r'high);
2416    constant right_index      : INTEGER := mins(l'low, r'low);
2417    variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
2418  begin
2419    if (l'length < 1 or r'length < 1) then
2420      return NASF;
2421    end if;
2422    lresize := resize (l, left_index, right_index);
2423    rresize := resize (r, left_index, right_index);
2424    return to_fixed(maximum(to_s(lresize), to_s(rresize)),
2425                    left_index, right_index);
2426  end function maximum;
2427
2428  function minimum (l, r : UNRESOLVED_ufixed) return UNRESOLVED_ufixed is
2429    constant left_index       : INTEGER := maximum(l'high, r'high);
2430    constant right_index      : INTEGER := mins(l'low, r'low);
2431    variable lresize, rresize : UNRESOLVED_ufixed (left_index downto right_index);
2432  begin
2433    if (l'length < 1 or r'length < 1) then
2434      return NAUF;
2435    end if;
2436    lresize := resize (l, left_index, right_index);
2437    rresize := resize (r, left_index, right_index);
2438    return to_fixed(minimum(to_uns(lresize), to_uns(rresize)),
2439                    left_index, right_index);
2440  end function minimum;
2441
2442  function minimum (l, r : UNRESOLVED_sfixed) return UNRESOLVED_sfixed is
2443    constant left_index       : INTEGER := maximum(l'high, r'high);
2444    constant right_index      : INTEGER := mins(l'low, r'low);
2445    variable lresize, rresize : UNRESOLVED_sfixed (left_index downto right_index);
2446  begin
2447    if (l'length < 1 or r'length < 1) then
2448      return NASF;
2449    end if;
2450    lresize := resize (l, left_index, right_index);
2451    rresize := resize (r, left_index, right_index);
2452    return to_fixed(minimum(to_s(lresize), to_s(rresize)),
2453                    left_index, right_index);
2454  end function minimum;
2455
2456  function to_ufixed (
2457    arg                     : NATURAL;  -- integer
2458    constant left_index     : INTEGER;  -- left index (high index)
2459    constant right_index    : INTEGER                   := 0;  -- right index
2460    constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
2461    constant round_style    : fixed_round_style_type    := fixed_round_style)
2462    return UNRESOLVED_ufixed
2463  is
2464    constant fw      : INTEGER := mins (right_index, right_index);  -- catch literals
2465    variable result  : UNRESOLVED_ufixed (left_index downto fw);
2466    variable sresult : UNRESOLVED_ufixed (left_index downto 0) :=
2467      (others => '0');  -- integer portion
2468    variable argx    : NATURAL;         -- internal version of arg
2469  begin
2470    if (result'length < 1) then
2471      return NAUF;
2472    end if;
2473    if arg /= 0 then
2474      argx := arg;
2475      for I in 0 to sresult'left loop
2476        if (argx mod 2) = 0 then
2477          sresult(I) := '0';
2478        else
2479          sresult(I) := '1';
2480        end if;
2481        argx := argx/2;
2482      end loop;
2483      if argx /= 0 then
2484        assert no_warning
2485          report fixed_generic_pkg'instance_name
2486          & "TO_UFIXED(NATURAL): vector truncated"
2487          severity warning;
2488        if overflow_style = fixed_saturate then
2489          return saturate (left_index, right_index);
2490        end if;
2491      end if;
2492      result := resize (arg            => sresult,
2493                        left_index     => left_index,
2494                        right_index    => right_index,
2495                        round_style    => round_style,
2496                        overflow_style => overflow_style);
2497    else
2498      result := (others => '0');
2499    end if;
2500    return result;
2501  end function to_ufixed;
2502
2503  function to_sfixed (
2504    arg                     : INTEGER;  -- integer
2505    constant left_index     : INTEGER;  -- left index (high index)
2506    constant right_index    : INTEGER                   := 0;  -- right index
2507    constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
2508    constant round_style    : fixed_round_style_type    := fixed_round_style)
2509    return UNRESOLVED_sfixed
2510  is
2511    constant fw      : INTEGER := mins (right_index, right_index);  -- catch literals
2512    variable result  : UNRESOLVED_sfixed (left_index downto fw);
2513    variable sresult : UNRESOLVED_sfixed (left_index downto 0) :=
2514      (others => '0');  -- integer portion
2515    variable argx    : INTEGER;         -- internal version of arg
2516    variable sign    : STD_ULOGIC;      -- sign of input
2517  begin
2518    if (result'length < 1) then         -- null range
2519      return NASF;
2520    end if;
2521    if arg /= 0 then
2522      if (arg < 0) then
2523        sign := '1';
2524        argx := -(arg + 1);
2525      else
2526        sign := '0';
2527        argx := arg;
2528      end if;
2529      for I in 0 to sresult'left loop
2530        if (argx mod 2) = 0 then
2531          sresult(I) := sign;
2532        else
2533          sresult(I) := not sign;
2534        end if;
2535        argx := argx/2;
2536      end loop;
2537      if argx /= 0 or left_index < 0 or sign /= sresult(sresult'left) then
2538        assert no_warning
2539          report fixed_generic_pkg'instance_name
2540          & "TO_SFIXED(INTEGER): vector truncated"
2541          severity warning;
2542        if overflow_style = fixed_saturate then                -- saturate
2543          if arg < 0 then
2544            result := not saturate (result'high, result'low);  -- underflow
2545          else
2546            result := saturate (result'high, result'low);      -- overflow
2547          end if;
2548          return result;
2549        end if;
2550      end if;
2551      result := resize (arg            => sresult,
2552                        left_index     => left_index,
2553                        right_index    => right_index,
2554                        round_style    => round_style,
2555                        overflow_style => overflow_style);
2556    else
2557      result := (others => '0');
2558    end if;
2559    return result;
2560  end function to_sfixed;
2561
2562  function to_ufixed (
2563    arg                     : REAL;     -- real
2564    constant left_index     : INTEGER;  -- left index (high index)
2565    constant right_index    : INTEGER;  -- right index
2566    constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
2567    constant round_style    : fixed_round_style_type    := fixed_round_style;
2568    constant guard_bits     : NATURAL                   := fixed_guard_bits)  -- # of guard bits
2569    return UNRESOLVED_ufixed
2570  is
2571    constant fw              : INTEGER := mins (right_index, right_index);  -- catch literals
2572    variable result          : UNRESOLVED_ufixed (left_index downto fw) :=
2573      (others => '0');
2574    variable Xresult         : UNRESOLVED_ufixed (left_index downto
2575                                                  fw-guard_bits) :=
2576      (others => '0');
2577    variable presult         : REAL;
2578  begin
2579    -- If negative or null range, return.
2580    if (left_index < fw) then
2581      return NAUF;
2582    end if;
2583    if (arg < 0.0) then
2584      report fixed_generic_pkg'instance_name
2585        & "TO_UFIXED: Negative argument passed "
2586        & REAL'image(arg) severity error;
2587      return result;
2588    end if;
2589    presult := arg;
2590    if presult >= (2.0**(left_index+1)) then
2591      assert no_warning report fixed_generic_pkg'instance_name
2592        & "TO_UFIXED(REAL): vector truncated"
2593        severity warning;
2594      if overflow_style = fixed_wrap then
2595        presult := presult mod (2.0**(left_index+1));  -- wrap
2596      else
2597        return saturate (result'high, result'low);
2598      end if;
2599    end if;
2600    for i in Xresult'range loop
2601      if presult >= 2.0**i then
2602        Xresult(i) := '1';
2603        presult    := presult - 2.0**i;
2604      else
2605        Xresult(i) := '0';
2606      end if;
2607    end loop;
2608    if guard_bits > 0 and round_style = fixed_round then
2609      result := round_fixed (arg => Xresult (left_index
2610                                             downto right_index),
2611                             remainder => Xresult (right_index-1 downto
2612                                                   right_index-guard_bits),
2613                             overflow_style => overflow_style);
2614    else
2615      result := Xresult (result'range);
2616    end if;
2617    return result;
2618  end function to_ufixed;
2619
2620  function to_sfixed (
2621    arg                     : REAL;     -- real
2622    constant left_index     : INTEGER;  -- left index (high index)
2623    constant right_index    : INTEGER;  -- right index
2624    constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
2625    constant round_style    : fixed_round_style_type    := fixed_round_style;
2626    constant guard_bits     : NATURAL                   := fixed_guard_bits)  -- # of guard bits
2627    return UNRESOLVED_sfixed
2628  is
2629    constant fw     : INTEGER := mins (right_index, right_index);  -- catch literals
2630    variable result : UNRESOLVED_sfixed (left_index downto fw) :=
2631      (others => '0');
2632    variable Xresult : UNRESOLVED_sfixed (left_index+1 downto fw-guard_bits) :=
2633      (others => '0');
2634    variable presult : REAL;
2635  begin
2636    if (left_index < fw) then           -- null range
2637      return NASF;
2638    end if;
2639    if (arg >= (2.0**left_index) or arg < -(2.0**left_index)) then
2640      assert no_warning report fixed_generic_pkg'instance_name
2641        & "TO_SFIXED(REAL): vector truncated"
2642        severity warning;
2643      if overflow_style = fixed_saturate then
2644        if arg < 0.0 then               -- saturate
2645          result := not saturate (result'high, result'low);        -- underflow
2646        else
2647          result := saturate (result'high, result'low);            -- overflow
2648        end if;
2649        return result;
2650      else
2651        presult := abs(arg) mod (2.0**(left_index+1));             -- wrap
2652      end if;
2653    else
2654      presult := abs(arg);
2655    end if;
2656    for i in Xresult'range loop
2657      if presult >= 2.0**i then
2658        Xresult(i) := '1';
2659        presult    := presult - 2.0**i;
2660      else
2661        Xresult(i) := '0';
2662      end if;
2663    end loop;
2664    if arg < 0.0 then
2665      Xresult := to_fixed(-to_s(Xresult), Xresult'high, Xresult'low);
2666    end if;
2667    if guard_bits > 0 and round_style = fixed_round then
2668      result := round_fixed (arg => Xresult (left_index
2669                                             downto right_index),
2670                             remainder => Xresult (right_index-1 downto
2671                                                   right_index-guard_bits),
2672                             overflow_style => overflow_style);
2673    else
2674      result := Xresult (result'range);
2675    end if;
2676    return result;
2677  end function to_sfixed;
2678
2679  function to_ufixed (
2680    arg                     : UNRESOLVED_UNSIGNED;             -- unsigned
2681    constant left_index     : INTEGER;  -- left index (high index)
2682    constant right_index    : INTEGER                   := 0;  -- right index
2683    constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
2684    constant round_style    : fixed_round_style_type    := fixed_round_style)
2685    return UNRESOLVED_ufixed
2686  is
2687    constant ARG_LEFT : INTEGER := arg'length-1;
2688    alias XARG        : UNRESOLVED_UNSIGNED(ARG_LEFT downto 0) is arg;
2689    variable result   : UNRESOLVED_ufixed (left_index downto right_index);
2690  begin
2691    if arg'length < 1 or (left_index < right_index) then
2692      return NAUF;
2693    end if;
2694    result := resize (arg            => UNRESOLVED_ufixed (XARG),
2695                      left_index     => left_index,
2696                      right_index    => right_index,
2697                      round_style    => round_style,
2698                      overflow_style => overflow_style);
2699    return result;
2700  end function to_ufixed;
2701
2702  -- converted version
2703  function to_ufixed (
2704    arg : UNRESOLVED_UNSIGNED)          -- unsigned
2705    return UNRESOLVED_ufixed
2706  is
2707    constant ARG_LEFT : INTEGER := arg'length-1;
2708    alias XARG        : UNRESOLVED_UNSIGNED(ARG_LEFT downto 0) is arg;
2709  begin
2710    if arg'length < 1 then
2711      return NAUF;
2712    end if;
2713    return UNRESOLVED_ufixed(XARG);
2714  end function to_ufixed;
2715
2716  function to_sfixed (
2717    arg                     : UNRESOLVED_SIGNED;               -- signed
2718    constant left_index     : INTEGER;  -- left index (high index)
2719    constant right_index    : INTEGER                   := 0;  -- right index
2720    constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
2721    constant round_style    : fixed_round_style_type    := fixed_round_style)
2722    return UNRESOLVED_sfixed
2723  is
2724    constant ARG_LEFT : INTEGER := arg'length-1;
2725    alias XARG        : UNRESOLVED_SIGNED(ARG_LEFT downto 0) is arg;
2726    variable result   : UNRESOLVED_sfixed (left_index downto right_index);
2727  begin
2728    if arg'length < 1 or (left_index < right_index) then
2729      return NASF;
2730    end if;
2731    result := resize (arg            => UNRESOLVED_sfixed (XARG),
2732                      left_index     => left_index,
2733                      right_index    => right_index,
2734                      round_style    => round_style,
2735                      overflow_style => overflow_style);
2736    return result;
2737  end function to_sfixed;
2738
2739  -- converted version
2740  function to_sfixed (
2741    arg : UNRESOLVED_SIGNED)            -- signed
2742    return UNRESOLVED_sfixed
2743  is
2744    constant ARG_LEFT : INTEGER := arg'length-1;
2745    alias XARG        : UNRESOLVED_SIGNED(ARG_LEFT downto 0) is arg;
2746  begin
2747    if arg'length < 1 then
2748      return NASF;
2749    end if;
2750    return UNRESOLVED_sfixed(XARG);
2751  end function to_sfixed;
2752
2753  function to_sfixed (arg : UNRESOLVED_ufixed) return UNRESOLVED_sfixed is
2754    variable result : UNRESOLVED_sfixed (arg'high+1 downto arg'low);
2755  begin
2756    if arg'length < 1 then
2757      return NASF;
2758    end if;
2759    result (arg'high downto arg'low) := UNRESOLVED_sfixed(cleanvec(arg));
2760    result (arg'high+1)              := '0';
2761    return result;
2762  end function to_sfixed;
2763
2764  -- Because of the fairly complicated sizing rules in the fixed point
2765  -- packages these functions are provided to compute the result ranges
2766  -- Example:
2767  -- signal uf1 : ufixed (3 downto -3);
2768  -- signal uf2 : ufixed (4 downto -2);
2769  -- signal uf1multuf2 : ufixed (ufixed_high (3, -3, '*', 4, -2) downto
2770  --                             ufixed_low (3, -3, '*', 4, -2));
2771  -- uf1multuf2 <= uf1 * uf2;
2772  -- Valid characters: '+', '-', '*', '/', 'r' or 'R' (rem), 'm' or 'M' (mod),
2773  -- '1' (reciprocal), 'A', 'a' (abs), 'N', 'n' (-sfixed)
2774  function ufixed_high (left_index, right_index   : INTEGER;
2775                        operation                 : CHARACTER := 'X';
2776                        left_index2, right_index2 : INTEGER   := 0)
2777    return INTEGER is
2778  begin
2779    case operation is
2780      when '+'| '-' => return maximum (left_index, left_index2) + 1;
2781      when '*'      => return left_index + left_index2 + 1;
2782      when '/'      => return left_index - right_index2;
2783      when '1'      => return -right_index;                    -- reciprocal
2784      when 'R'|'r'  => return mins (left_index, left_index2);  -- "rem"
2785      when 'M'|'m'  => return mins (left_index, left_index2);  -- "mod"
2786      when others   => return left_index;  -- For abs and default
2787    end case;
2788  end function ufixed_high;
2789
2790  function ufixed_low (left_index, right_index   : INTEGER;
2791                       operation                 : CHARACTER := 'X';
2792                       left_index2, right_index2 : INTEGER   := 0)
2793    return INTEGER is
2794  begin
2795    case operation is
2796      when '+'| '-' => return mins (right_index, right_index2);
2797      when '*'      => return right_index + right_index2;
2798      when '/'      => return right_index - left_index2 - 1;
2799      when '1'      => return -left_index - 1;                   -- reciprocal
2800      when 'R'|'r'  => return mins (right_index, right_index2);  -- "rem"
2801      when 'M'|'m'  => return mins (right_index, right_index2);  -- "mod"
2802      when others   => return right_index;  -- for abs and default
2803    end case;
2804  end function ufixed_low;
2805
2806  function sfixed_high (left_index, right_index   : INTEGER;
2807                        operation                 : CHARACTER := 'X';
2808                        left_index2, right_index2 : INTEGER   := 0)
2809    return INTEGER is
2810  begin
2811    case operation is
2812      when '+'| '-' => return maximum (left_index, left_index2) + 1;
2813      when '*'      => return left_index + left_index2 + 1;
2814      when '/'      => return left_index - right_index2 + 1;
2815      when '1'      => return -right_index + 1;                -- reciprocal
2816      when 'R'|'r'  => return mins (left_index, left_index2);  -- "rem"
2817      when 'M'|'m'  => return left_index2;                     -- "mod"
2818      when 'A'|'a'  => return left_index + 1;                  -- "abs"
2819      when 'N'|'n'  => return left_index + 1;                  -- -sfixed
2820      when others   => return left_index;
2821    end case;
2822  end function sfixed_high;
2823
2824  function sfixed_low (left_index, right_index   : INTEGER;
2825                       operation                 : CHARACTER := 'X';
2826                       left_index2, right_index2 : INTEGER   := 0)
2827    return INTEGER is
2828  begin
2829    case operation is
2830      when '+'| '-' => return mins (right_index, right_index2);
2831      when '*'      => return right_index + right_index2;
2832      when '/'      => return right_index - left_index2;
2833      when '1'      => return -left_index;  -- reciprocal
2834      when 'R'|'r'  => return mins (right_index, right_index2);  -- "rem"
2835      when 'M'|'m'  => return mins (right_index, right_index2);  -- "mod"
2836      when others   => return right_index;  -- default for abs, neg and default
2837    end case;
2838  end function sfixed_low;
2839
2840  -- Same as above, but using the "size_res" input only for their ranges:
2841  -- signal uf1multuf2 : ufixed (ufixed_high (uf1, '*', uf2) downto
2842  --                             ufixed_low (uf1, '*', uf2));
2843  -- uf1multuf2 <= uf1 * uf2;
2844  function ufixed_high (size_res  : UNRESOLVED_ufixed;
2845                        operation : CHARACTER := 'X';
2846                        size_res2 : UNRESOLVED_ufixed)
2847    return INTEGER is
2848  begin
2849    return ufixed_high (left_index   => size_res'high,
2850                        right_index  => size_res'low,
2851                        operation    => operation,
2852                        left_index2  => size_res2'high,
2853                        right_index2 => size_res2'low);
2854  end function ufixed_high;
2855
2856  function ufixed_low (size_res  : UNRESOLVED_ufixed;
2857                       operation : CHARACTER := 'X';
2858                       size_res2 : UNRESOLVED_ufixed)
2859    return INTEGER is
2860  begin
2861    return ufixed_low (left_index   => size_res'high,
2862                       right_index  => size_res'low,
2863                       operation    => operation,
2864                       left_index2  => size_res2'high,
2865                       right_index2 => size_res2'low);
2866  end function ufixed_low;
2867
2868  function sfixed_high (size_res  : UNRESOLVED_sfixed;
2869                        operation : CHARACTER := 'X';
2870                        size_res2 : UNRESOLVED_sfixed)
2871    return INTEGER is
2872  begin
2873    return sfixed_high (left_index   => size_res'high,
2874                        right_index  => size_res'low,
2875                        operation    => operation,
2876                        left_index2  => size_res2'high,
2877                        right_index2 => size_res2'low);
2878  end function sfixed_high;
2879
2880  function sfixed_low (size_res  : UNRESOLVED_sfixed;
2881                       operation : CHARACTER := 'X';
2882                       size_res2 : UNRESOLVED_sfixed)
2883    return INTEGER is
2884  begin
2885    return sfixed_low (left_index   => size_res'high,
2886                       right_index  => size_res'low,
2887                       operation    => operation,
2888                       left_index2  => size_res2'high,
2889                       right_index2 => size_res2'low);
2890  end function sfixed_low;
2891
2892  -- purpose: returns a saturated number
2893  function saturate (
2894    constant left_index  : INTEGER;
2895    constant right_index : INTEGER)
2896    return UNRESOLVED_ufixed
2897  is
2898    constant sat : UNRESOLVED_ufixed (left_index downto right_index) :=
2899      (others => '1');
2900  begin
2901    return sat;
2902  end function saturate;
2903
2904  -- purpose: returns a saturated number
2905  function saturate (
2906    constant left_index  : INTEGER;
2907    constant right_index : INTEGER)
2908    return UNRESOLVED_sfixed
2909  is
2910    variable sat : UNRESOLVED_sfixed (left_index downto right_index) :=
2911      (others => '1');
2912  begin
2913    -- saturate positive, to saturate negative, just do "not saturate()"
2914    sat (left_index) := '0';
2915    return sat;
2916  end function saturate;
2917
2918  function saturate (
2919    size_res : UNRESOLVED_ufixed)       -- only the size of this is used
2920    return UNRESOLVED_ufixed is
2921  begin
2922    return saturate (size_res'high, size_res'low);
2923  end function saturate;
2924
2925  function saturate (
2926    size_res : UNRESOLVED_sfixed)       -- only the size of this is used
2927    return UNRESOLVED_sfixed is
2928  begin
2929    return saturate (size_res'high, size_res'low);
2930  end function saturate;
2931
2932  -- As a concession to those who use a graphical DSP environment,
2933  -- these functions take parameters in those tools format and create
2934  -- fixed point numbers.  These functions are designed to convert from
2935  -- a std_logic_vector to the VHDL fixed point format using the conventions
2936  -- of these packages.  In a pure VHDL environment you should use the
2937  -- "to_ufixed" and "to_sfixed" routines.
2938  -- Unsigned fixed point
2939  function to_UFix (
2940    arg      : STD_ULOGIC_VECTOR;
2941    width    : NATURAL;                 -- width of vector
2942    fraction : NATURAL)                 -- width of fraction
2943    return UNRESOLVED_ufixed
2944  is
2945    variable result : UNRESOLVED_ufixed (width-fraction-1 downto -fraction);
2946  begin
2947    if (arg'length /= result'length) then
2948      report fixed_generic_pkg'instance_name
2949        & "TO_UFIX (STD_ULOGIC_VECTOR) "
2950        & "Vector lengths do not match.  Input length is "
2951        & INTEGER'image(arg'length) & " and output will be "
2952        & INTEGER'image(result'length) & " wide."
2953        severity error;
2954      return NAUF;
2955    else
2956      result := to_ufixed (arg, result'high, result'low);
2957      return result;
2958    end if;
2959  end function to_UFix;
2960
2961  -- signed fixed point
2962  function to_SFix (
2963    arg      : STD_ULOGIC_VECTOR;
2964    width    : NATURAL;                 -- width of vector
2965    fraction : NATURAL)                 -- width of fraction
2966    return UNRESOLVED_sfixed
2967  is
2968    variable result : UNRESOLVED_sfixed (width-fraction-1 downto -fraction);
2969  begin
2970    if (arg'length /= result'length) then
2971      report fixed_generic_pkg'instance_name
2972        & "TO_SFIX (STD_ULOGIC_VECTOR) "
2973        & "Vector lengths do not match.  Input length is "
2974        & INTEGER'image(arg'length) & " and output will be "
2975        & INTEGER'image(result'length) & " wide."
2976        severity error;
2977      return NASF;
2978    else
2979      result := to_sfixed (arg, result'high, result'low);
2980      return result;
2981    end if;
2982  end function to_SFix;
2983
2984  -- finding the bounds of a number.  These functions can be used like this:
2985  -- signal xxx : ufixed (7 downto -3);
2986  -- -- Which is the same as "ufixed (UFix_high (11,3) downto UFix_low(11,3))"
2987  -- signal yyy : ufixed (UFix_high (11, 3, "+", 11, 3)
2988  --               downto UFix_low(11, 3, "+", 11, 3));
2989  -- Where "11" is the width of xxx (xxx'length),
2990  -- and 3 is the lower bound (abs (xxx'low))
2991  -- In a pure VHDL environment use "ufixed_high" and "ufixed_low"
2992  function ufix_high (
2993    width, fraction   : NATURAL;
2994    operation         : CHARACTER := 'X';
2995    width2, fraction2 : NATURAL   := 0)
2996    return INTEGER is
2997  begin
2998    return ufixed_high (left_index   => width - 1 - fraction,
2999                        right_index  => -fraction,
3000                        operation    => operation,
3001                        left_index2  => width2 - 1 - fraction2,
3002                        right_index2 => -fraction2);
3003  end function ufix_high;
3004
3005  function ufix_low (
3006    width, fraction   : NATURAL;
3007    operation         : CHARACTER := 'X';
3008    width2, fraction2 : NATURAL   := 0)
3009    return INTEGER is
3010  begin
3011    return ufixed_low (left_index   => width - 1 - fraction,
3012                       right_index  => -fraction,
3013                       operation    => operation,
3014                       left_index2  => width2 - 1 - fraction2,
3015                       right_index2 => -fraction2);
3016  end function ufix_low;
3017
3018  function sfix_high (
3019    width, fraction   : NATURAL;
3020    operation         : CHARACTER := 'X';
3021    width2, fraction2 : NATURAL   := 0)
3022    return INTEGER is
3023  begin
3024    return sfixed_high (left_index   => width - fraction,
3025                        right_index  => -fraction,
3026                        operation    => operation,
3027                        left_index2  => width2 - fraction2,
3028                        right_index2 => -fraction2);
3029  end function sfix_high;
3030
3031  function sfix_low (
3032    width, fraction   : NATURAL;
3033    operation         : CHARACTER := 'X';
3034    width2, fraction2 : NATURAL   := 0)
3035    return INTEGER is
3036  begin
3037    return sfixed_low (left_index   => width - fraction,
3038                       right_index  => -fraction,
3039                       operation    => operation,
3040                       left_index2  => width2 - fraction2,
3041                       right_index2 => -fraction2);
3042  end function sfix_low;
3043
3044  function to_unsigned (
3045    arg                     : UNRESOLVED_ufixed;  -- ufixed point input
3046    constant size           : NATURAL;            -- length of output
3047    constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
3048    constant round_style    : fixed_round_style_type    := fixed_round_style)
3049    return UNRESOLVED_UNSIGNED is
3050  begin
3051    return to_uns(resize (arg            => arg,
3052                          left_index     => size-1,
3053                          right_index    => 0,
3054                          round_style    => round_style,
3055                          overflow_style => overflow_style));
3056  end function to_unsigned;
3057
3058  function to_unsigned (
3059    arg                     : UNRESOLVED_ufixed;    -- ufixed point input
3060    size_res                : UNRESOLVED_UNSIGNED;  -- length of output
3061    constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
3062    constant round_style    : fixed_round_style_type    := fixed_round_style)
3063    return UNRESOLVED_UNSIGNED is
3064  begin
3065    return to_unsigned (arg            => arg,
3066                        size           => size_res'length,
3067                        round_style    => round_style,
3068                        overflow_style => overflow_style);
3069  end function to_unsigned;
3070
3071  function to_signed (
3072    arg                     : UNRESOLVED_sfixed;  -- sfixed point input
3073    constant size           : NATURAL;            -- length of output
3074    constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
3075    constant round_style    : fixed_round_style_type    := fixed_round_style)
3076    return UNRESOLVED_SIGNED is
3077  begin
3078    return to_s(resize (arg            => arg,
3079                        left_index     => size-1,
3080                        right_index    => 0,
3081                        round_style    => round_style,
3082                        overflow_style => overflow_style));
3083  end function to_signed;
3084
3085  function to_signed (
3086    arg                     : UNRESOLVED_sfixed;  -- sfixed point input
3087    size_res                : UNRESOLVED_SIGNED;  -- used for length of output
3088    constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
3089    constant round_style    : fixed_round_style_type    := fixed_round_style)
3090    return UNRESOLVED_SIGNED is
3091  begin
3092    return to_signed (arg            => arg,
3093                      size           => size_res'length,
3094                      round_style    => round_style,
3095                      overflow_style => overflow_style);
3096  end function to_signed;
3097
3098  function to_real (
3099    arg : UNRESOLVED_ufixed)            -- ufixed point input
3100    return REAL
3101  is
3102    constant left_index  : INTEGER := arg'high;
3103    constant right_index : INTEGER := arg'low;
3104    variable result      : REAL;        -- result
3105    variable arg_int     : UNRESOLVED_ufixed (left_index downto right_index);
3106  begin
3107    if (arg'length < 1) then
3108      return 0.0;
3109    end if;
3110    arg_int := To_X01(cleanvec(arg));
3111    if (Is_X(arg_int)) then
3112      assert no_warning
3113        report fixed_generic_pkg'instance_name
3114        & "TO_REAL (ufixed): metavalue detected, returning 0.0"
3115        severity warning;
3116      return 0.0;
3117    end if;
3118    result := 0.0;
3119    for i in arg_int'range loop
3120      if (arg_int(i) = '1') then
3121        result := result + (2.0**i);
3122      end if;
3123    end loop;
3124    return result;
3125  end function to_real;
3126
3127  function to_real (
3128    arg : UNRESOLVED_sfixed)            -- ufixed point input
3129    return REAL
3130  is
3131    constant left_index  : INTEGER := arg'high;
3132    constant right_index : INTEGER := arg'low;
3133    variable result      : REAL;        -- result
3134    variable arg_int     : UNRESOLVED_sfixed (left_index downto right_index);
3135    -- unsigned version of argument
3136    variable arg_uns     : UNRESOLVED_ufixed (left_index downto right_index);
3137    -- absolute of argument
3138  begin
3139    if (arg'length < 1) then
3140      return 0.0;
3141    end if;
3142    arg_int := to_X01(cleanvec(arg));
3143    if (Is_X(arg_int)) then
3144      assert no_warning
3145        report fixed_generic_pkg'instance_name
3146        & "TO_REAL (sfixed): metavalue detected, returning 0.0"
3147        severity warning;
3148      return 0.0;
3149    end if;
3150    arg_uns := to_ufixed (arg_int);
3151    result  := to_real (arg_uns);
3152    if (arg_int(arg_int'high) = '1') then
3153      result := -result;
3154    end if;
3155    return result;
3156  end function to_real;
3157
3158  function to_integer (
3159    arg                     : UNRESOLVED_ufixed;  -- fixed point input
3160    constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
3161    constant round_style    : fixed_round_style_type    := fixed_round_style)
3162    return NATURAL
3163  is
3164    constant left_index : INTEGER := arg'high;
3165    variable arg_uns    : UNRESOLVED_UNSIGNED (left_index+1 downto 0)
3166      := (others => '0');
3167  begin
3168    if (arg'length < 1) then
3169      return 0;
3170    end if;
3171    if (Is_X (arg)) then
3172      assert no_warning
3173        report fixed_generic_pkg'instance_name
3174        & "TO_INTEGER (ufixed): metavalue detected, returning 0"
3175        severity warning;
3176      return 0;
3177    end if;
3178    if (left_index < -1) then
3179      return 0;
3180    end if;
3181    arg_uns := to_uns(resize (arg            => arg,
3182                              left_index     => arg_uns'high,
3183                              right_index    => 0,
3184                              round_style    => round_style,
3185                              overflow_style => overflow_style));
3186    return to_integer (arg_uns);
3187  end function to_integer;
3188
3189  function to_integer (
3190    arg                     : UNRESOLVED_sfixed;  -- fixed point input
3191    constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
3192    constant round_style    : fixed_round_style_type    := fixed_round_style)
3193    return INTEGER
3194  is
3195    constant left_index  : INTEGER := arg'high;
3196    variable arg_s       : UNRESOLVED_SIGNED (left_index+1 downto 0);
3197  begin
3198    if (arg'length < 1) then
3199      return 0;
3200    end if;
3201    if (Is_X (arg)) then
3202      assert no_warning
3203        report fixed_generic_pkg'instance_name
3204        & "TO_INTEGER (sfixed): metavalue detected, returning 0"
3205        severity warning;
3206      return 0;
3207    end if;
3208    if (left_index < -1) then
3209      return 0;
3210    end if;
3211    arg_s := to_s(resize (arg            => arg,
3212                          left_index     => arg_s'high,
3213                          right_index    => 0,
3214                          round_style    => round_style,
3215                          overflow_style => overflow_style));
3216    return to_integer (arg_s);
3217  end function to_integer;
3218
3219  function to_01 (
3220    s             : UNRESOLVED_ufixed;              -- ufixed point input
3221    constant XMAP : STD_ULOGIC := '0')              -- Map x to
3222    return UNRESOLVED_ufixed
3223  is
3224  begin
3225    if (s'length < 1) then
3226      assert no_warning
3227        report fixed_generic_pkg'instance_name
3228        & "TO_01(ufixed): null detected, returning NULL"
3229        severity warning;
3230      return NAUF;
3231    end if;
3232    return to_fixed (to_01(to_uns(s), XMAP), s'high, s'low);
3233  end function to_01;
3234
3235  function to_01 (
3236    s             : UNRESOLVED_sfixed;  -- sfixed point input
3237    constant XMAP : STD_ULOGIC := '0')  -- Map x to
3238    return UNRESOLVED_sfixed
3239  is
3240  begin
3241    if (s'length < 1) then
3242      assert no_warning
3243        report fixed_generic_pkg'instance_name
3244        & "TO_01(sfixed): null detected, returning NULL"
3245        severity warning;
3246      return NASF;
3247    end if;
3248    return to_fixed (to_01(to_s(s), XMAP), s'high, s'low);
3249  end function to_01;
3250
3251  function Is_X (
3252    arg : UNRESOLVED_ufixed)
3253    return BOOLEAN
3254  is
3255    variable argslv : STD_ULOGIC_VECTOR (arg'length-1 downto 0);  -- slv
3256  begin
3257    argslv := to_sulv(arg);
3258    return Is_X (argslv);
3259  end function Is_X;
3260
3261  function Is_X (
3262    arg : UNRESOLVED_sfixed)
3263    return BOOLEAN
3264  is
3265    variable argslv : STD_ULOGIC_VECTOR (arg'length-1 downto 0);  -- slv
3266  begin
3267    argslv := to_sulv(arg);
3268    return Is_X (argslv);
3269  end function Is_X;
3270
3271  function To_X01 (
3272    arg : UNRESOLVED_ufixed)
3273    return UNRESOLVED_ufixed is
3274  begin
3275    return to_ufixed (To_X01(to_sulv(arg)), arg'high, arg'low);
3276  end function To_X01;
3277
3278  function to_X01 (
3279    arg : UNRESOLVED_sfixed)
3280    return UNRESOLVED_sfixed is
3281  begin
3282    return to_sfixed (To_X01(to_sulv(arg)), arg'high, arg'low);
3283  end function to_X01;
3284
3285  function To_X01Z (
3286    arg : UNRESOLVED_ufixed)
3287    return UNRESOLVED_ufixed is
3288  begin
3289    return to_ufixed (To_X01Z(to_sulv(arg)), arg'high, arg'low);
3290  end function To_X01Z;
3291
3292  function to_X01Z (
3293    arg : UNRESOLVED_sfixed)
3294    return UNRESOLVED_sfixed is
3295  begin
3296    return to_sfixed (To_X01Z(to_sulv(arg)), arg'high, arg'low);
3297  end function to_X01Z;
3298
3299  function To_UX01 (
3300    arg : UNRESOLVED_ufixed)
3301    return UNRESOLVED_ufixed is
3302  begin
3303    return to_ufixed (To_UX01(to_sulv(arg)), arg'high, arg'low);
3304  end function To_UX01;
3305
3306  function to_UX01 (
3307    arg : UNRESOLVED_sfixed)
3308    return UNRESOLVED_sfixed is
3309  begin
3310    return to_sfixed (To_UX01(to_sulv(arg)), arg'high, arg'low);
3311  end function to_UX01;
3312
3313  function resize (
3314    arg                     : UNRESOLVED_ufixed;            -- input
3315    constant left_index     : INTEGER;  -- integer portion
3316    constant right_index    : INTEGER;  -- size of fraction
3317    constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
3318    constant round_style    : fixed_round_style_type    := fixed_round_style)
3319    return UNRESOLVED_ufixed
3320  is
3321    constant arghigh : INTEGER := maximum (arg'high, arg'low);
3322    constant arglow  : INTEGER := mine (arg'high, arg'low);
3323    variable invec   : UNRESOLVED_ufixed (arghigh downto arglow);
3324    variable result  : UNRESOLVED_ufixed(left_index downto right_index) :=
3325      (others => '0');
3326    variable needs_rounding : BOOLEAN := false;
3327  begin  -- resize
3328    if (arg'length < 1) or (result'length < 1) then
3329      return NAUF;
3330    elsif (invec'length < 1) then
3331      return result;                    -- string literal value
3332    else
3333      invec := cleanvec(arg);
3334      if (right_index > arghigh) then   -- return top zeros
3335        needs_rounding := (round_style = fixed_round) and
3336                          (right_index = arghigh+1);
3337      elsif (left_index < arglow) then  -- return overflow
3338        if (overflow_style = fixed_saturate) and
3339          (or(to_sulv(invec)) = '1') then
3340          result := saturate (result'high, result'low);     -- saturate
3341        end if;
3342      elsif (arghigh > left_index) then
3343        -- wrap or saturate?
3344        if (overflow_style = fixed_saturate and
3345            or (to_sulv(invec(arghigh downto left_index+1))) = '1')
3346        then
3347          result := saturate (result'high, result'low);     -- saturate
3348        else
3349          if (arglow >= right_index) then
3350            result (left_index downto arglow) :=
3351              invec(left_index downto arglow);
3352          else
3353            result (left_index downto right_index) :=
3354              invec (left_index downto right_index);
3355            needs_rounding := (round_style = fixed_round);  -- round
3356          end if;
3357        end if;
3358      else                              -- arghigh <= integer width
3359        if (arglow >= right_index) then
3360          result (arghigh downto arglow) := invec;
3361        else
3362          result (arghigh downto right_index) :=
3363            invec (arghigh downto right_index);
3364          needs_rounding := (round_style = fixed_round);    -- round
3365        end if;
3366      end if;
3367      -- Round result
3368      if needs_rounding then
3369        result := round_fixed (arg            => result,
3370                               remainder      => invec (right_index-1
3371                                                        downto arglow),
3372                               overflow_style => overflow_style);
3373      end if;
3374      return result;
3375    end if;
3376  end function resize;
3377
3378  function resize (
3379    arg                     : UNRESOLVED_sfixed;          -- input
3380    constant left_index     : INTEGER;  -- integer portion
3381    constant right_index    : INTEGER;  -- size of fraction
3382    constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
3383    constant round_style    : fixed_round_style_type    := fixed_round_style)
3384    return UNRESOLVED_sfixed
3385  is
3386    constant arghigh : INTEGER := maximum (arg'high, arg'low);
3387    constant arglow  : INTEGER := mine (arg'high, arg'low);
3388    variable invec   : UNRESOLVED_sfixed (arghigh downto arglow);
3389    variable result  : UNRESOLVED_sfixed(left_index downto right_index) :=
3390      (others => '0');
3391    variable reduced        : STD_ULOGIC;
3392    variable needs_rounding : BOOLEAN := false;           -- rounding
3393  begin  -- resize
3394    if (arg'length < 1) or (result'length < 1) then
3395      return NASF;
3396    elsif (invec'length < 1) then
3397      return result;                    -- string literal value
3398    else
3399      invec := cleanvec(arg);
3400      if (right_index > arghigh) then   -- return top zeros
3401        if (arg'low /= INTEGER'low) then  -- check for a literal
3402          result := (others => arg(arghigh));             -- sign extend
3403        end if;
3404        needs_rounding := (round_style = fixed_round) and
3405                          (right_index = arghigh+1);
3406      elsif (left_index < arglow) then  -- return overflow
3407        if (overflow_style = fixed_saturate) then
3408          reduced := or (to_sulv(invec));
3409          if (reduced = '1') then
3410            if (invec(arghigh) = '0') then
3411              -- saturate POSITIVE
3412              result := saturate (result'high, result'low);
3413            else
3414              -- saturate negative
3415              result := not saturate (result'high, result'low);
3416            end if;
3417            -- else return 0 (input was 0)
3418          end if;
3419          -- else return 0 (wrap)
3420        end if;
3421      elsif (arghigh > left_index) then
3422        if (invec(arghigh) = '0') then
3423          reduced := or (to_sulv(invec(arghigh-1 downto
3424                                      left_index)));
3425          if overflow_style = fixed_saturate and reduced = '1' then
3426            -- saturate positive
3427            result := saturate (result'high, result'low);
3428          else
3429            if (right_index > arglow) then
3430              result         := invec (left_index downto right_index);
3431              needs_rounding := (round_style = fixed_round);
3432            else
3433              result (left_index downto arglow) :=
3434                invec (left_index downto arglow);
3435            end if;
3436          end if;
3437        else
3438          reduced := and (to_sulv(invec(arghigh-1 downto
3439                                       left_index)));
3440          if overflow_style = fixed_saturate and reduced = '0' then
3441            result := not saturate (result'high, result'low);
3442          else
3443            if (right_index > arglow) then
3444              result         := invec (left_index downto right_index);
3445              needs_rounding := (round_style = fixed_round);
3446            else
3447              result (left_index downto arglow) :=
3448                invec (left_index downto arglow);
3449            end if;
3450          end if;
3451        end if;
3452      else                              -- arghigh <= integer width
3453        if (arglow >= right_index) then
3454          result (arghigh downto arglow) := invec;
3455        else
3456          result (arghigh downto right_index) :=
3457            invec (arghigh downto right_index);
3458          needs_rounding := (round_style = fixed_round);  -- round
3459        end if;
3460        if (left_index > arghigh) then  -- sign extend
3461          result(left_index downto arghigh+1) := (others => invec(arghigh));
3462        end if;
3463      end if;
3464      -- Round result
3465      if (needs_rounding) then
3466        result := round_fixed (arg            => result,
3467                               remainder      => invec (right_index-1
3468                                                        downto arglow),
3469                               overflow_style => overflow_style);
3470      end if;
3471      return result;
3472    end if;
3473  end function resize;
3474
3475  -- size_res functions
3476  -- These functions compute the size from a passed variable named "size_res"
3477  -- The only part of this variable used it it's size, it is never passed
3478  -- to a lower level routine.
3479  function to_ufixed (
3480    arg      : STD_ULOGIC_VECTOR;       -- shifted vector
3481    size_res : UNRESOLVED_ufixed)       -- for size only
3482    return UNRESOLVED_ufixed
3483  is
3484    constant fw     : INTEGER := mine (size_res'low, size_res'low);  -- catch literals
3485    variable result : UNRESOLVED_ufixed (size_res'left downto fw);
3486  begin
3487    if (result'length < 1 or arg'length < 1) then
3488      return NAUF;
3489    else
3490      result := to_ufixed (arg         => arg,
3491                           left_index  => size_res'high,
3492                           right_index => size_res'low);
3493      return result;
3494    end if;
3495  end function to_ufixed;
3496
3497  function to_sfixed (
3498    arg      : STD_ULOGIC_VECTOR;       -- shifted vector
3499    size_res : UNRESOLVED_sfixed)       -- for size only
3500    return UNRESOLVED_sfixed
3501  is
3502    constant fw     : INTEGER := mine (size_res'low, size_res'low);  -- catch literals
3503    variable result : UNRESOLVED_sfixed (size_res'left downto fw);
3504  begin
3505    if (result'length < 1 or arg'length < 1) then
3506      return NASF;
3507    else
3508      result := to_sfixed (arg         => arg,
3509                           left_index  => size_res'high,
3510                           right_index => size_res'low);
3511      return result;
3512    end if;
3513  end function to_sfixed;
3514
3515  function to_ufixed (
3516    arg                     : NATURAL;            -- integer
3517    size_res                : UNRESOLVED_ufixed;  -- for size only
3518    constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
3519    constant round_style    : fixed_round_style_type    := fixed_round_style)
3520    return UNRESOLVED_ufixed
3521  is
3522    constant fw     : INTEGER := mine (size_res'low, size_res'low);  -- catch literals
3523    variable result : UNRESOLVED_ufixed (size_res'left downto fw);
3524  begin
3525    if (result'length < 1) then
3526      return NAUF;
3527    else
3528      result := to_ufixed (arg            => arg,
3529                           left_index     => size_res'high,
3530                           right_index    => size_res'low,
3531                           round_style    => round_style,
3532                           overflow_style => overflow_style);
3533      return result;
3534    end if;
3535  end function to_ufixed;
3536
3537  function to_sfixed (
3538    arg                     : INTEGER;            -- integer
3539    size_res                : UNRESOLVED_sfixed;  -- for size only
3540    constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
3541    constant round_style    : fixed_round_style_type    := fixed_round_style)
3542    return UNRESOLVED_sfixed
3543  is
3544    constant fw     : INTEGER := mine (size_res'low, size_res'low);  -- catch literals
3545    variable result : UNRESOLVED_sfixed (size_res'left downto fw);
3546  begin
3547    if (result'length < 1) then
3548      return NASF;
3549    else
3550      result := to_sfixed (arg            => arg,
3551                           left_index     => size_res'high,
3552                           right_index    => size_res'low,
3553                           round_style    => round_style,
3554                           overflow_style => overflow_style);
3555      return result;
3556    end if;
3557  end function to_sfixed;
3558
3559  function to_ufixed (
3560    arg                     : REAL;     -- real
3561    size_res                : UNRESOLVED_ufixed;  -- for size only
3562    constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
3563    constant round_style    : fixed_round_style_type    := fixed_round_style;
3564    constant guard_bits     : NATURAL                   := fixed_guard_bits)  -- # of guard bits
3565    return UNRESOLVED_ufixed
3566  is
3567    constant fw     : INTEGER := mine (size_res'low, size_res'low);  -- catch literals
3568    variable result : UNRESOLVED_ufixed (size_res'left downto fw);
3569  begin
3570    if (result'length < 1) then
3571      return NAUF;
3572    else
3573      result := to_ufixed (arg            => arg,
3574                           left_index     => size_res'high,
3575                           right_index    => size_res'low,
3576                           guard_bits     => guard_bits,
3577                           round_style    => round_style,
3578                           overflow_style => overflow_style);
3579      return result;
3580    end if;
3581  end function to_ufixed;
3582
3583  function to_sfixed (
3584    arg                     : REAL;     -- real
3585    size_res                : UNRESOLVED_sfixed;  -- for size only
3586    constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
3587    constant round_style    : fixed_round_style_type    := fixed_round_style;
3588    constant guard_bits     : NATURAL                   := fixed_guard_bits)  -- # of guard bits
3589    return UNRESOLVED_sfixed
3590  is
3591    constant fw     : INTEGER := mine (size_res'low, size_res'low);  -- catch literals
3592    variable result : UNRESOLVED_sfixed (size_res'left downto fw);
3593  begin
3594    if (result'length < 1) then
3595      return NASF;
3596    else
3597      result := to_sfixed (arg            => arg,
3598                           left_index     => size_res'high,
3599                           right_index    => size_res'low,
3600                           guard_bits     => guard_bits,
3601                           round_style    => round_style,
3602                           overflow_style => overflow_style);
3603      return result;
3604    end if;
3605  end function to_sfixed;
3606
3607  function to_ufixed (
3608    arg                     : UNRESOLVED_UNSIGNED;  -- unsigned
3609    size_res                : UNRESOLVED_ufixed;    -- for size only
3610    constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
3611    constant round_style    : fixed_round_style_type    := fixed_round_style)
3612    return UNRESOLVED_ufixed
3613  is
3614    constant fw     : INTEGER := mine (size_res'low, size_res'low);  -- catch literals
3615    variable result : UNRESOLVED_ufixed (size_res'left downto fw);
3616  begin
3617    if (result'length < 1 or arg'length < 1) then
3618      return NAUF;
3619    else
3620      result := to_ufixed (arg            => arg,
3621                           left_index     => size_res'high,
3622                           right_index    => size_res'low,
3623                           round_style    => round_style,
3624                           overflow_style => overflow_style);
3625      return result;
3626    end if;
3627  end function to_ufixed;
3628
3629  function to_sfixed (
3630    arg                     : UNRESOLVED_SIGNED;  -- signed
3631    size_res                : UNRESOLVED_sfixed;  -- for size only
3632    constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
3633    constant round_style    : fixed_round_style_type    := fixed_round_style)
3634    return UNRESOLVED_sfixed
3635  is
3636    constant fw     : INTEGER := mine (size_res'low, size_res'low);  -- catch literals
3637    variable result : UNRESOLVED_sfixed (size_res'left downto fw);
3638  begin
3639    if (result'length < 1 or arg'length < 1) then
3640      return NASF;
3641    else
3642      result := to_sfixed (arg            => arg,
3643                           left_index     => size_res'high,
3644                           right_index    => size_res'low,
3645                           round_style    => round_style,
3646                           overflow_style => overflow_style);
3647      return result;
3648    end if;
3649  end function to_sfixed;
3650
3651  function resize (
3652    arg                     : UNRESOLVED_ufixed;  -- input
3653    size_res                : UNRESOLVED_ufixed;  -- for size only
3654    constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
3655    constant round_style    : fixed_round_style_type    := fixed_round_style)
3656    return UNRESOLVED_ufixed
3657  is
3658    constant fw     : INTEGER := mine (size_res'low, size_res'low);  -- catch literals
3659    variable result : UNRESOLVED_ufixed (size_res'high downto fw);
3660  begin
3661    if (result'length < 1 or arg'length < 1) then
3662      return NAUF;
3663    else
3664      result := resize (arg            => arg,
3665                        left_index     => size_res'high,
3666                        right_index    => size_res'low,
3667                        round_style    => round_style,
3668                        overflow_style => overflow_style);
3669      return result;
3670    end if;
3671  end function resize;
3672
3673  function resize (
3674    arg                     : UNRESOLVED_sfixed;  -- input
3675    size_res                : UNRESOLVED_sfixed;  -- for size only
3676    constant overflow_style : fixed_overflow_style_type := fixed_overflow_style;
3677    constant round_style    : fixed_round_style_type    := fixed_round_style)
3678    return UNRESOLVED_sfixed
3679  is
3680    constant fw     : INTEGER := mine (size_res'low, size_res'low);  -- catch literals
3681    variable result : UNRESOLVED_sfixed (size_res'high downto fw);
3682  begin
3683    if (result'length < 1 or arg'length < 1) then
3684      return NASF;
3685    else
3686      result := resize (arg            => arg,
3687                        left_index     => size_res'high,
3688                        right_index    => size_res'low,
3689                        round_style    => round_style,
3690                        overflow_style => overflow_style);
3691      return result;
3692    end if;
3693  end function resize;
3694
3695  -- Overloaded math functions for real
3696  function "+" (
3697    l : UNRESOLVED_ufixed;              -- fixed point input
3698    r : REAL)
3699    return UNRESOLVED_ufixed is
3700  begin
3701    return (l + to_ufixed (r, l'high, l'low));
3702  end function "+";
3703
3704  function "+" (
3705    l : REAL;
3706    r : UNRESOLVED_ufixed)              -- fixed point input
3707    return UNRESOLVED_ufixed is
3708  begin
3709    return (to_ufixed (l, r'high, r'low) + r);
3710  end function "+";
3711
3712  function "+" (
3713    l : UNRESOLVED_sfixed;              -- fixed point input
3714    r : REAL)
3715    return UNRESOLVED_sfixed is
3716  begin
3717    return (l + to_sfixed (r, l'high, l'low));
3718  end function "+";
3719
3720  function "+" (
3721    l : REAL;
3722    r : UNRESOLVED_sfixed)              -- fixed point input
3723    return UNRESOLVED_sfixed is
3724  begin
3725    return (to_sfixed (l, r'high, r'low) + r);
3726  end function "+";
3727
3728  function "-" (
3729    l : UNRESOLVED_ufixed;              -- fixed point input
3730    r : REAL)
3731    return UNRESOLVED_ufixed is
3732  begin
3733    return (l - to_ufixed (r, l'high, l'low));
3734  end function "-";
3735
3736  function "-" (
3737    l : REAL;
3738    r : UNRESOLVED_ufixed)              -- fixed point input
3739    return UNRESOLVED_ufixed is
3740  begin
3741    return (to_ufixed (l, r'high, r'low) - r);
3742  end function "-";
3743
3744  function "-" (
3745    l : UNRESOLVED_sfixed;              -- fixed point input
3746    r : REAL)
3747    return UNRESOLVED_sfixed is
3748  begin
3749    return (l - to_sfixed (r, l'high, l'low));
3750  end function "-";
3751
3752  function "-" (
3753    l : REAL;
3754    r : UNRESOLVED_sfixed)              -- fixed point input
3755    return UNRESOLVED_sfixed is
3756  begin
3757    return (to_sfixed (l, r'high, r'low) - r);
3758  end function "-";
3759
3760  function "*" (
3761    l : UNRESOLVED_ufixed;              -- fixed point input
3762    r : REAL)
3763    return UNRESOLVED_ufixed is
3764  begin
3765    return (l * to_ufixed (r, l'high, l'low));
3766  end function "*";
3767
3768  function "*" (
3769    l : REAL;
3770    r : UNRESOLVED_ufixed)              -- fixed point input
3771    return UNRESOLVED_ufixed is
3772  begin
3773    return (to_ufixed (l, r'high, r'low) * r);
3774  end function "*";
3775
3776  function "*" (
3777    l : UNRESOLVED_sfixed;              -- fixed point input
3778    r : REAL)
3779    return UNRESOLVED_sfixed is
3780  begin
3781    return (l * to_sfixed (r, l'high, l'low));
3782  end function "*";
3783
3784  function "*" (
3785    l : REAL;
3786    r : UNRESOLVED_sfixed)              -- fixed point input
3787    return UNRESOLVED_sfixed is
3788  begin
3789    return (to_sfixed (l, r'high, r'low) * r);
3790  end function "*";
3791
3792  function "/" (
3793    l : UNRESOLVED_ufixed;              -- fixed point input
3794    r : REAL)
3795    return UNRESOLVED_ufixed is
3796  begin
3797    return (l / to_ufixed (r, l'high, l'low));
3798  end function "/";
3799
3800  function "/" (
3801    l : REAL;
3802    r : UNRESOLVED_ufixed)              -- fixed point input
3803    return UNRESOLVED_ufixed is
3804  begin
3805    return (to_ufixed (l, r'high, r'low) / r);
3806  end function "/";
3807
3808  function "/" (
3809    l : UNRESOLVED_sfixed;              -- fixed point input
3810    r : REAL)
3811    return UNRESOLVED_sfixed is
3812  begin
3813    return (l / to_sfixed (r, l'high, l'low));
3814  end function "/";
3815
3816  function "/" (
3817    l : REAL;
3818    r : UNRESOLVED_sfixed)              -- fixed point input
3819    return UNRESOLVED_sfixed is
3820  begin
3821    return (to_sfixed (l, r'high, r'low) / r);
3822  end function "/";
3823
3824  function "rem" (
3825    l : UNRESOLVED_ufixed;              -- fixed point input
3826    r : REAL)
3827    return UNRESOLVED_ufixed is
3828  begin
3829    return (l rem to_ufixed (r, l'high, l'low));
3830  end function "rem";
3831
3832  function "rem" (
3833    l : REAL;
3834    r : UNRESOLVED_ufixed)              -- fixed point input
3835    return UNRESOLVED_ufixed is
3836  begin
3837    return (to_ufixed (l, r'high, r'low) rem r);
3838  end function "rem";
3839
3840  function "rem" (
3841    l : UNRESOLVED_sfixed;              -- fixed point input
3842    r : REAL)
3843    return UNRESOLVED_sfixed is
3844  begin
3845    return (l rem to_sfixed (r, l'high, l'low));
3846  end function "rem";
3847
3848  function "rem" (
3849    l : REAL;
3850    r : UNRESOLVED_sfixed)              -- fixed point input
3851    return UNRESOLVED_sfixed is
3852  begin
3853    return (to_sfixed (l, r'high, r'low) rem r);
3854  end function "rem";
3855
3856  function "mod" (
3857    l : UNRESOLVED_ufixed;              -- fixed point input
3858    r : REAL)
3859    return UNRESOLVED_ufixed is
3860  begin
3861    return (l mod to_ufixed (r, l'high, l'low));
3862  end function "mod";
3863
3864  function "mod" (
3865    l : REAL;
3866    r : UNRESOLVED_ufixed)              -- fixed point input
3867    return UNRESOLVED_ufixed is
3868  begin
3869    return (to_ufixed (l, r'high, r'low) mod r);
3870  end function "mod";
3871
3872  function "mod" (
3873    l : UNRESOLVED_sfixed;              -- fixed point input
3874    r : REAL)
3875    return UNRESOLVED_sfixed is
3876  begin
3877    return (l mod to_sfixed (r, l'high, l'low));
3878  end function "mod";
3879
3880  function "mod" (
3881    l : REAL;
3882    r : UNRESOLVED_sfixed)              -- fixed point input
3883    return UNRESOLVED_sfixed is
3884  begin
3885    return (to_sfixed (l, r'high, r'low) mod r);
3886  end function "mod";
3887
3888  -- Overloaded math functions for integers
3889  function "+" (
3890    l : UNRESOLVED_ufixed;              -- fixed point input
3891    r : NATURAL)
3892    return UNRESOLVED_ufixed is
3893  begin
3894    return (l + to_ufixed (r, l'high, 0));
3895  end function "+";
3896
3897  function "+" (
3898    l : NATURAL;
3899    r : UNRESOLVED_ufixed)              -- fixed point input
3900    return UNRESOLVED_ufixed is
3901  begin
3902    return (to_ufixed (l, r'high, 0) + r);
3903  end function "+";
3904
3905  function "+" (
3906    l : UNRESOLVED_sfixed;              -- fixed point input
3907    r : INTEGER)
3908    return UNRESOLVED_sfixed is
3909  begin
3910    return (l + to_sfixed (r, l'high, 0));
3911  end function "+";
3912
3913  function "+" (
3914    l : INTEGER;
3915    r : UNRESOLVED_sfixed)              -- fixed point input
3916    return UNRESOLVED_sfixed is
3917  begin
3918    return (to_sfixed (l, r'high, 0) + r);
3919  end function "+";
3920
3921  -- Overloaded functions
3922  function "-" (
3923    l : UNRESOLVED_ufixed;              -- fixed point input
3924    r : NATURAL)
3925    return UNRESOLVED_ufixed is
3926  begin
3927    return (l - to_ufixed (r, l'high, 0));
3928  end function "-";
3929
3930  function "-" (
3931    l : NATURAL;
3932    r : UNRESOLVED_ufixed)              -- fixed point input
3933    return UNRESOLVED_ufixed is
3934  begin
3935    return (to_ufixed (l, r'high, 0) - r);
3936  end function "-";
3937
3938  function "-" (
3939    l : UNRESOLVED_sfixed;              -- fixed point input
3940    r : INTEGER)
3941    return UNRESOLVED_sfixed is
3942  begin
3943    return (l - to_sfixed (r, l'high, 0));
3944  end function "-";
3945
3946  function "-" (
3947    l : INTEGER;
3948    r : UNRESOLVED_sfixed)              -- fixed point input
3949    return UNRESOLVED_sfixed is
3950  begin
3951    return (to_sfixed (l, r'high, 0) - r);
3952  end function "-";
3953
3954  -- Overloaded functions
3955  function "*" (
3956    l : UNRESOLVED_ufixed;              -- fixed point input
3957    r : NATURAL)
3958    return UNRESOLVED_ufixed is
3959  begin
3960    return (l * to_ufixed (r, l'high, 0));
3961  end function "*";
3962
3963  function "*" (
3964    l : NATURAL;
3965    r : UNRESOLVED_ufixed)              -- fixed point input
3966    return UNRESOLVED_ufixed is
3967  begin
3968    return (to_ufixed (l, r'high, 0) * r);
3969  end function "*";
3970
3971  function "*" (
3972    l : UNRESOLVED_sfixed;              -- fixed point input
3973    r : INTEGER)
3974    return UNRESOLVED_sfixed is
3975  begin
3976    return (l * to_sfixed (r, l'high, 0));
3977  end function "*";
3978
3979  function "*" (
3980    l : INTEGER;
3981    r : UNRESOLVED_sfixed)              -- fixed point input
3982    return UNRESOLVED_sfixed is
3983  begin
3984    return (to_sfixed (l, r'high, 0) * r);
3985  end function "*";
3986
3987  -- Overloaded functions
3988  function "/" (
3989    l : UNRESOLVED_ufixed;              -- fixed point input
3990    r : NATURAL)
3991    return UNRESOLVED_ufixed is
3992  begin
3993    return (l / to_ufixed (r, l'high, 0));
3994  end function "/";
3995
3996  function "/" (
3997    l : NATURAL;
3998    r : UNRESOLVED_ufixed)              -- fixed point input
3999    return UNRESOLVED_ufixed is
4000  begin
4001    return (to_ufixed (l, r'high, 0) / r);
4002  end function "/";
4003
4004  function "/" (
4005    l : UNRESOLVED_sfixed;              -- fixed point input
4006    r : INTEGER)
4007    return UNRESOLVED_sfixed is
4008  begin
4009    return (l / to_sfixed (r, l'high, 0));
4010  end function "/";
4011
4012  function "/" (
4013    l : INTEGER;
4014    r : UNRESOLVED_sfixed)              -- fixed point input
4015    return UNRESOLVED_sfixed is
4016  begin
4017    return (to_sfixed (l, r'high, 0) / r);
4018  end function "/";
4019
4020  function "rem" (
4021    l : UNRESOLVED_ufixed;              -- fixed point input
4022    r : NATURAL)
4023    return UNRESOLVED_ufixed is
4024  begin
4025    return (l rem to_ufixed (r, l'high, 0));
4026  end function "rem";
4027
4028  function "rem" (
4029    l : NATURAL;
4030    r : UNRESOLVED_ufixed)              -- fixed point input
4031    return UNRESOLVED_ufixed is
4032  begin
4033    return (to_ufixed (l, r'high, 0) rem r);
4034  end function "rem";
4035
4036  function "rem" (
4037    l : UNRESOLVED_sfixed;              -- fixed point input
4038    r : INTEGER)
4039    return UNRESOLVED_sfixed is
4040  begin
4041    return (l rem to_sfixed (r, l'high, 0));
4042  end function "rem";
4043
4044  function "rem" (
4045    l : INTEGER;
4046    r : UNRESOLVED_sfixed)              -- fixed point input
4047    return UNRESOLVED_sfixed is
4048  begin
4049    return (to_sfixed (l, r'high, 0) rem r);
4050  end function "rem";
4051
4052  function "mod" (
4053    l : UNRESOLVED_ufixed;              -- fixed point input
4054    r : NATURAL)
4055    return UNRESOLVED_ufixed is
4056  begin
4057    return (l mod to_ufixed (r, l'high, 0));
4058  end function "mod";
4059
4060  function "mod" (
4061    l : NATURAL;
4062    r : UNRESOLVED_ufixed)              -- fixed point input
4063    return UNRESOLVED_ufixed is
4064  begin
4065    return (to_ufixed (l, r'high, 0) mod r);
4066  end function "mod";
4067
4068  function "mod" (
4069    l : UNRESOLVED_sfixed;              -- fixed point input
4070    r : INTEGER)
4071    return UNRESOLVED_sfixed is
4072  begin
4073    return (l mod to_sfixed (r, l'high, 0));
4074  end function "mod";
4075
4076  function "mod" (
4077    l : INTEGER;
4078    r : UNRESOLVED_sfixed)              -- fixed point input
4079    return UNRESOLVED_sfixed is
4080  begin
4081    return (to_sfixed (l, r'high, 0) mod r);
4082  end function "mod";
4083
4084  -- overloaded ufixed compare functions with integer
4085  function "=" (
4086    l : UNRESOLVED_ufixed;
4087    r : NATURAL)                        -- fixed point input
4088    return BOOLEAN is
4089  begin
4090    return (l = to_ufixed (r, l'high, l'low));
4091  end function "=";
4092
4093  function "/=" (
4094    l : UNRESOLVED_ufixed;
4095    r : NATURAL)                        -- fixed point input
4096    return BOOLEAN is
4097  begin
4098    return (l /= to_ufixed (r, l'high, l'low));
4099  end function "/=";
4100
4101  function ">=" (
4102    l : UNRESOLVED_ufixed;
4103    r : NATURAL)                        -- fixed point input
4104    return BOOLEAN is
4105  begin
4106    return (l >= to_ufixed (r, l'high, l'low));
4107  end function ">=";
4108
4109  function "<=" (
4110    l : UNRESOLVED_ufixed;
4111    r : NATURAL)                        -- fixed point input
4112    return BOOLEAN is
4113  begin
4114    return (l <= to_ufixed (r, l'high, l'low));
4115  end function "<=";
4116
4117  function ">" (
4118    l : UNRESOLVED_ufixed;
4119    r : NATURAL)                        -- fixed point input
4120    return BOOLEAN is
4121  begin
4122    return (l > to_ufixed (r, l'high, l'low));
4123  end function ">";
4124
4125  function "<" (
4126    l : UNRESOLVED_ufixed;
4127    r : NATURAL)                        -- fixed point input
4128    return BOOLEAN is
4129  begin
4130    return (l < to_ufixed (r, l'high, l'low));
4131  end function "<";
4132
4133  function "?=" (
4134    l : UNRESOLVED_ufixed;
4135    r : NATURAL)                        -- fixed point input
4136    return STD_ULOGIC is
4137  begin
4138    return (l ?= to_ufixed (r, l'high, l'low));
4139  end function "?=";
4140
4141  function "?/=" (
4142    l : UNRESOLVED_ufixed;
4143    r : NATURAL)                        -- fixed point input
4144    return STD_ULOGIC is
4145  begin
4146    return (l ?/= to_ufixed (r, l'high, l'low));
4147  end function "?/=";
4148
4149  function "?>=" (
4150    l : UNRESOLVED_ufixed;
4151    r : NATURAL)                        -- fixed point input
4152    return STD_ULOGIC is
4153  begin
4154    return (l ?>= to_ufixed (r, l'high, l'low));
4155  end function "?>=";
4156
4157  function "?<=" (
4158    l : UNRESOLVED_ufixed;
4159    r : NATURAL)                        -- fixed point input
4160    return STD_ULOGIC is
4161  begin
4162    return (l ?<= to_ufixed (r, l'high, l'low));
4163  end function "?<=";
4164
4165  function "?>" (
4166    l : UNRESOLVED_ufixed;
4167    r : NATURAL)                        -- fixed point input
4168    return STD_ULOGIC is
4169  begin
4170    return (l ?> to_ufixed (r, l'high, l'low));
4171  end function "?>";
4172
4173  function "?<" (
4174    l : UNRESOLVED_ufixed;
4175    r : NATURAL)                        -- fixed point input
4176    return STD_ULOGIC is
4177  begin
4178    return (l ?< to_ufixed (r, l'high, l'low));
4179  end function "?<";
4180
4181  function maximum (
4182    l : UNRESOLVED_ufixed;              -- fixed point input
4183    r : NATURAL)
4184    return UNRESOLVED_ufixed is
4185  begin
4186    return maximum (l, to_ufixed (r, l'high, l'low));
4187  end function maximum;
4188
4189  function minimum (
4190    l : UNRESOLVED_ufixed;              -- fixed point input
4191    r : NATURAL)
4192    return UNRESOLVED_ufixed is
4193  begin
4194    return minimum (l, to_ufixed (r, l'high, l'low));
4195  end function minimum;
4196
4197  -- NATURAL to ufixed
4198  function "=" (
4199    l : NATURAL;
4200    r : UNRESOLVED_ufixed)              -- fixed point input
4201    return BOOLEAN is
4202  begin
4203    return (to_ufixed (l, r'high, r'low) = r);
4204  end function "=";
4205
4206  function "/=" (
4207    l : NATURAL;
4208    r : UNRESOLVED_ufixed)              -- fixed point input
4209    return BOOLEAN is
4210  begin
4211    return (to_ufixed (l, r'high, r'low) /= r);
4212  end function "/=";
4213
4214  function ">=" (
4215    l : NATURAL;
4216    r : UNRESOLVED_ufixed)              -- fixed point input
4217    return BOOLEAN is
4218  begin
4219    return (to_ufixed (l, r'high, r'low) >= r);
4220  end function ">=";
4221
4222  function "<=" (
4223    l : NATURAL;
4224    r : UNRESOLVED_ufixed)              -- fixed point input
4225    return BOOLEAN is
4226  begin
4227    return (to_ufixed (l, r'high, r'low) <= r);
4228  end function "<=";
4229
4230  function ">" (
4231    l : NATURAL;
4232    r : UNRESOLVED_ufixed)              -- fixed point input
4233    return BOOLEAN is
4234  begin
4235    return (to_ufixed (l, r'high, r'low) > r);
4236  end function ">";
4237
4238  function "<" (
4239    l : NATURAL;
4240    r : UNRESOLVED_ufixed)              -- fixed point input
4241    return BOOLEAN is
4242  begin
4243    return (to_ufixed (l, r'high, r'low) < r);
4244  end function "<";
4245
4246  function "?=" (
4247    l : NATURAL;
4248    r : UNRESOLVED_ufixed)              -- fixed point input
4249    return STD_ULOGIC is
4250  begin
4251    return (to_ufixed (l, r'high, r'low) ?= r);
4252  end function "?=";
4253
4254  function "?/=" (
4255    l : NATURAL;
4256    r : UNRESOLVED_ufixed)              -- fixed point input
4257    return STD_ULOGIC is
4258  begin
4259    return (to_ufixed (l, r'high, r'low) ?/= r);
4260  end function "?/=";
4261
4262  function "?>=" (
4263    l : NATURAL;
4264    r : UNRESOLVED_ufixed)              -- fixed point input
4265    return STD_ULOGIC is
4266  begin
4267    return (to_ufixed (l, r'high, r'low) ?>= r);
4268  end function "?>=";
4269
4270  function "?<=" (
4271    l : NATURAL;
4272    r : UNRESOLVED_ufixed)              -- fixed point input
4273    return STD_ULOGIC is
4274  begin
4275    return (to_ufixed (l, r'high, r'low) ?<= r);
4276  end function "?<=";
4277
4278  function "?>" (
4279    l : NATURAL;
4280    r : UNRESOLVED_ufixed)              -- fixed point input
4281    return STD_ULOGIC is
4282  begin
4283    return (to_ufixed (l, r'high, r'low) ?> r);
4284  end function "?>";
4285
4286  function "?<" (
4287    l : NATURAL;
4288    r : UNRESOLVED_ufixed)              -- fixed point input
4289    return STD_ULOGIC is
4290  begin
4291    return (to_ufixed (l, r'high, r'low) ?< r);
4292  end function "?<";
4293
4294  function maximum (
4295    l : NATURAL;
4296    r : UNRESOLVED_ufixed)              -- fixed point input
4297    return UNRESOLVED_ufixed is
4298  begin
4299    return maximum (to_ufixed (l, r'high, r'low), r);
4300  end function maximum;
4301
4302  function minimum (
4303    l : NATURAL;
4304    r : UNRESOLVED_ufixed)              -- fixed point input
4305    return UNRESOLVED_ufixed is
4306  begin
4307    return minimum (to_ufixed (l, r'high, r'low), r);
4308  end function minimum;
4309
4310  -- overloaded ufixed compare functions with real
4311  function "=" (
4312    l : UNRESOLVED_ufixed;
4313    r : REAL)
4314    return BOOLEAN is
4315  begin
4316    return (l = to_ufixed (r, l'high, l'low));
4317  end function "=";
4318
4319  function "/=" (
4320    l : UNRESOLVED_ufixed;
4321    r : REAL)
4322    return BOOLEAN is
4323  begin
4324    return (l /= to_ufixed (r, l'high, l'low));
4325  end function "/=";
4326
4327  function ">=" (
4328    l : UNRESOLVED_ufixed;
4329    r : REAL)
4330    return BOOLEAN is
4331  begin
4332    return (l >= to_ufixed (r, l'high, l'low));
4333  end function ">=";
4334
4335  function "<=" (
4336    l : UNRESOLVED_ufixed;
4337    r : REAL)
4338    return BOOLEAN is
4339  begin
4340    return (l <= to_ufixed (r, l'high, l'low));
4341  end function "<=";
4342
4343  function ">" (
4344    l : UNRESOLVED_ufixed;
4345    r : REAL)
4346    return BOOLEAN is
4347  begin
4348    return (l > to_ufixed (r, l'high, l'low));
4349  end function ">";
4350
4351  function "<" (
4352    l : UNRESOLVED_ufixed;
4353    r : REAL)
4354    return BOOLEAN is
4355  begin
4356    return (l < to_ufixed (r, l'high, l'low));
4357  end function "<";
4358
4359  function "?=" (
4360    l : UNRESOLVED_ufixed;
4361    r : REAL)
4362    return STD_ULOGIC is
4363  begin
4364    return (l ?= to_ufixed (r, l'high, l'low));
4365  end function "?=";
4366
4367  function "?/=" (
4368    l : UNRESOLVED_ufixed;
4369    r : REAL)
4370    return STD_ULOGIC is
4371  begin
4372    return (l ?/= to_ufixed (r, l'high, l'low));
4373  end function "?/=";
4374
4375  function "?>=" (
4376    l : UNRESOLVED_ufixed;
4377    r : REAL)
4378    return STD_ULOGIC is
4379  begin
4380    return (l ?>= to_ufixed (r, l'high, l'low));
4381  end function "?>=";
4382
4383  function "?<=" (
4384    l : UNRESOLVED_ufixed;
4385    r : REAL)
4386    return STD_ULOGIC is
4387  begin
4388    return (l ?<= to_ufixed (r, l'high, l'low));
4389  end function "?<=";
4390
4391  function "?>" (
4392    l : UNRESOLVED_ufixed;
4393    r : REAL)
4394    return STD_ULOGIC is
4395  begin
4396    return (l ?> to_ufixed (r, l'high, l'low));
4397  end function "?>";
4398
4399  function "?<" (
4400    l : UNRESOLVED_ufixed;
4401    r : REAL)
4402    return STD_ULOGIC is
4403  begin
4404    return (l ?< to_ufixed (r, l'high, l'low));
4405  end function "?<";
4406
4407  function maximum (
4408    l : UNRESOLVED_ufixed;
4409    r : REAL)
4410    return UNRESOLVED_ufixed is
4411  begin
4412    return maximum (l, to_ufixed (r, l'high, l'low));
4413  end function maximum;
4414
4415  function minimum (
4416    l : UNRESOLVED_ufixed;
4417    r : REAL)
4418    return UNRESOLVED_ufixed is
4419  begin
4420    return minimum (l, to_ufixed (r, l'high, l'low));
4421  end function minimum;
4422
4423  -- real and ufixed
4424  function "=" (
4425    l : REAL;
4426    r : UNRESOLVED_ufixed)              -- fixed point input
4427    return BOOLEAN is
4428  begin
4429    return (to_ufixed (l, r'high, r'low) = r);
4430  end function "=";
4431
4432  function "/=" (
4433    l : REAL;
4434    r : UNRESOLVED_ufixed)              -- fixed point input
4435    return BOOLEAN is
4436  begin
4437    return (to_ufixed (l, r'high, r'low) /= r);
4438  end function "/=";
4439
4440  function ">=" (
4441    l : REAL;
4442    r : UNRESOLVED_ufixed)              -- fixed point input
4443    return BOOLEAN is
4444  begin
4445    return (to_ufixed (l, r'high, r'low) >= r);
4446  end function ">=";
4447
4448  function "<=" (
4449    l : REAL;
4450    r : UNRESOLVED_ufixed)              -- fixed point input
4451    return BOOLEAN is
4452  begin
4453    return (to_ufixed (l, r'high, r'low) <= r);
4454  end function "<=";
4455
4456  function ">" (
4457    l : REAL;
4458    r : UNRESOLVED_ufixed)              -- fixed point input
4459    return BOOLEAN is
4460  begin
4461    return (to_ufixed (l, r'high, r'low) > r);
4462  end function ">";
4463
4464  function "<" (
4465    l : REAL;
4466    r : UNRESOLVED_ufixed)              -- fixed point input
4467    return BOOLEAN is
4468  begin
4469    return (to_ufixed (l, r'high, r'low) < r);
4470  end function "<";
4471
4472  function "?=" (
4473    l : REAL;
4474    r : UNRESOLVED_ufixed)              -- fixed point input
4475    return STD_ULOGIC is
4476  begin
4477    return (to_ufixed (l, r'high, r'low) ?= r);
4478  end function "?=";
4479
4480  function "?/=" (
4481    l : REAL;
4482    r : UNRESOLVED_ufixed)              -- fixed point input
4483    return STD_ULOGIC is
4484  begin
4485    return (to_ufixed (l, r'high, r'low) ?/= r);
4486  end function "?/=";
4487
4488  function "?>=" (
4489    l : REAL;
4490    r : UNRESOLVED_ufixed)              -- fixed point input
4491    return STD_ULOGIC is
4492  begin
4493    return (to_ufixed (l, r'high, r'low) ?>= r);
4494  end function "?>=";
4495
4496  function "?<=" (
4497    l : REAL;
4498    r : UNRESOLVED_ufixed)              -- fixed point input
4499    return STD_ULOGIC is
4500  begin
4501    return (to_ufixed (l, r'high, r'low) ?<= r);
4502  end function "?<=";
4503
4504  function "?>" (
4505    l : REAL;
4506    r : UNRESOLVED_ufixed)              -- fixed point input
4507    return STD_ULOGIC is
4508  begin
4509    return (to_ufixed (l, r'high, r'low) ?> r);
4510  end function "?>";
4511
4512  function "?<" (
4513    l : REAL;
4514    r : UNRESOLVED_ufixed)              -- fixed point input
4515    return STD_ULOGIC is
4516  begin
4517    return (to_ufixed (l, r'high, r'low) ?< r);
4518  end function "?<";
4519
4520  function maximum (
4521    l : REAL;
4522    r : UNRESOLVED_ufixed)              -- fixed point input
4523    return UNRESOLVED_ufixed is
4524  begin
4525    return maximum (to_ufixed (l, r'high, r'low), r);
4526  end function maximum;
4527
4528  function minimum (
4529    l : REAL;
4530    r : UNRESOLVED_ufixed)              -- fixed point input
4531    return UNRESOLVED_ufixed is
4532  begin
4533    return minimum (to_ufixed (l, r'high, r'low), r);
4534  end function minimum;
4535
4536  -- overloaded sfixed compare functions with integer
4537  function "=" (
4538    l : UNRESOLVED_sfixed;
4539    r : INTEGER)
4540    return BOOLEAN is
4541  begin
4542    return (l = to_sfixed (r, l'high, l'low));
4543  end function "=";
4544
4545  function "/=" (
4546    l : UNRESOLVED_sfixed;
4547    r : INTEGER)
4548    return BOOLEAN is
4549  begin
4550    return (l /= to_sfixed (r, l'high, l'low));
4551  end function "/=";
4552
4553  function ">=" (
4554    l : UNRESOLVED_sfixed;
4555    r : INTEGER)
4556    return BOOLEAN is
4557  begin
4558    return (l >= to_sfixed (r, l'high, l'low));
4559  end function ">=";
4560
4561  function "<=" (
4562    l : UNRESOLVED_sfixed;
4563    r : INTEGER)
4564    return BOOLEAN is
4565  begin
4566    return (l <= to_sfixed (r, l'high, l'low));
4567  end function "<=";
4568
4569  function ">" (
4570    l : UNRESOLVED_sfixed;
4571    r : INTEGER)
4572    return BOOLEAN is
4573  begin
4574    return (l > to_sfixed (r, l'high, l'low));
4575  end function ">";
4576
4577  function "<" (
4578    l : UNRESOLVED_sfixed;
4579    r : INTEGER)
4580    return BOOLEAN is
4581  begin
4582    return (l < to_sfixed (r, l'high, l'low));
4583  end function "<";
4584
4585  function "?=" (
4586    l : UNRESOLVED_sfixed;
4587    r : INTEGER)
4588    return STD_ULOGIC is
4589  begin
4590    return (l ?= to_sfixed (r, l'high, l'low));
4591  end function "?=";
4592
4593  function "?/=" (
4594    l : UNRESOLVED_sfixed;
4595    r : INTEGER)
4596    return STD_ULOGIC is
4597  begin
4598    return (l ?/= to_sfixed (r, l'high, l'low));
4599  end function "?/=";
4600
4601  function "?>=" (
4602    l : UNRESOLVED_sfixed;
4603    r : INTEGER)
4604    return STD_ULOGIC is
4605  begin
4606    return (l ?>= to_sfixed (r, l'high, l'low));
4607  end function "?>=";
4608
4609  function "?<=" (
4610    l : UNRESOLVED_sfixed;
4611    r : INTEGER)
4612    return STD_ULOGIC is
4613  begin
4614    return (l ?<= to_sfixed (r, l'high, l'low));
4615  end function "?<=";
4616
4617  function "?>" (
4618    l : UNRESOLVED_sfixed;
4619    r : INTEGER)
4620    return STD_ULOGIC is
4621  begin
4622    return (l ?> to_sfixed (r, l'high, l'low));
4623  end function "?>";
4624
4625  function "?<" (
4626    l : UNRESOLVED_sfixed;
4627    r : INTEGER)
4628    return STD_ULOGIC is
4629  begin
4630    return (l ?< to_sfixed (r, l'high, l'low));
4631  end function "?<";
4632
4633  function maximum (
4634    l : UNRESOLVED_sfixed;
4635    r : INTEGER)
4636    return UNRESOLVED_sfixed is
4637  begin
4638    return maximum (l, to_sfixed (r, l'high, l'low));
4639  end function maximum;
4640
4641  function minimum (
4642    l : UNRESOLVED_sfixed;
4643    r : INTEGER)
4644    return UNRESOLVED_sfixed is
4645  begin
4646    return minimum (l, to_sfixed (r, l'high, l'low));
4647  end function minimum;
4648
4649  -- integer and sfixed
4650  function "=" (
4651    l : INTEGER;
4652    r : UNRESOLVED_sfixed)              -- fixed point input
4653    return BOOLEAN is
4654  begin
4655    return (to_sfixed (l, r'high, r'low) = r);
4656  end function "=";
4657
4658  function "/=" (
4659    l : INTEGER;
4660    r : UNRESOLVED_sfixed)              -- fixed point input
4661    return BOOLEAN is
4662  begin
4663    return (to_sfixed (l, r'high, r'low) /= r);
4664  end function "/=";
4665
4666  function ">=" (
4667    l : INTEGER;
4668    r : UNRESOLVED_sfixed)              -- fixed point input
4669    return BOOLEAN is
4670  begin
4671    return (to_sfixed (l, r'high, r'low) >= r);
4672  end function ">=";
4673
4674  function "<=" (
4675    l : INTEGER;
4676    r : UNRESOLVED_sfixed)              -- fixed point input
4677    return BOOLEAN is
4678  begin
4679    return (to_sfixed (l, r'high, r'low) <= r);
4680  end function "<=";
4681
4682  function ">" (
4683    l : INTEGER;
4684    r : UNRESOLVED_sfixed)              -- fixed point input
4685    return BOOLEAN is
4686  begin
4687    return (to_sfixed (l, r'high, r'low) > r);
4688  end function ">";
4689
4690  function "<" (
4691    l : INTEGER;
4692    r : UNRESOLVED_sfixed)              -- fixed point input
4693    return BOOLEAN is
4694  begin
4695    return (to_sfixed (l, r'high, r'low) < r);
4696  end function "<";
4697
4698  function "?=" (
4699    l : INTEGER;
4700    r : UNRESOLVED_sfixed)              -- fixed point input
4701    return STD_ULOGIC is
4702  begin
4703    return (to_sfixed (l, r'high, r'low) ?= r);
4704  end function "?=";
4705
4706  function "?/=" (
4707    l : INTEGER;
4708    r : UNRESOLVED_sfixed)              -- fixed point input
4709    return STD_ULOGIC is
4710  begin
4711    return (to_sfixed (l, r'high, r'low) ?/= r);
4712  end function "?/=";
4713
4714  function "?>=" (
4715    l : INTEGER;
4716    r : UNRESOLVED_sfixed)              -- fixed point input
4717    return STD_ULOGIC is
4718  begin
4719    return (to_sfixed (l, r'high, r'low) ?>= r);
4720  end function "?>=";
4721
4722  function "?<=" (
4723    l : INTEGER;
4724    r : UNRESOLVED_sfixed)              -- fixed point input
4725    return STD_ULOGIC is
4726  begin
4727    return (to_sfixed (l, r'high, r'low) ?<= r);
4728  end function "?<=";
4729
4730  function "?>" (
4731    l : INTEGER;
4732    r : UNRESOLVED_sfixed)              -- fixed point input
4733    return STD_ULOGIC is
4734  begin
4735    return (to_sfixed (l, r'high, r'low) ?> r);
4736  end function "?>";
4737
4738  function "?<" (
4739    l : INTEGER;
4740    r : UNRESOLVED_sfixed)              -- fixed point input
4741    return STD_ULOGIC is
4742  begin
4743    return (to_sfixed (l, r'high, r'low) ?< r);
4744  end function "?<";
4745
4746  function maximum (
4747    l : INTEGER;
4748    r : UNRESOLVED_sfixed)
4749    return UNRESOLVED_sfixed is
4750  begin
4751    return maximum (to_sfixed (l, r'high, r'low), r);
4752  end function maximum;
4753
4754  function minimum (
4755    l : INTEGER;
4756    r : UNRESOLVED_sfixed)
4757    return UNRESOLVED_sfixed is
4758  begin
4759    return minimum (to_sfixed (l, r'high, r'low), r);
4760  end function minimum;
4761
4762  -- overloaded sfixed compare functions with real
4763  function "=" (
4764    l : UNRESOLVED_sfixed;
4765    r : REAL)
4766    return BOOLEAN is
4767  begin
4768    return (l = to_sfixed (r, l'high, l'low));
4769  end function "=";
4770
4771  function "/=" (
4772    l : UNRESOLVED_sfixed;
4773    r : REAL)
4774    return BOOLEAN is
4775  begin
4776    return (l /= to_sfixed (r, l'high, l'low));
4777  end function "/=";
4778
4779  function ">=" (
4780    l : UNRESOLVED_sfixed;
4781    r : REAL)
4782    return BOOLEAN is
4783  begin
4784    return (l >= to_sfixed (r, l'high, l'low));
4785  end function ">=";
4786
4787  function "<=" (
4788    l : UNRESOLVED_sfixed;
4789    r : REAL)
4790    return BOOLEAN is
4791  begin
4792    return (l <= to_sfixed (r, l'high, l'low));
4793  end function "<=";
4794
4795  function ">" (
4796    l : UNRESOLVED_sfixed;
4797    r : REAL)
4798    return BOOLEAN is
4799  begin
4800    return (l > to_sfixed (r, l'high, l'low));
4801  end function ">";
4802
4803  function "<" (
4804    l : UNRESOLVED_sfixed;
4805    r : REAL)
4806    return BOOLEAN is
4807  begin
4808    return (l < to_sfixed (r, l'high, l'low));
4809  end function "<";
4810
4811  function "?=" (
4812    l : UNRESOLVED_sfixed;
4813    r : REAL)
4814    return STD_ULOGIC is
4815  begin
4816    return (l ?= to_sfixed (r, l'high, l'low));
4817  end function "?=";
4818
4819  function "?/=" (
4820    l : UNRESOLVED_sfixed;
4821    r : REAL)
4822    return STD_ULOGIC is
4823  begin
4824    return (l ?/= to_sfixed (r, l'high, l'low));
4825  end function "?/=";
4826
4827  function "?>=" (
4828    l : UNRESOLVED_sfixed;
4829    r : REAL)
4830    return STD_ULOGIC is
4831  begin
4832    return (l ?>= to_sfixed (r, l'high, l'low));
4833  end function "?>=";
4834
4835  function "?<=" (
4836    l : UNRESOLVED_sfixed;
4837    r : REAL)
4838    return STD_ULOGIC is
4839  begin
4840    return (l ?<= to_sfixed (r, l'high, l'low));
4841  end function "?<=";
4842
4843  function "?>" (
4844    l : UNRESOLVED_sfixed;
4845    r : REAL)
4846    return STD_ULOGIC is
4847  begin
4848    return (l ?> to_sfixed (r, l'high, l'low));
4849  end function "?>";
4850
4851  function "?<" (
4852    l : UNRESOLVED_sfixed;
4853    r : REAL)
4854    return STD_ULOGIC is
4855  begin
4856    return (l ?< to_sfixed (r, l'high, l'low));
4857  end function "?<";
4858
4859  function maximum (
4860    l : UNRESOLVED_sfixed;
4861    r : REAL)
4862    return UNRESOLVED_sfixed is
4863  begin
4864    return maximum (l, to_sfixed (r, l'high, l'low));
4865  end function maximum;
4866
4867  function minimum (
4868    l : UNRESOLVED_sfixed;
4869    r : REAL)
4870    return UNRESOLVED_sfixed is
4871  begin
4872    return minimum (l, to_sfixed (r, l'high, l'low));
4873  end function minimum;
4874
4875  -- REAL and sfixed
4876  function "=" (
4877    l : REAL;
4878    r : UNRESOLVED_sfixed)              -- fixed point input
4879    return BOOLEAN is
4880  begin
4881    return (to_sfixed (l, r'high, r'low) = r);
4882  end function "=";
4883
4884  function "/=" (
4885    l : REAL;
4886    r : UNRESOLVED_sfixed)              -- fixed point input
4887    return BOOLEAN is
4888  begin
4889    return (to_sfixed (l, r'high, r'low) /= r);
4890  end function "/=";
4891
4892  function ">=" (
4893    l : REAL;
4894    r : UNRESOLVED_sfixed)              -- fixed point input
4895    return BOOLEAN is
4896  begin
4897    return (to_sfixed (l, r'high, r'low) >= r);
4898  end function ">=";
4899
4900  function "<=" (
4901    l : REAL;
4902    r : UNRESOLVED_sfixed)              -- fixed point input
4903    return BOOLEAN is
4904  begin
4905    return (to_sfixed (l, r'high, r'low) <= r);
4906  end function "<=";
4907
4908  function ">" (
4909    l : REAL;
4910    r : UNRESOLVED_sfixed)              -- fixed point input
4911    return BOOLEAN is
4912  begin
4913    return (to_sfixed (l, r'high, r'low) > r);
4914  end function ">";
4915
4916  function "<" (
4917    l : REAL;
4918    r : UNRESOLVED_sfixed)              -- fixed point input
4919    return BOOLEAN is
4920  begin
4921    return (to_sfixed (l, r'high, r'low) < r);
4922  end function "<";
4923
4924  function "?=" (
4925    l : REAL;
4926    r : UNRESOLVED_sfixed)              -- fixed point input
4927    return STD_ULOGIC is
4928  begin
4929    return (to_sfixed (l, r'high, r'low) ?= r);
4930  end function "?=";
4931
4932  function "?/=" (
4933    l : REAL;
4934    r : UNRESOLVED_sfixed)              -- fixed point input
4935    return STD_ULOGIC is
4936  begin
4937    return (to_sfixed (l, r'high, r'low) ?/= r);
4938  end function "?/=";
4939
4940  function "?>=" (
4941    l : REAL;
4942    r : UNRESOLVED_sfixed)              -- fixed point input
4943    return STD_ULOGIC is
4944  begin
4945    return (to_sfixed (l, r'high, r'low) ?>= r);
4946  end function "?>=";
4947
4948  function "?<=" (
4949    l : REAL;
4950    r : UNRESOLVED_sfixed)              -- fixed point input
4951    return STD_ULOGIC is
4952  begin
4953    return (to_sfixed (l, r'high, r'low) ?<= r);
4954  end function "?<=";
4955
4956  function "?>" (
4957    l : REAL;
4958    r : UNRESOLVED_sfixed)              -- fixed point input
4959    return STD_ULOGIC is
4960  begin
4961    return (to_sfixed (l, r'high, r'low) ?> r);
4962  end function "?>";
4963
4964  function "?<" (
4965    l : REAL;
4966    r : UNRESOLVED_sfixed)              -- fixed point input
4967    return STD_ULOGIC is
4968  begin
4969    return (to_sfixed (l, r'high, r'low) ?< r);
4970  end function "?<";
4971
4972  function maximum (
4973    l : REAL;
4974    r : UNRESOLVED_sfixed)
4975    return UNRESOLVED_sfixed is
4976  begin
4977    return maximum (to_sfixed (l, r'high, r'low), r);
4978  end function maximum;
4979
4980  function minimum (
4981    l : REAL;
4982    r : UNRESOLVED_sfixed)
4983    return UNRESOLVED_sfixed is
4984  begin
4985    return minimum (to_sfixed (l, r'high, r'low), r);
4986  end function minimum;
4987
4988  -- copied from std_logic_textio
4989  type MVL9plus is ('U', 'X', '0', '1', 'Z', 'W', 'L', 'H', '-', error);
4990  type char_indexed_by_MVL9 is array (STD_ULOGIC) of CHARACTER;
4991  type MVL9_indexed_by_char is array (CHARACTER) of STD_ULOGIC;
4992  type MVL9plus_indexed_by_char is array (CHARACTER) of MVL9plus;
4993
4994  constant MVL9_to_char : char_indexed_by_MVL9 := "UX01ZWLH-";
4995  constant char_to_MVL9 : MVL9_indexed_by_char :=
4996    ('U' => 'U', 'X' => 'X', '0' => '0', '1' => '1', 'Z' => 'Z',
4997     'W' => 'W', 'L' => 'L', 'H' => 'H', '-' => '-', others => 'U');
4998  constant char_to_MVL9plus : MVL9plus_indexed_by_char :=
4999    ('U' => 'U', 'X' => 'X', '0' => '0', '1' => '1', 'Z' => 'Z',
5000     'W' => 'W', 'L' => 'L', 'H' => 'H', '-' => '-', others => error);
5001  constant NBSP : CHARACTER      := CHARACTER'val(160);  -- space character
5002  constant NUS  : STRING(2 to 1) := (others => ' ');
5003
5004  -- purpose: Skips white space
5005  procedure skip_whitespace (
5006    L : inout LINE) is
5007    variable c : CHARACTER;
5008    variable left : positive;
5009  begin
5010    while L /= null and L.all'length /= 0 loop
5011      left := L.all'left;
5012      c := L.all(left);
5013      if (c = ' ' or c = NBSP or c = HT) then
5014        read (L, c);
5015      else
5016        exit;
5017      end if;
5018    end loop;
5019  end procedure skip_whitespace;
5020
5021  -- purpose: writes fixed point into a line
5022  procedure write (
5023    L         : inout LINE;               -- input line
5024    VALUE     : in    UNRESOLVED_ufixed;  -- fixed point input
5025    JUSTIFIED : in    SIDE  := right;
5026    FIELD     : in    WIDTH := 0) is
5027    variable s     : STRING(1 to VALUE'length +1) := (others => ' ');
5028    variable sindx : INTEGER;
5029  begin  -- function write   Example: 0011.1100
5030    sindx := 1;
5031    for i in VALUE'high downto VALUE'low loop
5032      if i = -1 then
5033        s(sindx) := '.';
5034        sindx    := sindx + 1;
5035      end if;
5036      s(sindx) := MVL9_to_char(STD_ULOGIC(VALUE(i)));
5037      sindx    := sindx + 1;
5038    end loop;
5039    write(L, s, JUSTIFIED, FIELD);
5040  end procedure write;
5041
5042  -- purpose: writes fixed point into a line
5043  procedure write (
5044    L         : inout LINE;               -- input line
5045    VALUE     : in    UNRESOLVED_sfixed;  -- fixed point input
5046    JUSTIFIED : in    SIDE  := right;
5047    FIELD     : in    WIDTH := 0) is
5048    variable s     : STRING(1 to VALUE'length +1);
5049    variable sindx : INTEGER;
5050  begin  -- function write   Example: 0011.1100
5051    sindx := 1;
5052    for i in VALUE'high downto VALUE'low loop
5053      if i = -1 then
5054        s(sindx) := '.';
5055        sindx    := sindx + 1;
5056      end if;
5057      s(sindx) := MVL9_to_char(STD_ULOGIC(VALUE(i)));
5058      sindx    := sindx + 1;
5059    end loop;
5060    write(L, s, JUSTIFIED, FIELD);
5061  end procedure write;
5062
5063  procedure READ(L     : inout LINE;
5064                 VALUE : out   UNRESOLVED_ufixed) is
5065    -- Possible data:  00000.0000000
5066    --                 000000000000
5067    variable c      : CHARACTER;
5068    variable readOk : BOOLEAN;
5069    variable i      : INTEGER;          -- index variable
5070    variable mv : ufixed (VALUE'range);
5071    variable lastu  : BOOLEAN := false;       -- last character was an "_"
5072    variable founddot : BOOLEAN := false;  -- found a "."
5073  begin  -- READ
5074    VALUE := (VALUE'range => 'U');
5075    skip_whitespace (L);
5076    if VALUE'length > 0 then            -- non Null input string
5077      read (L, c, readOk);
5078      i := VALUE'high;
5079      while i >= VALUE'low loop
5080        if readOk = false then              -- Bail out if there was a bad read
5081          report fixed_generic_pkg'instance_name & "READ(ufixed) "
5082            & "End of string encountered"
5083            severity error;
5084          return;
5085        elsif c = '_' then
5086          if i = VALUE'high then
5087            report fixed_generic_pkg'instance_name & "READ(ufixed) "
5088              & "String begins with an ""_""" severity error;
5089            return;
5090          elsif lastu then
5091            report fixed_generic_pkg'instance_name & "READ(ufixed) "
5092              & "Two underscores detected in input string ""__"""
5093              severity error;
5094            return;
5095          else
5096            lastu := true;
5097          end if;
5098        elsif c = '.' then                -- binary point
5099          if founddot then
5100            report fixed_generic_pkg'instance_name & "READ(ufixed) "
5101              & "Two binary points found in input string" severity error;
5102            return;
5103          elsif i /= -1 then                 -- Seperator in the wrong spot
5104            report fixed_generic_pkg'instance_name & "READ(ufixed) "
5105              & "Decimal point does not match number format "
5106              severity error;
5107            return;
5108          end if;
5109          founddot := true;
5110          lastu := false;
5111        elsif c = ' ' or c = NBSP or c = HT then  -- reading done.
5112          report fixed_generic_pkg'instance_name & "READ(ufixed) "
5113            & "Short read, Space encounted in input string"
5114            severity error;
5115          return;
5116        elsif char_to_MVL9plus(c) = error then
5117          report fixed_generic_pkg'instance_name & "READ(ufixed) "
5118            & "Character '" &
5119            c & "' read, expected STD_ULOGIC literal."
5120            severity error;
5121          return;
5122        else
5123          mv(i) := char_to_MVL9(c);
5124          i := i - 1;
5125          if i < mv'low then
5126            VALUE := mv;
5127            return;
5128          end if;
5129          lastu := false;
5130        end if;
5131        read(L, c, readOk);
5132      end loop;
5133    end if;
5134  end procedure READ;
5135
5136  procedure READ(L     : inout LINE;
5137                 VALUE : out   UNRESOLVED_ufixed;
5138                 GOOD  : out   BOOLEAN) is
5139    -- Possible data:  00000.0000000
5140    --                 000000000000
5141    variable c      : CHARACTER;
5142    variable readOk : BOOLEAN;
5143    variable mv : ufixed (VALUE'range);
5144    variable i      : INTEGER;          -- index variable
5145    variable lastu  : BOOLEAN := false;       -- last character was an "_"
5146    variable founddot : BOOLEAN := false;  -- found a "."
5147  begin  -- READ
5148    VALUE := (VALUE'range => 'U');
5149    skip_whitespace (L);
5150    if VALUE'length > 0 then
5151      read (L, c, readOk);
5152      i := VALUE'high;
5153      GOOD := false;
5154      while i >= VALUE'low loop
5155        if not readOk then     -- Bail out if there was a bad read
5156          return;
5157        elsif c = '_' then
5158          if i = VALUE'high then          -- Begins with an "_"
5159            return;
5160          elsif lastu then               -- "__" detected
5161            return;
5162          else
5163            lastu := true;
5164          end if;
5165        elsif c = '.' then                -- binary point
5166          if founddot then
5167            return;
5168          elsif i /= -1 then                 -- Seperator in the wrong spot
5169            return;
5170          end if;
5171          founddot := true;
5172          lastu := false;
5173        elsif (char_to_MVL9plus(c) = error) then   -- Illegal character/short read
5174          return;
5175        else
5176          mv(i) := char_to_MVL9(c);
5177          i := i - 1;
5178          if i < mv'low then             -- reading done
5179            GOOD := true;
5180            VALUE := mv;
5181            return;
5182          end if;
5183          lastu := false;
5184        end if;
5185        read(L, c, readOk);
5186      end loop;
5187    else
5188      GOOD := true;                   -- read into a null array
5189    end if;
5190  end procedure READ;
5191
5192  procedure READ(L     : inout LINE;
5193                 VALUE : out   UNRESOLVED_sfixed) is
5194    variable c      : CHARACTER;
5195    variable readOk : BOOLEAN;
5196    variable i      : INTEGER;          -- index variable
5197    variable mv : sfixed (VALUE'range);
5198    variable lastu  : BOOLEAN := false;       -- last character was an "_"
5199    variable founddot : BOOLEAN := false;  -- found a "."
5200  begin  -- READ
5201    VALUE := (VALUE'range => 'U');
5202    skip_whitespace (L);
5203    if VALUE'length > 0 then            -- non Null input string
5204      read (L, c, readOk);
5205      i := VALUE'high;
5206      while i >= VALUE'low loop
5207        if readOk = false then              -- Bail out if there was a bad read
5208          report fixed_generic_pkg'instance_name & "READ(sfixed) "
5209            & "End of string encountered"
5210            severity error;
5211          return;
5212        elsif c = '_' then
5213          if i = VALUE'high then
5214            report fixed_generic_pkg'instance_name & "READ(sfixed) "
5215              & "String begins with an ""_""" severity error;
5216            return;
5217          elsif lastu then
5218            report fixed_generic_pkg'instance_name & "READ(sfixed) "
5219              & "Two underscores detected in input string ""__"""
5220              severity error;
5221            return;
5222          else
5223            lastu := true;
5224          end if;
5225        elsif c = '.' then                -- binary point
5226          if founddot then
5227            report fixed_generic_pkg'instance_name & "READ(sfixed) "
5228              & "Two binary points found in input string" severity error;
5229            return;
5230          elsif i /= -1 then                 -- Seperator in the wrong spot
5231            report fixed_generic_pkg'instance_name & "READ(sfixed) "
5232              & "Decimal point does not match number format "
5233              severity error;
5234            return;
5235          end if;
5236          founddot := true;
5237          lastu := false;
5238        elsif c = ' ' or c = NBSP or c = HT then  -- reading done.
5239          report fixed_generic_pkg'instance_name & "READ(sfixed) "
5240            & "Short read, Space encounted in input string"
5241            severity error;
5242          return;
5243        elsif char_to_MVL9plus(c) = error then
5244          report fixed_generic_pkg'instance_name & "READ(sfixed) "
5245            & "Character '" &
5246            c & "' read, expected STD_ULOGIC literal."
5247            severity error;
5248          return;
5249        else
5250          mv(i) := char_to_MVL9(c);
5251          i := i - 1;
5252          if i < mv'low then
5253            VALUE := mv;
5254            return;
5255          end if;
5256          lastu := false;
5257        end if;
5258        read(L, c, readOk);
5259      end loop;
5260    end if;
5261  end procedure READ;
5262
5263  procedure READ(L     : inout LINE;
5264                 VALUE : out   UNRESOLVED_sfixed;
5265                 GOOD  : out   BOOLEAN) is
5266    variable value_ufixed : UNRESOLVED_ufixed (VALUE'range);
5267  begin  -- READ
5268    READ (L => L, VALUE => value_ufixed, GOOD => GOOD);
5269    VALUE := UNRESOLVED_sfixed (value_ufixed);
5270  end procedure READ;
5271
5272  -- octal read and write
5273  procedure owrite (
5274    L         : inout LINE;               -- input line
5275    VALUE     : in    UNRESOLVED_ufixed;  -- fixed point input
5276    JUSTIFIED : in    SIDE  := right;
5277    FIELD     : in    WIDTH := 0) is
5278  begin  -- Example 03.30
5279    write (L         => L,
5280           VALUE     => TO_OSTRING (VALUE),
5281           JUSTIFIED => JUSTIFIED,
5282           FIELD     => FIELD);
5283  end procedure owrite;
5284
5285  procedure owrite (
5286    L         : inout LINE;               -- input line
5287    VALUE     : in    UNRESOLVED_sfixed;  -- fixed point input
5288    JUSTIFIED : in    SIDE  := right;
5289    FIELD     : in    WIDTH := 0) is
5290  begin  -- Example 03.30
5291    write (L         => L,
5292           VALUE     => TO_OSTRING (VALUE),
5293           JUSTIFIED => JUSTIFIED,
5294           FIELD     => FIELD);
5295  end procedure owrite;
5296
5297  -- Note that for Octal and Hex read, you can not start with a ".",
5298  -- the read is for numbers formatted "A.BC".  These routines go to
5299  -- the nearest bounds, so "F.E" will fit into an sfixed (2 downto -3).
5300  procedure Char2TriBits (C           :     CHARACTER;
5301                          RESULT      : out STD_ULOGIC_VECTOR(2 downto 0);
5302                          GOOD        : out BOOLEAN;
5303                          ISSUE_ERROR : in  BOOLEAN) is
5304  begin
5305    case C is
5306      when '0' => RESULT := o"0"; GOOD := true;
5307      when '1' => RESULT := o"1"; GOOD := true;
5308      when '2' => RESULT := o"2"; GOOD := true;
5309      when '3' => RESULT := o"3"; GOOD := true;
5310      when '4' => RESULT := o"4"; GOOD := true;
5311      when '5' => RESULT := o"5"; GOOD := true;
5312      when '6' => RESULT := o"6"; GOOD := true;
5313      when '7' => RESULT := o"7"; GOOD := true;
5314      when 'Z' => RESULT := "ZZZ"; GOOD := true;
5315      when 'X' => RESULT := "XXX"; GOOD := true;
5316      when others =>
5317        assert not ISSUE_ERROR
5318          report fixed_generic_pkg'instance_name
5319          & "OREAD Error: Read a '" & C &
5320          "', expected an Octal character (0-7)."
5321          severity error;
5322        RESULT := "UUU";
5323        GOOD   := false;
5324    end case;
5325  end procedure Char2TriBits;
5326
5327  -- purpose: Routines common to the OREAD routines
5328  procedure OREAD_common (
5329    L                : inout LINE;
5330    slv              : out   STD_ULOGIC_VECTOR;
5331    igood            : out   BOOLEAN;
5332    idex             : out INTEGER;
5333    constant bpoint : in INTEGER;       -- binary point
5334    constant message : in    BOOLEAN;
5335    constant smath   : in    BOOLEAN) is
5336
5337    -- purpose: error message routine
5338    procedure errmes (
5339      constant mess : in STRING) is     -- error message
5340    begin
5341      if message then
5342        if smath then
5343          report fixed_generic_pkg'instance_name
5344            & "OREAD(sfixed) "
5345            & mess
5346            severity error;
5347        else
5348          report fixed_generic_pkg'instance_name
5349            & "OREAD(ufixed) "
5350            & mess
5351            severity error;
5352        end if;
5353      end if;
5354    end procedure errmes;
5355    variable xgood : BOOLEAN;
5356    variable nybble : STD_ULOGIC_VECTOR (2 downto 0);        -- 3 bits
5357    variable c : CHARACTER;
5358    variable i : INTEGER;
5359    variable lastu  : BOOLEAN := false;       -- last character was an "_"
5360    variable founddot : BOOLEAN := false;  -- found a dot.
5361  begin
5362    skip_whitespace (L);
5363    if slv'length > 0 then
5364      i := slv'high;
5365      read (L, c, xgood);
5366      while i > 0 loop
5367        if xgood = false then
5368          errmes ("Error: end of string encountered");
5369          exit;
5370        elsif c = '_' then
5371          if i = slv'length then
5372            errmes ("Error: String begins with an ""_""");
5373            xgood := false;
5374            exit;
5375          elsif lastu then
5376            errmes ("Error: Two underscores detected in input string ""__""");
5377            xgood := false;
5378            exit;
5379          else
5380            lastu := true;
5381          end if;
5382        elsif (c = '.') then
5383          if (i + 1 /= bpoint) then
5384            errmes ("encountered ""."" at wrong index");
5385            xgood := false;
5386            exit;
5387          elsif i = slv'length then
5388            errmes ("encounted a ""."" at the beginning of the line");
5389            xgood := false;
5390            exit;
5391          elsif founddot then
5392            errmes ("Two ""."" encounted in input string");
5393            xgood := false;
5394            exit;
5395          end if;
5396          founddot := true;
5397          lastu := false;
5398        else
5399          Char2TriBits(c, nybble, xgood, message);
5400          if not xgood then
5401            exit;
5402          end if;
5403          slv (i downto i-2) := nybble;
5404          i := i - 3;
5405          lastu := false;
5406        end if;
5407        if i > 0 then
5408          read (L, c, xgood);
5409        end if;
5410      end loop;
5411      idex := i;
5412      igood := xgood;
5413    else
5414      igood := true;                  -- read into a null array
5415      idex := -1;
5416    end if;
5417  end procedure OREAD_common;
5418
5419  -- Note that for Octal and Hex read, you can not start with a ".",
5420  -- the read is for numbers formatted "A.BC".  These routines go to
5421  -- the nearest bounds, so "F.E" will fit into an sfixed (2 downto -3).
5422  procedure OREAD (L     : inout LINE;
5423                   VALUE : out   UNRESOLVED_ufixed) is
5424    constant hbv    : INTEGER := (((maximum(3, (VALUE'high+1))+2)/3)*3)-1;
5425    constant lbv    : INTEGER := ((mine(0, VALUE'low)-2)/3)*3;
5426    variable slv    : STD_ULOGIC_VECTOR (hbv-lbv downto 0);  -- high bits
5427    variable valuex : UNRESOLVED_ufixed (hbv downto lbv);
5428    variable igood  : BOOLEAN;
5429    variable i      : INTEGER;
5430  begin
5431    VALUE := (VALUE'range => 'U');
5432    OREAD_common ( L => L,
5433                   slv => slv,
5434                   igood => igood,
5435                   idex => i,
5436                   bpoint => -lbv,
5437                   message => true,
5438                   smath => false);
5439    if igood then                       -- We did not get another error
5440      if not ((i = -1) and               -- We read everything, and high bits 0
5441              (or (slv(hbv-lbv downto VALUE'high+1-lbv)) = '0')) then
5442        report fixed_generic_pkg'instance_name
5443          & "OREAD(ufixed): Vector truncated."
5444          severity error;
5445      else
5446        if (or (slv(VALUE'low-lbv-1 downto 0)) = '1') then
5447          assert no_warning
5448            report fixed_generic_pkg'instance_name
5449            & "OREAD(ufixed): Vector truncated"
5450            severity warning;
5451        end if;
5452        valuex := to_ufixed (slv, hbv, lbv);
5453        VALUE  := valuex (VALUE'range);
5454      end if;
5455    end if;
5456  end procedure OREAD;
5457
5458  procedure OREAD(L     : inout LINE;
5459                  VALUE : out   UNRESOLVED_ufixed;
5460                  GOOD  : out   BOOLEAN) is
5461    constant hbv    : INTEGER := (((maximum(3, (VALUE'high+1))+2)/3)*3)-1;
5462    constant lbv    : INTEGER := ((mine(0, VALUE'low)-2)/3)*3;
5463    variable slv    : STD_ULOGIC_VECTOR (hbv-lbv downto 0);  -- high bits
5464    variable valuex : UNRESOLVED_ufixed (hbv downto lbv);
5465    variable igood  : BOOLEAN;
5466    variable i      : INTEGER;
5467  begin
5468    VALUE := (VALUE'range => 'U');
5469    OREAD_common ( L => L,
5470                   slv => slv,
5471                   igood => igood,
5472                   idex => i,
5473                   bpoint => -lbv,
5474                   message => false,
5475                   smath => false);
5476    if (igood and                   -- We did not get another error
5477        (i = -1) and                -- We read everything, and high bits 0
5478        (or (slv(hbv-lbv downto VALUE'high+1-lbv)) = '0')) then
5479      valuex := to_ufixed (slv, hbv, lbv);
5480      VALUE  := valuex (VALUE'range);
5481      GOOD := true;
5482    else
5483      GOOD := false;
5484    end if;
5485  end procedure OREAD;
5486
5487  procedure OREAD(L     : inout LINE;
5488                  VALUE : out   UNRESOLVED_sfixed) is
5489    constant hbv    : INTEGER := (((maximum(3, (VALUE'high+1))+2)/3)*3)-1;
5490    constant lbv    : INTEGER := ((mine(0, VALUE'low)-2)/3)*3;
5491    variable slv    : STD_ULOGIC_VECTOR (hbv-lbv downto 0);  -- high bits
5492    variable valuex : UNRESOLVED_sfixed (hbv downto lbv);
5493    variable igood  : BOOLEAN;
5494    variable i      : INTEGER;
5495  begin
5496    VALUE := (VALUE'range => 'U');
5497    OREAD_common ( L => L,
5498                   slv => slv,
5499                   igood => igood,
5500                   idex => i,
5501                   bpoint => -lbv,
5502                   message => true,
5503                   smath => true);
5504    if igood then                       -- We did not get another error
5505      if not ((i = -1) and               -- We read everything
5506              ((slv(VALUE'high-lbv) = '0' and      -- sign bits = extra bits
5507                or (slv(hbv-lbv downto VALUE'high+1-lbv)) = '0') or
5508               (slv(VALUE'high-lbv) = '1' and
5509                and (slv(hbv-lbv downto VALUE'high+1-lbv)) = '1'))) then
5510        report fixed_generic_pkg'instance_name
5511          & "OREAD(sfixed): Vector truncated."
5512          severity error;
5513      else
5514        if (or (slv(VALUE'low-lbv-1 downto 0)) = '1') then
5515          assert no_warning
5516            report fixed_generic_pkg'instance_name
5517            & "OREAD(sfixed): Vector truncated"
5518            severity warning;
5519        end if;
5520        valuex := to_sfixed (slv, hbv, lbv);
5521        VALUE  := valuex (VALUE'range);
5522      end if;
5523    end if;
5524  end procedure OREAD;
5525
5526  procedure OREAD(L     : inout LINE;
5527                  VALUE : out   UNRESOLVED_sfixed;
5528                  GOOD  : out   BOOLEAN) is
5529    constant hbv    : INTEGER := (((maximum(3, (VALUE'high+1))+2)/3)*3)-1;
5530    constant lbv    : INTEGER := ((mine(0, VALUE'low)-2)/3)*3;
5531    variable slv    : STD_ULOGIC_VECTOR (hbv-lbv downto 0);  -- high bits
5532    variable valuex : UNRESOLVED_sfixed (hbv downto lbv);
5533    variable igood  : BOOLEAN;
5534    variable i      : INTEGER;
5535  begin
5536    VALUE := (VALUE'range => 'U');
5537    OREAD_common ( L => L,
5538                   slv => slv,
5539                   igood => igood,
5540                   idex => i,
5541                   bpoint => -lbv,
5542                   message => false,
5543                   smath => true);
5544    if (igood                       -- We did not get another error
5545        and (i = -1)                -- We read everything
5546        and ((slv(VALUE'high-lbv) = '0' and  -- sign bits = extra bits
5547              or (slv(hbv-lbv downto VALUE'high+1-lbv)) = '0') or
5548             (slv(VALUE'high-lbv) = '1' and
5549              and (slv(hbv-lbv downto VALUE'high+1-lbv)) = '1'))) then
5550      valuex := to_sfixed (slv, hbv, lbv);
5551      VALUE  := valuex (VALUE'range);
5552      GOOD := true;
5553    else
5554      GOOD := false;
5555    end if;
5556  end procedure OREAD;
5557
5558  -- hex read and write
5559  procedure hwrite (
5560    L         : inout LINE;               -- input line
5561    VALUE     : in    UNRESOLVED_ufixed;  -- fixed point input
5562    JUSTIFIED : in    SIDE  := right;
5563    FIELD     : in    WIDTH := 0) is
5564  begin  -- Example 03.30
5565    write (L         => L,
5566           VALUE     => TO_HSTRING (VALUE),
5567           JUSTIFIED => JUSTIFIED,
5568           FIELD     => FIELD);
5569  end procedure hwrite;
5570
5571  -- purpose: writes fixed point into a line
5572  procedure hwrite (
5573    L         : inout LINE;               -- input line
5574    VALUE     : in    UNRESOLVED_sfixed;  -- fixed point input
5575    JUSTIFIED : in    SIDE  := right;
5576    FIELD     : in    WIDTH := 0) is
5577  begin  -- Example 03.30
5578    write (L         => L,
5579           VALUE     => TO_HSTRING (VALUE),
5580           JUSTIFIED => JUSTIFIED,
5581           FIELD     => FIELD);
5582  end procedure hwrite;
5583
5584  -- Hex Read and Write procedures for STD_ULOGIC_VECTOR.
5585  -- Modified from the original to be more forgiving.
5586
5587  procedure Char2QuadBits (C           :     CHARACTER;
5588                           RESULT      : out STD_ULOGIC_VECTOR(3 downto 0);
5589                           GOOD        : out BOOLEAN;
5590                           ISSUE_ERROR : in  BOOLEAN) is
5591  begin
5592    case C is
5593      when '0'       => RESULT := x"0"; GOOD := true;
5594      when '1'       => RESULT := x"1"; GOOD := true;
5595      when '2'       => RESULT := x"2"; GOOD := true;
5596      when '3'       => RESULT := x"3"; GOOD := true;
5597      when '4'       => RESULT := x"4"; GOOD := true;
5598      when '5'       => RESULT := x"5"; GOOD := true;
5599      when '6'       => RESULT := x"6"; GOOD := true;
5600      when '7'       => RESULT := x"7"; GOOD := true;
5601      when '8'       => RESULT := x"8"; GOOD := true;
5602      when '9'       => RESULT := x"9"; GOOD := true;
5603      when 'A' | 'a' => RESULT := x"A"; GOOD := true;
5604      when 'B' | 'b' => RESULT := x"B"; GOOD := true;
5605      when 'C' | 'c' => RESULT := x"C"; GOOD := true;
5606      when 'D' | 'd' => RESULT := x"D"; GOOD := true;
5607      when 'E' | 'e' => RESULT := x"E"; GOOD := true;
5608      when 'F' | 'f' => RESULT := x"F"; GOOD := true;
5609      when 'Z'       => RESULT := "ZZZZ"; GOOD := true;
5610      when 'X'       => RESULT := "XXXX"; GOOD := true;
5611      when others =>
5612        assert not ISSUE_ERROR
5613          report fixed_generic_pkg'instance_name
5614          & "HREAD Error: Read a '" & C &
5615          "', expected a Hex character (0-F)."
5616          severity error;
5617        RESULT := "UUUU";
5618        GOOD   := false;
5619    end case;
5620  end procedure Char2QuadBits;
5621
5622  -- purpose: Routines common to the HREAD routines
5623  procedure HREAD_common (
5624    L                : inout LINE;
5625    slv              : out   STD_ULOGIC_VECTOR;
5626    igood            : out   BOOLEAN;
5627    idex             : out INTEGER;
5628    constant bpoint : in INTEGER;       -- binary point
5629    constant message : in    BOOLEAN;
5630    constant smath   : in    BOOLEAN) is
5631
5632    -- purpose: error message routine
5633    procedure errmes (
5634      constant mess : in STRING) is     -- error message
5635    begin
5636      if message then
5637        if smath then
5638          report fixed_generic_pkg'instance_name
5639            & "HREAD(sfixed) "
5640            & mess
5641            severity error;
5642        else
5643          report fixed_generic_pkg'instance_name
5644            & "HREAD(ufixed) "
5645            & mess
5646            severity error;
5647        end if;
5648      end if;
5649    end procedure errmes;
5650    variable xgood  : BOOLEAN;
5651    variable nybble : STD_ULOGIC_VECTOR (3 downto 0);        -- 4 bits
5652    variable c      : CHARACTER;
5653    variable i      : INTEGER;
5654    variable lastu  : BOOLEAN := false;       -- last character was an "_"
5655    variable founddot : BOOLEAN := false;  -- found a dot.
5656  begin
5657    skip_whitespace (L);
5658    if slv'length > 0 then
5659      i := slv'high;
5660      read (L, c, xgood);
5661      while i > 0 loop
5662        if xgood = false then
5663          errmes ("Error: end of string encountered");
5664          exit;
5665        elsif c = '_' then
5666          if i = slv'length then
5667            errmes ("Error: String begins with an ""_""");
5668            xgood := false;
5669            exit;
5670          elsif lastu then
5671            errmes ("Error: Two underscores detected in input string ""__""");
5672            xgood := false;
5673            exit;
5674          else
5675            lastu := true;
5676          end if;
5677        elsif (c = '.') then
5678          if (i + 1 /= bpoint) then
5679            errmes ("encountered ""."" at wrong index");
5680            xgood := false;
5681            exit;
5682          elsif i = slv'length then
5683            errmes ("encounted a ""."" at the beginning of the line");
5684            xgood := false;
5685            exit;
5686          elsif founddot then
5687            errmes ("Two ""."" encounted in input string");
5688            xgood := false;
5689            exit;
5690          end if;
5691          founddot := true;
5692          lastu := false;
5693        else
5694          Char2QuadBits(c, nybble, xgood, message);
5695          if not xgood then
5696            exit;
5697          end if;
5698          slv (i downto i-3) := nybble;
5699          i := i - 4;
5700          lastu := false;
5701        end if;
5702        if i > 0 then
5703          read (L, c, xgood);
5704        end if;
5705      end loop;
5706      idex := i;
5707      igood := xgood;
5708    else
5709      idex := -1;
5710      igood := true;                    -- read null string
5711    end if;
5712  end procedure HREAD_common;
5713
5714  procedure HREAD(L     : inout LINE;
5715                  VALUE : out   UNRESOLVED_ufixed) is
5716    constant hbv    : INTEGER := (((maximum(4, (VALUE'high+1))+3)/4)*4)-1;
5717    constant lbv    : INTEGER := ((mine(0, VALUE'low)-3)/4)*4;
5718    variable slv    : STD_ULOGIC_VECTOR (hbv-lbv downto 0);  -- high bits
5719    variable valuex : UNRESOLVED_ufixed (hbv downto lbv);
5720    variable igood  : BOOLEAN;
5721    variable i      : INTEGER;
5722  begin
5723    VALUE := (VALUE'range => 'U');
5724    HREAD_common ( L => L,
5725                   slv => slv,
5726                   igood => igood,
5727                   idex => i,
5728                   bpoint => -lbv,
5729                   message => true,
5730                   smath => false);
5731    if igood then
5732      if not ((i = -1) and               -- We read everything, and high bits 0
5733              (or (slv(hbv-lbv downto VALUE'high+1-lbv)) = '0')) then
5734        report fixed_generic_pkg'instance_name
5735          & "HREAD(ufixed): Vector truncated."
5736          severity error;
5737      else
5738        if (or (slv(VALUE'low-lbv-1 downto 0)) = '1') then
5739          assert no_warning
5740            report fixed_generic_pkg'instance_name
5741            & "HREAD(ufixed): Vector truncated"
5742            severity warning;
5743        end if;
5744        valuex := to_ufixed (slv, hbv, lbv);
5745        VALUE  := valuex (VALUE'range);
5746      end if;
5747    end if;
5748  end procedure HREAD;
5749
5750  procedure HREAD(L     : inout LINE;
5751                  VALUE : out   UNRESOLVED_ufixed;
5752                  GOOD  : out   BOOLEAN) is
5753    constant hbv    : INTEGER := (((maximum(4, (VALUE'high+1))+3)/4)*4)-1;
5754    constant lbv    : INTEGER := ((mine(0, VALUE'low)-3)/4)*4;
5755    variable slv    : STD_ULOGIC_VECTOR (hbv-lbv downto 0);  -- high bits
5756    variable valuex : UNRESOLVED_ufixed (hbv downto lbv);
5757    variable igood  : BOOLEAN;
5758    variable i      : INTEGER;
5759  begin
5760    VALUE := (VALUE'range => 'U');
5761    HREAD_common ( L => L,
5762                   slv => slv,
5763                   igood => igood,
5764                   idex => i,
5765                   bpoint => -lbv,
5766                   message => false,
5767                   smath => false);
5768    if (igood and                   -- We did not get another error
5769        (i = -1) and                -- We read everything, and high bits 0
5770        (or (slv(hbv-lbv downto VALUE'high+1-lbv)) = '0')) then
5771      valuex := to_ufixed (slv, hbv, lbv);
5772      VALUE  := valuex (VALUE'range);
5773      GOOD := true;
5774    else
5775      GOOD := false;
5776    end if;
5777  end procedure HREAD;
5778
5779  procedure HREAD(L     : inout LINE;
5780                  VALUE : out   UNRESOLVED_sfixed) is
5781    constant hbv    : INTEGER := (((maximum(4, (VALUE'high+1))+3)/4)*4)-1;
5782    constant lbv    : INTEGER := ((mine(0, VALUE'low)-3)/4)*4;
5783    variable slv    : STD_ULOGIC_VECTOR (hbv-lbv downto 0);  -- high bits
5784    variable valuex : UNRESOLVED_sfixed (hbv downto lbv);
5785    variable igood  : BOOLEAN;
5786    variable i      : INTEGER;
5787  begin
5788    VALUE := (VALUE'range => 'U');
5789    HREAD_common ( L => L,
5790                   slv => slv,
5791                   igood => igood,
5792                   idex => i,
5793                   bpoint => -lbv,
5794                   message => true,
5795                   smath => true);
5796    if igood then                       -- We did not get another error
5797      if not ((i = -1)                   -- We read everything
5798              and ((slv(VALUE'high-lbv) = '0' and  -- sign bits = extra bits
5799                    or (slv(hbv-lbv downto VALUE'high+1-lbv)) = '0') or
5800                   (slv(VALUE'high-lbv) = '1' and
5801                    and (slv(hbv-lbv downto VALUE'high+1-lbv)) = '1'))) then
5802        report fixed_generic_pkg'instance_name
5803          & "HREAD(sfixed): Vector truncated."
5804          severity error;
5805      else
5806        if (or (slv(VALUE'low-lbv-1 downto 0)) = '1') then
5807          assert no_warning
5808            report fixed_generic_pkg'instance_name
5809            & "HREAD(sfixed): Vector truncated"
5810            severity warning;
5811        end if;
5812        valuex := to_sfixed (slv, hbv, lbv);
5813        VALUE  := valuex (VALUE'range);
5814      end if;
5815    end if;
5816  end procedure HREAD;
5817
5818  procedure HREAD(L     : inout LINE;
5819                  VALUE : out   UNRESOLVED_sfixed;
5820                  GOOD  : out   BOOLEAN) is
5821    constant hbv    : INTEGER := (((maximum(4, (VALUE'high+1))+3)/4)*4)-1;
5822    constant lbv    : INTEGER := ((mine(0, VALUE'low)-3)/4)*4;
5823    variable slv    : STD_ULOGIC_VECTOR (hbv-lbv downto 0);  -- high bits
5824    variable valuex : UNRESOLVED_sfixed (hbv downto lbv);
5825    variable igood  : BOOLEAN;
5826    variable i      : INTEGER;
5827  begin
5828    VALUE := (VALUE'range => 'U');
5829    HREAD_common ( L => L,
5830                   slv => slv,
5831                   igood => igood,
5832                   idex => i,
5833                   bpoint => -lbv,
5834                   message => false,
5835                   smath => true);
5836    if (igood and                   -- We did not get another error
5837        (i = -1) and                -- We read everything
5838        ((slv(VALUE'high-lbv) = '0' and  -- sign bits = extra bits
5839          or (slv(hbv-lbv downto VALUE'high+1-lbv)) = '0') or
5840         (slv(VALUE'high-lbv) = '1' and
5841          and (slv(hbv-lbv downto VALUE'high+1-lbv)) = '1'))) then
5842      valuex := to_sfixed (slv, hbv, lbv);
5843      VALUE  := valuex (VALUE'range);
5844      GOOD := true;
5845    else
5846      GOOD := false;
5847    end if;
5848  end procedure HREAD;
5849
5850  -- TO_STRING functions.  Useful in "report" statements.
5851  -- Example:  report "result was " & TO_STRING(result);
5852  function TO_STRING (value : UNRESOLVED_ufixed) return STRING is
5853    variable s     : STRING(1 to value'length +1) := (others => ' ');
5854    variable subval : UNRESOLVED_ufixed (value'high downto -1);
5855    variable sindx : INTEGER;
5856  begin
5857    if value'length < 1 then
5858      return NUS;
5859    else
5860      if value'high < 0 then
5861        if value(value'high) = 'Z' then
5862          return TO_STRING (resize (sfixed(value), 0, value'low));
5863        else
5864          return TO_STRING (resize (value, 0, value'low));
5865        end if;
5866      elsif value'low >= 0 then
5867        if Is_X (value(value'low)) then
5868          subval := (others => value(value'low));
5869          subval (value'range) := value;
5870          return TO_STRING(subval);
5871        else
5872          return TO_STRING (resize (value, value'high, -1));
5873        end if;
5874      else
5875        sindx := 1;
5876        for i in value'high downto value'low loop
5877          if i = -1 then
5878            s(sindx) := '.';
5879            sindx    := sindx + 1;
5880          end if;
5881          s(sindx) := MVL9_to_char(STD_ULOGIC(value(i)));
5882          sindx    := sindx + 1;
5883        end loop;
5884        return s;
5885      end if;
5886    end if;
5887  end function TO_STRING;
5888
5889  function TO_STRING (value : UNRESOLVED_sfixed) return STRING is
5890    variable s     : STRING(1 to value'length + 1) := (others => ' ');
5891    variable subval : UNRESOLVED_sfixed (value'high downto -1);
5892    variable sindx : INTEGER;
5893  begin
5894    if value'length < 1 then
5895      return NUS;
5896    else
5897      if value'high < 0 then
5898        return TO_STRING (resize (value, 0, value'low));
5899      elsif value'low >= 0 then
5900        if Is_X (value(value'low)) then
5901          subval := (others => value(value'low));
5902          subval (value'range) := value;
5903          return TO_STRING(subval);
5904        else
5905          return TO_STRING (resize (value, value'high, -1));
5906        end if;
5907      else
5908        sindx := 1;
5909        for i in value'high downto value'low loop
5910          if i = -1 then
5911            s(sindx) := '.';
5912            sindx    := sindx + 1;
5913          end if;
5914          s(sindx) := MVL9_to_char(STD_ULOGIC(value(i)));
5915          sindx    := sindx + 1;
5916        end loop;
5917        return s;
5918      end if;
5919    end if;
5920  end function TO_STRING;
5921
5922  function TO_OSTRING (value : UNRESOLVED_ufixed) return STRING is
5923    constant lne  : INTEGER := (-value'low+2)/3;
5924    variable subval : UNRESOLVED_ufixed (value'high downto -3);
5925    variable lpad : STD_ULOGIC_VECTOR (0 to (lne*3 + value'low) -1);
5926    variable slv : STD_ULOGIC_VECTOR (value'length-1 downto 0);
5927  begin
5928    if value'length < 1 then
5929      return NUS;
5930    else
5931      if value'high < 0 then
5932        if value(value'high) = 'Z' then
5933          return TO_OSTRING (resize (sfixed(value), 2, value'low));
5934        else
5935          return TO_OSTRING (resize (value, 2, value'low));
5936        end if;
5937      elsif value'low >= 0 then
5938        if Is_X (value(value'low)) then
5939          subval := (others => value(value'low));
5940          subval (value'range) := value;
5941          return TO_OSTRING(subval);
5942        else
5943          return TO_OSTRING (resize (value, value'high, -3));
5944        end if;
5945      else
5946        slv := to_sulv (value);
5947        if Is_X (value (value'low)) then
5948          lpad := (others => value (value'low));
5949        else
5950          lpad := (others => '0');
5951        end if;
5952        return TO_OSTRING(slv(slv'high downto slv'high-value'high))
5953          & "."
5954          & TO_OSTRING(slv(slv'high-value'high-1 downto 0) & lpad);
5955      end if;
5956    end if;
5957  end function TO_OSTRING;
5958
5959  function TO_HSTRING (value : UNRESOLVED_ufixed) return STRING is
5960    constant lne  : INTEGER := (-value'low+3)/4;
5961    variable subval : UNRESOLVED_ufixed (value'high downto -4);
5962    variable lpad : STD_ULOGIC_VECTOR (0 to (lne*4 + value'low) -1);
5963    variable slv : STD_ULOGIC_VECTOR (value'length-1 downto 0);
5964  begin
5965    if value'length < 1 then
5966      return NUS;
5967    else
5968      if value'high < 0 then
5969        if value(value'high) = 'Z' then
5970          return TO_HSTRING (resize (sfixed(value), 3, value'low));
5971        else
5972          return TO_HSTRING (resize (value, 3, value'low));
5973        end if;
5974      elsif value'low >= 0 then
5975        if Is_X (value(value'low)) then
5976          subval := (others => value(value'low));
5977          subval (value'range) := value;
5978          return TO_HSTRING(subval);
5979        else
5980          return TO_HSTRING (resize (value, value'high, -4));
5981        end if;
5982      else
5983        slv := to_sulv (value);
5984        if Is_X (value (value'low)) then
5985          lpad := (others => value(value'low));
5986        else
5987          lpad := (others => '0');
5988        end if;
5989        return TO_HSTRING(slv(slv'high downto slv'high-value'high))
5990          & "."
5991          & TO_HSTRING(slv(slv'high-value'high-1 downto 0)&lpad);
5992      end if;
5993    end if;
5994  end function TO_HSTRING;
5995
5996  function TO_OSTRING (value : UNRESOLVED_sfixed) return STRING is
5997    constant ne   : INTEGER := ((value'high+1)+2)/3;
5998    variable pad  : STD_ULOGIC_VECTOR(0 to (ne*3 - (value'high+1)) - 1);
5999    constant lne  : INTEGER := (-value'low+2)/3;
6000    variable subval : UNRESOLVED_sfixed (value'high downto -3);
6001    variable lpad : STD_ULOGIC_VECTOR (0 to (lne*3 + value'low) -1);
6002    variable slv  : STD_ULOGIC_VECTOR (value'high - value'low downto 0);
6003  begin
6004    if value'length < 1 then
6005      return NUS;
6006    else
6007      if value'high < 0 then
6008        return TO_OSTRING (resize (value, 2, value'low));
6009      elsif value'low >= 0 then
6010        if Is_X (value(value'low)) then
6011          subval := (others => value(value'low));
6012          subval (value'range) := value;
6013          return TO_OSTRING(subval);
6014        else
6015          return TO_OSTRING (resize (value, value'high, -3));
6016        end if;
6017      else
6018        pad := (others => value(value'high));
6019        slv := to_sulv (value);
6020        if Is_X (value (value'low)) then
6021          lpad := (others => value(value'low));
6022        else
6023          lpad := (others => '0');
6024        end if;
6025        return TO_OSTRING(pad & slv(slv'high downto slv'high-value'high))
6026          & "."
6027          & TO_OSTRING(slv(slv'high-value'high-1 downto 0) & lpad);
6028      end if;
6029    end if;
6030  end function TO_OSTRING;
6031
6032  function TO_HSTRING (value : UNRESOLVED_sfixed) return STRING is
6033    constant ne   : INTEGER := ((value'high+1)+3)/4;
6034    variable pad  : STD_ULOGIC_VECTOR(0 to (ne*4 - (value'high+1)) - 1);
6035    constant lne  : INTEGER := (-value'low+3)/4;
6036    variable subval : UNRESOLVED_sfixed (value'high downto -4);
6037    variable lpad : STD_ULOGIC_VECTOR (0 to (lne*4 + value'low) -1);
6038    variable slv  : STD_ULOGIC_VECTOR (value'length-1 downto 0);
6039  begin
6040    if value'length < 1 then
6041      return NUS;
6042    else
6043      if value'high < 0 then
6044        return TO_HSTRING (resize (value, 3, value'low));
6045      elsif value'low >= 0 then
6046        if Is_X (value(value'low)) then
6047          subval := (others => value(value'low));
6048          subval (value'range) := value;
6049          return TO_HSTRING(subval);
6050        else
6051          return TO_HSTRING (resize (value, value'high, -4));
6052        end if;
6053      else
6054        slv := to_sulv (value);
6055        pad := (others => value(value'high));
6056        if Is_X (value (value'low)) then
6057          lpad := (others => value(value'low));
6058        else
6059          lpad := (others => '0');
6060        end if;
6061        return TO_HSTRING(pad & slv(slv'high downto slv'high-value'high))
6062          & "."
6063          & TO_HSTRING(slv(slv'high-value'high-1 downto 0) & lpad);
6064      end if;
6065    end if;
6066  end function TO_HSTRING;
6067
6068  -- From string functions allow you to convert a string into a fixed
6069  -- point number.  Example:
6070  --  signal uf1 : ufixed (3 downto -3);
6071  --  uf1 <= from_string ("0110.100", uf1'high, uf1'low); -- 6.5
6072  -- The "." is optional in this syntax, however it exist and is
6073  -- in the wrong location an error is produced.  Overflow will
6074  -- result in saturation.
6075  function from_string (
6076    bstring              : STRING;      -- binary string
6077    constant left_index  : INTEGER;
6078    constant right_index : INTEGER)
6079    return UNRESOLVED_ufixed
6080  is
6081    variable result : UNRESOLVED_ufixed (left_index downto right_index);
6082    variable L      : LINE;
6083    variable good   : BOOLEAN;
6084  begin
6085    L := new STRING'(bstring);
6086    READ (L, result, good);
6087    deallocate (L);
6088    assert (good)
6089      report fixed_generic_pkg'instance_name
6090      & "from_string: Bad string "& bstring severity error;
6091    return result;
6092  end function from_string;
6093
6094  -- Octal and hex conversions work as follows:
6095  -- uf1 <= from_hstring ("6.8", 3, -3); -- 6.5 (bottom zeros dropped)
6096  -- uf1 <= from_ostring ("06.4", 3, -3); -- 6.5 (top zeros dropped)
6097  function from_ostring (
6098    ostring              : STRING;      -- Octal string
6099    constant left_index  : INTEGER;
6100    constant right_index : INTEGER)
6101    return UNRESOLVED_ufixed
6102  is
6103    variable result : UNRESOLVED_ufixed (left_index downto right_index);
6104    variable L      : LINE;
6105    variable good   : BOOLEAN;
6106  begin
6107    L := new STRING'(ostring);
6108    OREAD (L, result, good);
6109    deallocate (L);
6110    assert (good)
6111      report fixed_generic_pkg'instance_name
6112      & "from_ostring: Bad string "& ostring severity error;
6113    return result;
6114  end function from_ostring;
6115
6116  function from_hstring (
6117    hstring              : STRING;      -- hex string
6118    constant left_index  : INTEGER;
6119    constant right_index : INTEGER)
6120    return UNRESOLVED_ufixed
6121  is
6122    variable result : UNRESOLVED_ufixed (left_index downto right_index);
6123    variable L      : LINE;
6124    variable good   : BOOLEAN;
6125  begin
6126    L := new STRING'(hstring);
6127    HREAD (L, result, good);
6128    deallocate (L);
6129    assert (good)
6130      report fixed_generic_pkg'instance_name
6131      & "from_hstring: Bad string "& hstring severity error;
6132    return result;
6133  end function from_hstring;
6134
6135  function from_string (
6136    bstring              : STRING;      -- binary string
6137    constant left_index  : INTEGER;
6138    constant right_index : INTEGER)
6139    return UNRESOLVED_sfixed
6140  is
6141    variable result : UNRESOLVED_sfixed (left_index downto right_index);
6142    variable L      : LINE;
6143    variable good   : BOOLEAN;
6144  begin
6145    L := new STRING'(bstring);
6146    READ (L, result, good);
6147    deallocate (L);
6148    assert (good)
6149      report fixed_generic_pkg'instance_name
6150      & "from_string: Bad string "& bstring severity error;
6151    return result;
6152  end function from_string;
6153
6154  function from_ostring (
6155    ostring              : STRING;      -- Octal string
6156    constant left_index  : INTEGER;
6157    constant right_index : INTEGER)
6158    return UNRESOLVED_sfixed
6159  is
6160    variable result : UNRESOLVED_sfixed (left_index downto right_index);
6161    variable L      : LINE;
6162    variable good   : BOOLEAN;
6163  begin
6164    L := new STRING'(ostring);
6165    OREAD (L, result, good);
6166    deallocate (L);
6167    assert (good)
6168      report fixed_generic_pkg'instance_name
6169      & "from_ostring: Bad string "& ostring severity error;
6170    return result;
6171  end function from_ostring;
6172
6173  function from_hstring (
6174    hstring              : STRING;      -- hex string
6175    constant left_index  : INTEGER;
6176    constant right_index : INTEGER)
6177    return UNRESOLVED_sfixed
6178  is
6179    variable result : UNRESOLVED_sfixed (left_index downto right_index);
6180    variable L      : LINE;
6181    variable good   : BOOLEAN;
6182  begin
6183    L := new STRING'(hstring);
6184    HREAD (L, result, good);
6185    deallocate (L);
6186    assert (good)
6187      report fixed_generic_pkg'instance_name
6188      & "from_hstring: Bad string "& hstring severity error;
6189    return result;
6190  end function from_hstring;
6191
6192  -- Same as above, "size_res" is used for it's range only.
6193 function from_string (
6194    bstring  : STRING;                  -- binary string
6195    size_res : UNRESOLVED_ufixed)
6196    return UNRESOLVED_ufixed is
6197  begin
6198    return from_string (bstring, size_res'high, size_res'low);
6199  end function from_string;
6200
6201  function from_ostring (
6202    ostring  : STRING;                  -- Octal string
6203    size_res : UNRESOLVED_ufixed)
6204    return UNRESOLVED_ufixed is
6205  begin
6206    return from_ostring (ostring, size_res'high, size_res'low);
6207  end function from_ostring;
6208
6209  function from_hstring (
6210    hstring  : STRING;                  -- hex string
6211    size_res : UNRESOLVED_ufixed)
6212    return UNRESOLVED_ufixed is
6213  begin
6214    return from_hstring(hstring, size_res'high, size_res'low);
6215  end function from_hstring;
6216
6217  function from_string (
6218    bstring  : STRING;                  -- binary string
6219    size_res : UNRESOLVED_sfixed)
6220    return UNRESOLVED_sfixed is
6221  begin
6222    return from_string (bstring, size_res'high, size_res'low);
6223  end function from_string;
6224
6225  function from_ostring (
6226    ostring  : STRING;                  -- Octal string
6227    size_res : UNRESOLVED_sfixed)
6228    return UNRESOLVED_sfixed is
6229  begin
6230    return from_ostring (ostring, size_res'high, size_res'low);
6231  end function from_ostring;
6232
6233  function from_hstring (
6234    hstring  : STRING;                  -- hex string
6235    size_res : UNRESOLVED_sfixed)
6236    return UNRESOLVED_sfixed is
6237  begin
6238    return from_hstring (hstring, size_res'high, size_res'low);
6239  end function from_hstring;
6240
6241  -- Direct conversion functions.  Example:
6242  --  signal uf1 : ufixed (3 downto -3);
6243  --  uf1 <= from_string ("0110.100"); -- 6.5
6244  -- In this case the "." is not optional, and the size of
6245  -- the output must match exactly.
6246  -- purpose: Calculate the string boundaries
6247  procedure calculate_string_boundry (
6248    arg         : in  STRING;           -- input string
6249    left_index  : out INTEGER;          -- left
6250    right_index : out INTEGER) is       -- right
6251    -- examples "10001.111" would return +4, -3
6252    -- "07X.44" would return +2, -2 (then the octal routine would multiply)
6253    -- "A_B_._C" would return +1, -1 (then the hex routine would multiply)
6254    alias xarg : STRING (arg'length downto 1) is arg;  -- make it downto range
6255    variable l, r : INTEGER;            -- internal indexes
6256    variable founddot : BOOLEAN := false;
6257  begin
6258    if arg'length > 0 then
6259      l := xarg'high - 1;
6260      r := 0;
6261      for i in xarg'range loop
6262        if xarg(i) = '_' then
6263          if r = 0 then
6264            l := l - 1;
6265          else
6266            r := r + 1;
6267          end if;
6268        elsif xarg(i) = ' ' or xarg(i) = NBSP or xarg(i) = HT then
6269          report fixed_generic_pkg'instance_name
6270            & "Found a space in the input STRING " & xarg
6271            severity error;
6272        elsif xarg(i) = '.' then
6273          if founddot then
6274            report fixed_generic_pkg'instance_name
6275              & "Found two binary points in input string " & xarg
6276              severity error;
6277          else
6278            l := l - i;
6279            r := -i + 1;
6280            founddot := true;
6281          end if;
6282        end if;
6283      end loop;
6284      left_index := l;
6285      right_index := r;
6286    else
6287      left_index := 0;
6288      right_index := 0;
6289    end if;
6290  end procedure calculate_string_boundry;
6291
6292  -- Direct conversion functions.  Example:
6293  --  signal uf1 : ufixed (3 downto -3);
6294  --  uf1 <= from_string ("0110.100"); -- 6.5
6295  -- In this case the "." is not optional, and the size of
6296  -- the output must match exactly.
6297  function from_string (
6298    bstring : STRING)                      -- binary string
6299    return UNRESOLVED_ufixed
6300  is
6301    variable left_index, right_index : INTEGER;
6302  begin
6303    calculate_string_boundry (bstring, left_index, right_index);
6304    return from_string (bstring, left_index, right_index);
6305  end function from_string;
6306
6307  -- Direct octal and hex conversion functions.  In this case
6308  -- the string lengths must match.  Example:
6309  -- signal sf1 := sfixed (5 downto -3);
6310  -- sf1 <= from_ostring ("71.4") -- -6.5
6311  function from_ostring (
6312    ostring : STRING)                      -- Octal string
6313    return UNRESOLVED_ufixed
6314  is
6315    variable left_index, right_index : INTEGER;
6316  begin
6317    calculate_string_boundry (ostring, left_index, right_index);
6318    return from_ostring (ostring, ((left_index+1)*3)-1, right_index*3);
6319  end function from_ostring;
6320
6321  function from_hstring (
6322    hstring : STRING)                      -- hex string
6323    return UNRESOLVED_ufixed
6324  is
6325    variable left_index, right_index : INTEGER;
6326  begin
6327    calculate_string_boundry (hstring, left_index, right_index);
6328    return from_hstring (hstring, ((left_index+1)*4)-1, right_index*4);
6329  end function from_hstring;
6330
6331  function from_string (
6332    bstring : STRING)                      -- binary string
6333    return UNRESOLVED_sfixed
6334  is
6335    variable left_index, right_index : INTEGER;
6336  begin
6337    calculate_string_boundry (bstring, left_index, right_index);
6338    return from_string (bstring, left_index, right_index);
6339  end function from_string;
6340
6341  function from_ostring (
6342    ostring : STRING)                      -- Octal string
6343    return UNRESOLVED_sfixed
6344  is
6345    variable left_index, right_index : INTEGER;
6346  begin
6347    calculate_string_boundry (ostring, left_index, right_index);
6348    return from_ostring (ostring, ((left_index+1)*3)-1, right_index*3);
6349  end function from_ostring;
6350
6351  function from_hstring (
6352    hstring : STRING)                      -- hex string
6353    return UNRESOLVED_sfixed
6354  is
6355    variable left_index, right_index : INTEGER;
6356  begin
6357    calculate_string_boundry (hstring, left_index, right_index);
6358    return from_hstring (hstring, ((left_index+1)*4)-1, right_index*4);
6359  end function from_hstring;
6360
6361end package body fixed_generic_pkg;
6362