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

Subversion Repositories sincos

[/] [sincos/] [trunk/] [vhdl/] [arith/] [sincos/] [sincos_tb.vhd] - Blame information for rev 45

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 45 dk4xp
 
2
--------------------------------------------------------------------------------
3
-- (c) 2005.. Hoffmann RF & DSP  opencores@hoffmann-hochfrequenz.de
4
-- V1.0 published under BSD license
5
-- V1.1 2010-feb-25 added tests for combined sine and cosine module
6
--------------------------------------------------------------------------------
7
-- file name:      sincos_tb.vhd
8
-- tool version:   Modelsim 6.1, 6.5
9
-- description:    test bed for portable sine table
10
-- calls libs:     ieee standard
11
-- calls entities: clk_rst, 
12
--                 sincostab, sintab, 
13
--                 unsigned_pipestage, 
14
--                 sl_pipestage
15
--------------------------------------------------------------------------------
16
 
17
 
18
 
19
library ieee;
20
use ieee.std_logic_1164.all;
21
use ieee.numeric_std.all;
22
use ieee.math_real.all;
23
 
24
use work.un_signed_sprt.all;
25
 
26
entity sincos_tb is begin end sincos_tb;
27
 
28
 
29
architecture rtl of sincos_tb is
30
 
31
signal   verbose:           boolean := true;
32
 
33
 
34
constant theta_bits:        integer := 8;
35
constant amplitude_bits:    integer := 8;
36
 
37
constant pipestages:        integer :=0;
38
 
39
constant clock_frequency:   real := 100.0e6;
40
signal   clk:               std_logic;
41
signal   rst:               std_logic;
42
 
43
signal   ce:                std_logic := '1';
44
 
45
signal   theta:             unsigned(theta_bits - 1 downto 0) := (others => '0');
46
signal   y:                 signed(amplitude_bits - 1 downto 0);
47
signal   o_sin:             signed(amplitude_bits - 1 downto 0);
48
signal   o_cos:             signed(amplitude_bits - 1 downto 0);
49
 
50
signal   f_y, f_sin, f_cos: real;
51
 
52
signal   del_rst:           std_logic;   -- delayed inputs for result checking
53
signal   del_theta:         unsigned(theta_bits - 1 downto 0);
54
 
55
signal   ErrorInLsb_y:      real;
56
signal   WorstError_y:      real := 0.0;
57
 
58
signal   ErrorInLsb_o_sin:  real;
59
signal   WorstError_o_sin:  real := 0.0;
60
 
61
signal   ErrorInLsb_o_cos:  real;
62
signal   WorstError_o_cos:  real := 0.0;
63
 
64
signal   log_on:            std_logic;
65
 
66
 
67
 
68
-- In a system with 8 bit signed sines, the computed value should be -127....+127
69
-- The error should be less than 0.5, because otherwise a different value would be closer.
70
 
71
 
72
 
73
function compute_sin_error (verbose: boolean; theta: unsigned; result: signed) return real is
74
 
75
  variable scalefactor:     real := real((2 ** (result'length-1)-1));
76
  variable r_theta:         real;  -- the given phase 0...2pi
77
  variable TrueSine:        real;  -- the true sine value
78
  variable computed:        real;  -- result computed by the table
79
  variable ErrorInLsb:      real;
80
 
81
begin
82
 
83
      r_theta      := 2.0* Math_pi * (real(to_integer(theta))+ 0.5) / (2.0 ** theta'length);
84
      TrueSine     := sin(r_theta) * scalefactor;
85
 
86
      computed     := real(to_integer(result));
87
      ErrorInLsb   := TrueSine - computed;
88
      if verbose
89
      then
90
        report
91
               "theta = "         & integer'image(to_integer(theta))
92
             & "  r_theta = "     & real'image(r_theta)
93
             & "  exact = "       & real'image(TrueSine)
94
             & "  computed = "    & real'image(computed)
95
             & "  error LSB = "   & real'image(ErrorInLsb)
96
             ;
97
      end if; --verbose
98
      return ErrorInLsb;
99
 
100
end function compute_sin_error;
101
 
102
 
103
 
104
function compute_cos_error (verbose: boolean; theta: unsigned; result: signed) return real is
105
 
106
  variable scalefactor:     real := real((2 ** (result'length-1)-1));
107
  variable r_theta:         real;     -- the given phase 0...2pi
108
  variable TrueCos:         real;     -- the true cosine value
109
  variable computed:        real;     -- result computed by the table
110
  variable ErrorInLsb:      real;
111
 
112
begin
113
 
114
      r_theta      := 2.0* Math_pi * (real(to_integer(theta))+ 0.5) / (2.0 ** theta'length);
115
      TrueCos      := cos(r_theta) * scalefactor;
116
 
117
      computed     := real(to_integer(result));
118
      ErrorInLsb   := TrueCos - computed;
119
      if verbose
120
      then
121
        report
122
               "theta = "         & integer'image(to_integer(theta))
123
             & "  r_theta = "     & real'image(r_theta)
124
             & "  exact = "       & real'image(TrueCos)
125
             & "  computed = "    & real'image(computed)
126
             & "  error LSB = "   & real'image(ErrorInLsb)
127
             ;
128
      end if; --verbose
129
      return ErrorInLsb;
130
 
131
end function compute_cos_error;
132
 
133
 
134
----------------------------------------------------------------------------------------------------
135
 
136
BEGIN
137
 
138
 
139
u_clk_rst: entity work.clk_rst
140
  generic map(
141
    verbose         => false,
142
    clock_frequency => clock_frequency,
143
    min_resetwidth  => 46 ns
144
  )
145
  port map (
146
    clk             => clk,
147
    rst             => rst
148
  );
149
 
150
 
151
u_sin: entity work.sintab   -- convert phase to sine
152
  generic map (
153
     pipestages => pipestages
154
  )
155
  port map (
156
    clk         => clk,
157
    ce          => ce,
158
    rst         => rst,
159
 
160
    theta       => theta,
161
    sine        => y
162
  );
163
 
164
 
165
 
166
u_sincos: entity work.sincostab   -- convert phase to sine and cosine
167
  generic map (
168
     pipestages => pipestages
169
  )
170
  port map (
171
    clk         => clk,
172
    ce          => ce,
173
    rst         => rst,
174
 
175
    theta       => theta,
176
    sine        => o_sin,
177
    cosine      => o_cos
178
  );
179
 
180
 
181
--------------------------------------------------------------------------------
182
-- delay the input of the sinetable for result checking
183
-- and keep track when the first valid results should arrive.
184
 
185
 
186
u_delphase:     entity work.unsigned_pipestage
187
generic map (
188
  n_stages      => pipestages
189
)
190
Port map (
191
  clk => clk,
192
  ce  => ce,
193
  rst => rst,
194
 
195
  i   => theta,
196
  o   => del_theta
197
);
198
 
199
 
200
u_delrst:       entity work.sl_pipestage
201
generic map (
202
  n_stages      => pipestages
203
)
204
Port map (
205
  clk => clk,
206
  ce  => ce,
207
  rst => rst,
208
 
209
  i   => rst,
210
  o   => del_rst
211
);
212
 
213
 
214
--------------------------------------------------------------------------------
215
 
216
u_stimulus: process(clk) is begin
217
  if rising_edge(clk) then
218
    if rst = '1' then
219
      theta    <= (others => '0');
220
    elsif ce = '1' then
221
      theta    <= theta + 1;    -- phase accumulator
222
    end if;
223
  end if;
224
end process;
225
 
226
 
227
--------------------------------------------------------------------------------
228
-- check the output side of the sine module against the expected values.
229
-- This tests not only the table ROM but also address mirrorring,
230
-- output inversion and pipelining.
231
 
232
 
233
 
234
u_worst_sin: process(clk) is
235
begin
236
  if rising_edge(clk)
237
  then
238
 
239
    ErrorInLsb_y     <=  compute_sin_error (verbose, del_theta, y);
240
    ErrorInLsb_o_sin <=  compute_sin_error (verbose, del_theta, o_sin);
241
    ErrorInLsb_o_cos <=  compute_cos_error (verbose, del_theta, o_cos);
242
 
243
    if (ce = '1') and (del_rst = '0') then
244
 
245
     if abs(ErrorInLsb_y) > WorstError_y then
246
          WorstError_y <= abs(ErrorInLsb_y);
247
      end if;
248
 
249
      if abs(ErrorInLsb_o_sin) > WorstError_o_sin then
250
          WorstError_o_sin <= abs(ErrorInLsb_o_sin);
251
      end if;
252
 
253
      if abs(ErrorInLsb_o_cos) > WorstError_o_cos then
254
          WorstError_o_cos <= abs(ErrorInLsb_o_cos);
255
      end if;
256
 
257
      if verbose
258
      then
259
        report
260
          "  worst error upto now for y = "
261
          & real'image(WorstError_y)
262
          & "   for o_sin = "
263
          & real'image(WorstError_o_sin)
264
          & "   for o_cos = "
265
          & real'image(WorstError_o_cos)
266
          ;
267
      end if; --verbose
268
    end if; -- ce, del_rst
269
  end if; -- rising_edge()
270
end process;
271
 
272
 
273
 
274
-- log the generated sines and cosine to files so we can inspect them with matlab
275
log_on <= not del_rst;
276
 
277
 
278
-- convert amplitudes to floating point in -1.0 to 0.9999 range
279
-- from package work.un_signed_sprt
280
 
281
f_y   <= fract_signed2real(y);
282
f_sin <= fract_signed2real(o_sin);
283
f_cos <= fract_signed2real(o_cos);
284
 
285
 
286
u_log_y: entity work.real_file_log
287
   port map (
288
      clk      => clk,
289
      ce       => ce,
290
      filename => "logged_y.m",
291
      log_on   => log_on,
292
      d        => f_y
293
   );
294
 
295
 
296
u_log_sin: entity work.real_file_log
297
   port map (
298
      clk      => clk,
299
      ce       => ce,
300
      filename => "logged_sin.m",
301
      log_on   => log_on,
302
      d        => f_sin
303
   );
304
 
305
 
306
u_log_cos: entity work.real_file_log
307
   port map (
308
      clk      => clk,
309
      ce       => ce,
310
      filename => "logged_cos.m",
311
      log_on   => log_on,
312
      d        => f_cos
313
   );
314
 
315
 
316
 
317
END ARCHITECTURE rtl;

powered by: WebSVN 2.1.0

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