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

Subversion Repositories fixed_extensions

[/] [fixed_extensions/] [trunk/] [rtl/] [vhdl/] [fixed_extensions_pkg_sim.vhd] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 kavi
--------------------------------------------------------------------------------
2
-- Filename: fixed_extensions_pkg_sim.vhd
3
-- Purpose : Package adding various extensions to the VHDL-2008 (VHDL'93, 2002
4
--           compatibility versions) fixed-point arithmetic package by David 
5
--           Bishop.
6
--           Supported operators:
7
--           * ceil      : round towards plus infinity.
8
--           * fix       : round towards zero.
9
--           * floor     : round towards minus infinity.
10
--           * round     : round to nearest; ties to greatest absolute value.
11
--           * nearest   : round to nearest; ties to plus infinity.
12
--           * convergent: round to nearest; ties to closest even.
13
--           * bitinsert : bit-field insertion to word
14
--           * bitextract: bit-field extraction from word
15
--             
16
-- Author  : Nikolaos Kavvadias (C) 2011
17
-- Date    : 25-Jul-2011
18
-- Revision: 0.0.0 (01/05/11)
19
--           Initial version. Supports ceil, fix, floor, round, nearest, 
20
--           convergent based on their MATLAB documentation.
21
--           0.0.1 (03/05/11)
22
--           Added bitinsert.
23
--           0.0.2 (16/07/11)
24
--           Added bitextract (sfixed, ufixed), bitinsert (ufixed). Commented 
25
--           non-synthesizable part (assertions) of bitinsert.
26
--           0.0.3 (19/07/11)
27
--           Fixed ceil bug with rounding integral (zero fractional part) 
28
--           values.
29
--           0.0.4 (21/07/11)
30
--           Fixed more bugs regarding fix, round and convergent.
31
--           0.0.5 (25/07/11)
32
--           Design edited for simulation-oriented use.
33
--------------------------------------------------------------------------------
34
 
35
use STD.TEXTIO.all;
36
library IEEE;
37
use IEEE.STD_LOGIC_1164.all;
38
use IEEE.NUMERIC_STD.all;
39
--library IEEE_PROPOSED;
40
--use IEEE_PROPOSED.fixed_float_types.all;
41
--use IEEE_PROPOSED.fixed_pkg.all;
42
--use WORK.fixed_float_types.all;
43
use WORK.fixed_pkg.all;
44
 
45
package fixed_extensions_pkg is
46
 
47
  function ceil (arg : UNRESOLVED_sfixed) return UNRESOLVED_sfixed;
48
  function ceil (arg : UNRESOLVED_ufixed) return UNRESOLVED_ufixed;
49
  function fix (arg : UNRESOLVED_sfixed) return UNRESOLVED_sfixed;
50
  function fix (arg : UNRESOLVED_ufixed) return UNRESOLVED_ufixed;
51
  function floor (arg : UNRESOLVED_sfixed) return UNRESOLVED_sfixed;
52
  function floor (arg : UNRESOLVED_ufixed) return UNRESOLVED_ufixed;
53
  function round (arg : UNRESOLVED_sfixed) return UNRESOLVED_sfixed;
54
  function round (arg : UNRESOLVED_ufixed) return UNRESOLVED_ufixed;
55
  function nearest (arg : UNRESOLVED_sfixed) return UNRESOLVED_sfixed;
56
  function nearest (arg : UNRESOLVED_ufixed) return UNRESOLVED_ufixed;
57
  function convergent (arg : UNRESOLVED_sfixed) return UNRESOLVED_sfixed;
58
  function convergent (arg : UNRESOLVED_ufixed) return UNRESOLVED_ufixed;
59
  function bitinsert (a, y0 : UNRESOLVED_sfixed; bhi, blo : std_logic_vector) return UNRESOLVED_sfixed;
60
  function bitinsert (a, y0 : UNRESOLVED_ufixed; bhi, blo : std_logic_vector) return UNRESOLVED_ufixed;
61
  function bitextract (a : UNRESOLVED_sfixed; bhi, blo : std_logic_vector) return UNRESOLVED_sfixed;
62
  function bitextract (a : UNRESOLVED_ufixed; bhi, blo : std_logic_vector) return UNRESOLVED_ufixed;
63
 
64
end package fixed_extensions_pkg;
65
 
66
--library IEEE;
67
--use IEEE.MATH_REAL.all;
68
--use WORK.MATH_REAL.all;
69
 
70
package body fixed_extensions_pkg is
71
 
72
  -- ceil: round towards plus infinity.
73
  function ceil (
74
    arg : UNRESOLVED_sfixed)            -- fixed point input
75
    return UNRESOLVED_sfixed is
76
    variable result      : UNRESOLVED_sfixed (arg'high downto arg'low);
77
    variable fract_zero  : std_logic_vector(-arg'low-1 downto 0) := (others => '0');
78
  begin
79
    if (arg'high <= 0) then
80
      result := (others => '0');
81
      return result;
82
    end if;
83
    if (arg'low > 0) then
84
      result := arg;
85
      return result;
86
    end if;
87
    if (arg'low < 0) then
88
      if (to_slv(arg(-1 downto arg'low)) = fract_zero) then
89
        result := arg;
90
      else
91
        result := arg + 1;
92
      end if;
93
      result(-1 downto arg'low) := (others => '0');
94
    end if;
95
    return result;
96
  end function ceil;
97
 
98
  -- ceil: round towards plus infinity.
99
  function ceil (
100
    arg : UNRESOLVED_ufixed)            -- fixed point input
101
    return UNRESOLVED_ufixed is
102
    variable result      : UNRESOLVED_ufixed (arg'high downto arg'low);
103
    variable fract_zero  : std_logic_vector(-arg'low-1 downto 0) := (others => '0');
104
  begin
105
    if (arg'high <= 0) then
106
      result := (others => '0');
107
      return result;
108
    end if;
109
    if (arg'low > 0) then
110
      result := arg;
111
      return result;
112
    end if;
113
    if (arg'low < 0) then
114
      if (to_slv(arg(-1 downto arg'low)) = fract_zero) then
115
        result := arg;
116
      else
117
        result := arg + 1;
118
      end if;
119
      result(-1 downto arg'low) := (others => '0');
120
    end if;
121
    return result;
122
  end function ceil;
123
 
124
  -- fix: round towards zero.
125
  function fix (
126
    arg : UNRESOLVED_sfixed)            -- fixed point input
127
    return UNRESOLVED_sfixed is
128
    variable result      : UNRESOLVED_sfixed (arg'high downto arg'low);
129
    variable fract_zero  : std_logic_vector(-arg'low-1 downto 0) := (others => '0');
130
  begin
131
    if (arg'high <= 0) then
132
      result := (others => '0');
133
      return result;
134
    end if;
135
    if (arg'low > 0) then
136
      result := arg;
137
      return result;
138
    end if;
139
    if (arg'low < 0) then
140
      if (is_negative(arg)) then
141
        if (to_slv(arg(-1 downto arg'low)) = fract_zero) then
142
          result := arg;
143
        else
144
          result := arg + 1;
145
        end if;
146
      else
147
        result := arg;
148
      end if;
149
      result(-1 downto arg'low) := (others => '0');
150
    end if;
151
    return result;
152
  end function fix;
153
 
154
  -- fix: round towards zero.
155
  function fix (
156
    arg : UNRESOLVED_ufixed)            -- fixed point input
157
    return UNRESOLVED_ufixed is
158
    variable result      : UNRESOLVED_ufixed (arg'high downto arg'low);
159
  begin
160
    if (arg'high <= 0) then
161
      result := (others => '0');
162
      return result;
163
    end if;
164
    if (arg'low > 0) then
165
      result := arg;
166
      return result;
167
    end if;
168
    if (arg'low < 0) then
169
      result := arg;
170
      result(-1 downto arg'low) := (others => '0');
171
    end if;
172
    return result;
173
  end function fix;
174
 
175
  -- floor: round towards minus infinity.
176
  function floor (
177
    arg : UNRESOLVED_sfixed)            -- fixed point input
178
    return UNRESOLVED_sfixed is
179
    variable result      : UNRESOLVED_sfixed (arg'high downto arg'low);
180
  begin
181
    if (arg'high <= 0) then
182
      result := (others => '0');
183
      return result;
184
    end if;
185
    if (arg'low > 0) then
186
      result := arg;
187
      return result;
188
    end if;
189
    if (arg'low < 0) then
190
      result := arg;
191
      result(-1 downto arg'low) := (others => '0');
192
    end if;
193
    return result;
194
  end function floor;
195
 
196
  -- floor: round towards plus infinity.
197
  function floor (
198
    arg : UNRESOLVED_ufixed)            -- fixed point input
199
    return UNRESOLVED_ufixed is
200
    variable result      : UNRESOLVED_ufixed (arg'high downto arg'low);
201
  begin
202
    if (arg'high <= 0) then
203
      result := (others => '0');
204
      return result;
205
    end if;
206
    if (arg'low > 0) then
207
      result := arg;
208
      return result;
209
    end if;
210
    if (arg'low < 0) then
211
      result := arg;
212
      result(-1 downto arg'low) := (others => '0');
213
    end if;
214
    return result;
215
  end function floor;
216
 
217
  -- round: round to nearest; ties to greatest absolute value.
218
  function round (
219
    arg : UNRESOLVED_sfixed)            -- fixed point input
220
    return UNRESOLVED_sfixed is
221
    variable result      : UNRESOLVED_sfixed (arg'high downto arg'low);
222
    variable onehalf_vec : std_logic_vector(-arg'low-1 downto 0) := (others => '0');
223
  begin
224
    if (arg'high <= 0) then
225
      result := (others => '0');
226
      return result;
227
    end if;
228
    if (arg'low > 0) then
229
      result := arg;
230
      return result;
231
    end if;
232
    if (arg'low < 0) then
233
      onehalf_vec(-arg'low-1) := '1';
234
      if (is_negative(arg)) then
235
        if (to_slv(arg(-1 downto arg'low)) > onehalf_vec) then
236
          result := arg + 1;
237
        else
238
          result := arg;
239
        end if;
240
      else
241
        if (to_slv(arg(-1 downto arg'low)) >= onehalf_vec) then
242
          result := arg + 1;
243
        else
244
          result := arg;
245
        end if;
246
      end if;
247
      result(-1 downto arg'low) := (others => '0');
248
    end if;
249
    return result;
250
  end function round;
251
 
252
  -- round: round to nearest; ties to greatest absolute value.
253
  function round (
254
    arg : UNRESOLVED_ufixed)            -- fixed point input
255
    return UNRESOLVED_ufixed is
256
    variable result      : UNRESOLVED_ufixed (arg'high downto arg'low);
257
    variable onehalf_vec : std_logic_vector(-arg'low-1 downto 0) := (others => '0');
258
  begin
259
    if (arg'high <= 0) then
260
      result := (others => '0');
261
      return result;
262
    end if;
263
    if (arg'low > 0) then
264
      result := arg;
265
      return result;
266
    end if;
267
    if (arg'low < 0) then
268
      onehalf_vec(-arg'low-1) := '1';
269
      if (to_slv(arg(-1 downto arg'low)) >= onehalf_vec) then
270
        result := arg + 1;
271
      else
272
        result := arg;
273
      end if;
274
      result(-1 downto arg'low) := (others => '0');
275
    end if;
276
    return result;
277
  end function round;
278
 
279
  -- nearest: round to nearest; ties to plus infinity.
280
  function nearest (
281
    arg : UNRESOLVED_sfixed)            -- fixed point input
282
    return UNRESOLVED_sfixed is
283
    variable result      : UNRESOLVED_sfixed (arg'high downto arg'low);
284
  begin
285
    if (arg'high <= 0) then
286
      result := (others => '0');
287
      return result;
288
    end if;
289
    if (arg'low > 0) then
290
      result := arg;
291
      return result;
292
    end if;
293
    if (arg'low < 0) then
294
      if (arg(-1) = '1') then
295
        result := arg + 1;
296
      else
297
        result := arg;
298
      end if;
299
      result(-1 downto arg'low) := (others => '0');
300
    else
301
      result := arg;
302
      result(-1 downto arg'low) := (others => '0');
303
    end if;
304
    return result;
305
  end function nearest;
306
 
307
  -- nearest: round to nearest; ties to plus infinity.
308
  function nearest (
309
    arg : UNRESOLVED_ufixed)            -- fixed point input
310
    return UNRESOLVED_ufixed is
311
    variable result      : UNRESOLVED_ufixed (arg'high downto arg'low);
312
  begin
313
    if (arg'high <= 0) then
314
      result := (others => '0');
315
      return result;
316
    end if;
317
    if (arg'low > 0) then
318
      result := arg;
319
      return result;
320
    end if;
321
    if (arg'low < 0) then
322
      if (arg(-1) = '1') then
323
        result := arg + 1;
324
      else
325
        result := arg;
326
      end if;
327
      result(-1 downto arg'low) := (others => '0');
328
    else
329
      result := arg;
330
      result(-1 downto arg'low) := (others => '0');
331
    end if;
332
    return result;
333
  end function nearest;
334
 
335
  -- convergent: round to nearest; ties to closest even.
336
  function convergent (
337
    arg : UNRESOLVED_sfixed)            -- fixed point input
338
    return UNRESOLVED_sfixed is
339
    variable result      : UNRESOLVED_sfixed (arg'high downto arg'low);
340
    variable onehalf_vec : std_logic_vector(-arg'low-1 downto 0) := (others => '0');
341
  begin
342
    if (arg'high <= 0) then
343
      result := (others => '0');
344
      return result;
345
    end if;
346
    if (arg'low > 0) then
347
      result := arg;
348
      return result;
349
    end if;
350
    if (arg'low < 0) then
351
      onehalf_vec(-arg'low-1) := '1';
352
      if (arg(0) = '1') then
353
        if (to_slv(arg(-1 downto arg'low)) >= onehalf_vec) then
354
          result := arg + 1;
355
        else
356
          result := arg;
357
        end if;
358
      else
359
        if (to_slv(arg(-1 downto arg'low)) > onehalf_vec) then
360
          result := arg + 1;
361
        else
362
          result := arg;
363
        end if;
364
      end if;
365
      result(-1 downto arg'low) := (others => '0');
366
    end if;
367
    return result;
368
  end function convergent;
369
 
370
  -- convergent: round to nearest; ties to closest even.
371
  function convergent (
372
    arg : UNRESOLVED_ufixed)            -- fixed point input
373
    return UNRESOLVED_ufixed is
374
    variable result      : UNRESOLVED_ufixed (arg'high downto arg'low);
375
    variable onehalf_vec : std_logic_vector(-arg'low-1 downto 0) := (others => '0');
376
  begin
377
    if (arg'high <= 0) then
378
      result := (others => '0');
379
      return result;
380
    end if;
381
    if (arg'low > 0) then
382
      result := arg;
383
      return result;
384
    end if;
385
    if (arg'low < 0) then
386
      onehalf_vec(-arg'low-1) := '1';
387
      if (arg(0) = '1') then
388
        if (to_slv(arg(-1 downto arg'low)) >= onehalf_vec) then
389
          result := arg + 1;
390
        else
391
          result := arg;
392
        end if;
393
      else
394
        if (to_slv(arg(-1 downto arg'low)) > onehalf_vec) then
395
          result := arg + 1;
396
        else
397
          result := arg;
398
        end if;
399
      end if;
400
      result(-1 downto arg'low) := (others => '0');
401
    end if;
402
    return result;
403
  end function convergent;
404
 
405
  function bitinsert (a, y0 : UNRESOLVED_sfixed; bhi, blo : std_logic_vector) return UNRESOLVED_sfixed is
406
    variable y : UNRESOLVED_sfixed(a'RANGE);
407
  begin
408
--    if (bhi < blo) then
409
--      assert false 
410
--        report "Error: Invalid range for bitfield insert." 
411
--        severity failure;    
412
--    end if;
413
--    if (to_integer(signed(bhi)) > y'HIGH) then
414
--      assert false 
415
--        report "Error: High bound (bhi) is out of result range." 
416
--        severity failure;    
417
--    end if;
418
--    if (to_integer(signed(blo)) < y'LOW) then
419
--      assert false 
420
--        report "Error: Low bound (blo) is out of result range." 
421
--        severity failure;    
422
--    end if;
423
    y := y0;
424
    y(to_integer(signed(bhi)) downto to_integer(signed(blo))) :=
425
      a(to_integer(signed(bhi))-to_integer(signed(blo)) downto a'LOW);
426
    return (y);
427
  end bitinsert;
428
 
429
  function bitinsert (a, y0 : UNRESOLVED_ufixed; bhi, blo : std_logic_vector) return UNRESOLVED_ufixed is
430
    variable y : UNRESOLVED_ufixed(a'RANGE);
431
  begin
432
    y := y0;
433
    y(to_integer(signed(bhi)) downto to_integer(signed(blo))) :=
434
      a(to_integer(signed(bhi))-to_integer(signed(blo)) downto a'LOW);
435
    return (y);
436
  end bitinsert;
437
 
438
  function bitextract (a : UNRESOLVED_sfixed; bhi, blo : std_logic_vector) return UNRESOLVED_sfixed is
439
    variable y : sfixed(a'HIGH downto a'LOW);
440
  begin
441
    y := a;
442
    y(to_integer(signed(bhi))-to_integer(signed(blo)) downto a'LOW) :=
443
      a(to_integer(signed(bhi)) downto to_integer(signed(blo)));
444
    return (y);
445
  end bitextract;
446
 
447
  function bitextract (a : UNRESOLVED_ufixed; bhi, blo : std_logic_vector) return UNRESOLVED_ufixed is
448
    variable y : ufixed(a'HIGH downto a'LOW);
449
  begin
450
    y := a;
451
    y(to_integer(signed(bhi))-to_integer(signed(blo)) downto a'LOW) :=
452
      a(to_integer(signed(bhi)) downto to_integer(signed(blo)));
453
    return (y);
454
  end bitextract;
455
 
456
end package body fixed_extensions_pkg;

powered by: WebSVN 2.1.0

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