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

Subversion Repositories sincos

[/] [sincos/] [trunk/] [vhdl/] [tb/] [un_signed_sprt/] [un_signed_sprt.vhd] - Blame information for rev 40

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 40 dk4xp
 
2
--------------------------------------------------------------------------------
3
-- (c) 2011.. Hoffmann RF & DSP  opencores@hoffmann-hochfrequenz.de
4
-- V1.0 published under BSD license
5
--------------------------------------------------------------------------------
6
-- file name:      un_signed_sprt.vhd
7
-- tool version:   Modelsim 6.1, 6.5
8
-- description:    additional support routines for signed/unsigned
9
--                 conversions between real and signed / unsigned
10
--                 the frac_xxx routines assume the decimal point to the left
11
--                 so that the range is -0.999999 or 0.0   to +0.9999999
12
--                 Note that the bits have different weights for unsigned vs. signed
13
-- calls libs:     ieee standard
14
--------------------------------------------------------------------------------
15
 
16
library ieee;
17
use ieee.std_logic_1164.all;
18
use ieee.numeric_std.all;
19
use ieee.math_real.all;
20
 
21
package un_signed_sprt is
22
 
23
 
24
  function signed2string       (s:   signed) return string;
25
  function unsigned2string     (u: unsigned) return string;
26
 
27
  function to_unsigned         (x: std_logic; proto: unsigned) return unsigned;
28
  function to_signed           (x: std_logic; proto:   signed) return   signed;
29
 
30
  function unsigned2real       (u: unsigned)  return real;
31
  function signed2real         (s: signed)    return real;
32
  function fract_unsigned2real (u: unsigned)  return real;
33
  function fract_signed2real   (s: signed)    return real;
34
 
35
  function fits_into_unsigned  (r: real; proto: unsigned) return boolean;
36
  function fits_into_signed    (r: real; proto:   signed) return boolean;
37
 
38
  function real2unsigned       (r: real; proto: unsigned) return unsigned;
39
  function real2signed         (r: real; proto:   signed) return signed;
40
  function fract_real2unsigned (r: real; proto: unsigned) return unsigned;
41
  function fract_real2signed   (r: real; proto:   signed) return signed;
42
 
43
end un_signed_sprt;
44
 
45
 
46
package body un_signed_sprt is
47
 
48
 
49
function signed2string(s: signed) return string is
50
  variable x: string(1 to s'length);
51
begin
52
  for i in s'range loop
53
    if s(i) = '1' -- damn strong typing
54
    then
55
      x(i+1) := '1';
56
    elsif s(i) = '0'
57
    then
58
      x(i+1) := '0';
59
    else
60
      x(i+1) := 'X';  -- FIXME includes Z, weak values...
61
    end if;
62
  end loop;
63
  return x;
64
end;
65
 
66
 
67
function unsigned2string(u: unsigned) return string is
68
  variable x: string(1 to u'length);
69
begin
70
  for i in u'range loop
71
    if u(i) = '1'
72
    then
73
      x(i+1) := '1';
74
    elsif u(i) = '0'
75
    then
76
      x(i+1) := '0';
77
    else
78
      x(i+1) := 'X';
79
    end if;
80
  end loop;
81
  return x;
82
end;
83
 
84
-----------------------------------------------------------------------------------------------------------
85
 
86
-- blow up a standard_logic value to an entire singned or unsigned vector
87
-- proto is the variable that the function return value will be assigned to.
88
-- It is r/o and delivers only its bounds to the function.
89
-- (easier than extracting and passing two bounds)
90
-- Overloads functions of the same name but with different parameters.
91
 
92
function to_unsigned(x: std_logic; proto: unsigned) return unsigned is
93
  variable u: unsigned(proto'range);
94
begin
95
  for n in proto'range loop
96
    u(n) := x;
97
  end loop;
98
  return u;
99
end function;
100
 
101
 
102
function to_signed(x: std_logic; proto: signed) return signed is
103
  variable s: signed(proto'range);
104
begin
105
  for n in proto'range loop
106
    s(n) := x;
107
  end loop;
108
  return s;
109
end function;
110
 
111
-----------------------------------------------------------------------------------------------------------
112
 
113
-- unsigned-integer conversions are nice but limited to 32 bits in VHDL,
114
-- without the value 0x8000 0000
115
-- use reals instead for larger vectors. 
116
-- Beware that it might be impossible to be bit-accurate
117
-- but sometimes we only need bigger pseudo-analog vectors.
118
 
119
function unsigned2real (u: unsigned) return real is
120
 
121
        variable r, bit_value: real;
122
 
123
begin
124
 
125
   if u'length < 1 then
126
      assert false
127
          report "unsigned2real: input vector has null size, returning 0.0"
128
          severity WARNING;
129
      return 0.0;
130
    end if;
131
 
132
        r := 0.0;
133
        bit_value := 1.0 ** u'low;
134
 
135
        for i in u'low to u'high loop
136
                if u(i) = '1'
137
                then
138
                        r := r + bit_value;
139
                elsif u(i) = '0'
140
                then
141
                  null;
142
                else
143
                  assert false
144
                  report "unsigned2real(): input vector contains non-01-bits, returning 0.0"
145
                  severity WARNING;
146
                  return 0.0;
147
                end if;
148
                bit_value := 2.0 * bit_value;
149
        end loop;
150
 
151
        return r;
152
end unsigned2real;
153
 
154
 
155
 
156
function signed2real (s: signed) return real is
157
 
158
        variable result, bit_value: real;
159
 
160
begin
161
 
162
   if s'length < 2 then   -- may be unneccessary
163
      assert false
164
          report "signed2real: input vector too short, returning 0.0"
165
          severity WARNING;
166
      return 0.0;
167
    end if;
168
 
169
        result := 0.0;
170
        bit_value := 1.0 ** s'low;
171
 
172
        for i in s'low to s'high-1 loop
173
                if s(i) = '1'
174
                then
175
                        result := result + bit_value;
176
                elsif s(i) = '0'
177
                then
178
                  null;
179
                else
180
                  assert false
181
                  report "signed2real(): input vector contains non-01-bits, returning 0.0"
182
                  severity WARNING;
183
                  return 0.0;
184
                end if;
185
                bit_value := 2.0 * bit_value;
186
        end loop;
187
 
188
  if s(s'high) = '1'
189
  then
190
    result := result - bit_value;  -- subtract sign bit again
191
    return result;
192
  elsif s(s'high) = '0'
193
  then
194
    return result;
195
  else
196
    assert false
197
                  report "signed2real(): sign bit is neither 0 nor 1, returning 0.0"
198
                  severity WARNING;
199
                  return 0.0;
200
 
201
  end if;
202
end signed2real;
203
 
204
-----------------------------------------------------------------------------------------------------------
205
 
206
function fract_signed2real(s: signed) return real is
207
begin
208
  return signed2real(s) / (2.0 ** (s'length-1));
209
end function fract_signed2real;
210
 
211
 
212
function fract_unsigned2real(u: unsigned) return real is
213
begin
214
  return unsigned2real(u) / (2.0 ** u'length);
215
end function fract_unsigned2real;
216
 
217
-----------------------------------------------------------------------------------------------------------
218
 
219
function fits_into_unsigned(r: real; proto: unsigned) return boolean is
220
begin
221
  return (r >=0.0) and (r < 2.0 ** proto'length);
222
end;
223
 
224
 
225
-- for 8 bits, -128 to +127 would fit
226
 
227
function fits_into_signed(r: real; proto: signed) return boolean is
228
begin
229
  return (r >= -(2.0 ** (proto'length-1))) and (r < 2.0 ** (proto'length-1));
230
end;
231
 
232
------------------------------------------------------------------------------------------------------------
233
 
234
function real2unsigned(r: real; proto: unsigned) return unsigned is
235
  variable u: unsigned(proto'range);
236
  variable e: integer;
237
  variable rr: real := r;   -- r is constant;
238
begin
239
  if not fits_into_unsigned(r, proto)
240
  then
241
    assert false
242
    report "real2unsigned(): value does not fit into supplied unsigned "
243
         & real'image(r)
244
         & " vs. capacity: 0 to "
245
         & real'image((2.0 ** proto'length) -1.0)
246
    severity warning;
247
    u := to_unsigned('X', u);
248
  else
249
    -- extract the bits starting from the highest. 
250
    e := proto'length -1;
251
    for n in proto'range loop
252
      if rr >= 2.0 ** e
253
      then
254
        u(n) := '1';
255
        rr   := rr - 2.0 ** e;
256
      else
257
        u(n) := '0';
258
      end if;
259
      e := e - 1;
260
    end loop;
261
  end if;
262
  return u;
263
end function real2unsigned;
264
 
265
 
266
function real2signed(r: real; proto: signed) return signed is
267
  variable s: signed(proto'range);
268
  variable e: integer;
269
  variable rr: real := r;   -- r is constant;
270
  variable neg: boolean;
271
begin
272
  neg := r < 0.0;
273
  rr  := abs(r);
274
  if not fits_into_signed(r, proto)
275
  then
276
    assert false
277
    report "real2signed(): value does not fit into supplied signed "
278
         & real'image(rr)
279
         & " vs. capacity  -"
280
         & real'image(2.0 ** (proto'length-1))
281
         & " to +"
282
         & real'image((2.0 ** (proto'length-1)) -1.0)
283
    severity warning;
284
    s := to_signed('X', s);
285
  else
286
    -- extract the bits starting from the highest.
287
    s(proto'high) := '0';
288
    e := proto'length -1;
289
    for n in proto'high downto proto'low loop
290
      if rr >= 2.0 ** e
291
      then
292
        s(n) := '1';
293
        rr   := rr - 2.0 ** e;
294
      else
295
        s(n) := '0';
296
      end if;
297
      e := e - 1;
298
    end loop;
299
  end if;
300
  if neg
301
    then s := -s;
302
  end if;
303
  return s;
304
end function real2signed;
305
 
306
 
307
-----------------------------------------------------------------------------------------------------------
308
-- may produce internal overflows for very long vectors
309
 
310
function fract_real2unsigned (r: real; proto: unsigned) return unsigned is
311
  variable rr: real;
312
  variable upper_bound: real;
313
begin
314
  upper_bound := (1.0 - 2.0** (-proto'length));
315
  if (r < 0.0 or r > upper_bound )
316
  then
317
    assert false
318
      report "fract_real2unsigned(): arg must be 0.0 .. "
319
           & real'image(upper_bound)
320
           & " but it is "
321
           & real'image(r)
322
      severity warning;
323
    return to_unsigned('X', proto);
324
  end if;
325
 
326
  rr := r * 2.0**proto'length;      -- use the non-fractional routine
327
  return real2unsigned(rr, proto);
328
 
329
end function fract_real2unsigned;
330
 
331
 
332
 
333
function fract_real2signed   (r: real; proto:   signed) return signed is
334
  variable rr: real;
335
begin
336
  if (r< -1.0) or (r> 1.0 - (2.0**(-proto'length)))
337
  then
338
    assert false
339
      report "fract_real2unsigned(): arg must be in interval -1.0 to "
340
           & real'image(1.0 - (2.0**(-proto'length)))  -- FIXME hi bound maybe off by epsilon??
341
           & " but it is "
342
           & real'image(r)
343
      severity warning;
344
    return to_signed('X', proto);
345
  end if;
346
 
347
  rr := r * 2.0**(proto'length-1); -- use the non-fractional routine
348
  return real2signed(rr, proto);
349
 
350
end function fract_real2signed;
351
 
352
end package body un_signed_sprt;

powered by: WebSVN 2.1.0

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