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

Subversion Repositories systemc_cordic

[/] [systemc_cordic/] [trunk/] [cordic_ip/] [testbench.cpp.nop] - Blame information for rev 4

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 wwcheng
// testbench.cpp: source file
2
/********************************************************************
3
//
4
// Module:
5
//   Testbench feeding instructions into Cordic core
6
//
7
// Implementation:
8
//   This module tests the Rotate, Magnitude-Phase, Sin-Cos and
9
//   Sinh-Cosh CORDIC engines.
10
//
11
//
12
// Authors:     Winnie Cheng,
13
//              Peter Wu
14
//
15
 *********************************************************************/
16
 
17
#include "testbench.h"
18
#include "opcode.h"
19
#include "convert.h"
20
#include 
21
 
22
#define ROTATE_NUM_TEST         5
23
#define MAGPHASE_NUM_TEST       5
24
#define SINCOS_NUM_TEST         5
25
#define SINHCOSH_NUM_TEST       500
26
 
27
#ifdef MODULE_NAME
28
#undef MODULE_NAME
29
#endif
30
 
31
#define MODULE_NAME     "[testbench]"
32
 
33
void testbench::testbench_process()
34
{
35
    short i;
36
    double x, y, a;
37
    double rad, correct_x, correct_y;
38
    double computed_v1, computed_v2;
39
    bool success;
40
 
41
    // Initialize output
42
 
43
    done.write(false);
44
    instructions_valid.write(false);
45
    wait();
46
 
47
    wait_until(start.delayed()==true);
48
    printf("%s Testbench for CORDIC engines\n", MODULE_NAME);
49
    success = true;
50
 
51
    // Test Rotate Engine
52
    for(i = 0; i < ROTATE_NUM_TEST; i++) {
53
        wait();
54
 
55
        // Generate random input
56
        a = 1.0*((rand()>>2)%360)-180.0;
57
        x = 1.0*((rand()>>2)%100);
58
        y = 1.0*((rand()>>2)%100);
59
        cout << MODULE_NAME << "Rotate(" << x << ", " << y << ", " << a << ")" << endl;
60
 
61
        // activate the rotate engine
62
        engine_select.write(I_ROTATE);
63
        operand1.write(toint(x));       // orgX
64
        operand2.write(toint(y));       // orgY
65
        operand3.write(toint(a));       // angle
66
        instructions_valid.write(true);
67
        wait();
68
 
69
        // pulse instructions valid
70
        instructions_valid.write(false);
71
        wait_until(compute_done.delayed()==true);
72
 
73
        // Read Computed Results
74
        computed_v1 = tofp(result1.read());
75
        computed_v2 = tofp(result2.read());
76
 
77
        // Check Result
78
        rad=(3.1415926*a)/180.0;
79
        correct_x=x*cos(rad)-y*sin(rad); /* Perform "perfect" rotation by  */
80
        correct_y=y*cos(rad)+x*sin(rad); /* using f.p. and transcendentals */
81
 
82
        if ((fabs(computed_v1-correct_x)>0.15) ||
83
            (fabs(computed_v2-correct_y)>0.15)) {
84
            cout << MODULE_NAME << "ERROR computed=" << computed_v1 << ",";
85
            cout << computed_v2 << " expected=" << correct_x << ",";
86
            cout << correct_y << endl;
87
            success = false;
88
        } else {
89
            cout << MODULE_NAME << "CORRECT" << endl;
90
        }
91
 
92
        wait();
93
 
94
    } // end Test Rotate Engine
95
 
96
    // Test MagPhase Engine
97
    for(i = 0; i < MAGPHASE_NUM_TEST; i++) {
98
        wait();
99
        x = 2.0*((rand()>>2)%100) - 100;
100
        y = 2.0*((rand()>>2)%100) - 100;
101
        cout << MODULE_NAME << "Mag and Phase(" << x << ", " << y << ") " << endl;
102
 
103
        // activate the rotate engine
104
        engine_select.write(I_MAGPHASE);
105
        operand1.write(toint(x));       // orgX
106
        operand2.write(toint(y));       // orgY
107
        instructions_valid.write(true);
108
        wait();
109
 
110
        // pulse instructions valid
111
        instructions_valid.write(false);
112
        wait_until(compute_done.delayed()==true);
113
 
114
        // Read Computed Results
115
        computed_v1 = tofp(result1.read());
116
        computed_v2 = tofp(result2.read());
117
 
118
        // Check Result
119
        correct_x=sqrt(x*x+y*y); /* Perform "perfect" magnitude */
120
        correct_y=atan(y/x)*180/3.1415926;
121
 
122
        if (x<0 && y>0)
123
           correct_y = 180 + correct_y;
124
        if (x<0 && y<=0)
125
           correct_y = -180 + correct_y;
126
 
127
        if ((fabs(computed_v1-correct_x)>0.15) ||
128
            (fabs(computed_v2-correct_y)>0.15)) {
129
            cout << MODULE_NAME << "ERROR computed=" << computed_v1 << ",";
130
            cout << computed_v2 << " expected=" << correct_x << ",";
131
            cout << correct_y << endl;
132
            success = false;
133
        } else {
134
            cout << MODULE_NAME << "CORRECT" << endl;
135
        }
136
 
137
        wait();
138
 
139
    } // end Test Magnitude and Phase Engine
140
 
141
    // Test Sine Cosine Engine
142
    for(i = 0; i < SINCOS_NUM_TEST; i++) {
143
        wait();
144
        a = 1.0*((rand()>>2)%360)-180.0;
145
        cout << MODULE_NAME << "Sine and Cosine(" << a << ") " << endl;
146
 
147
        // activate the rotate engine
148
        engine_select.write(I_SINCOS);
149
        operand1.write(toint(a));       // orgX
150
        instructions_valid.write(true);
151
        wait();
152
 
153
        // pulse instructions valid
154
        instructions_valid.write(false);
155
        wait_until(compute_done.delayed()==true);
156
 
157
        // Read Computed Results
158
        computed_v1 = tofp(result1.read());
159
        computed_v2 = tofp(result2.read());
160
 
161
        // Check Result
162
        rad=(3.1415926*a)/180.0;
163
        correct_x=sin(rad); /* Perform "perfect" Cosine */
164
        correct_y=cos(rad);
165
        if ((fabs(computed_v1-correct_x)>0.06) ||
166
            (fabs(computed_v2-correct_y)>0.06)) {
167
            cout << MODULE_NAME << "ERROR computed=" << computed_v1 << ",";
168
            cout << computed_v2 << " expected=" << correct_x << ",";
169
            cout << correct_y << endl;
170
            success = false;
171
        } else {
172
            cout << MODULE_NAME << "CORRECT" << endl;
173
        }
174
 
175
        wait();
176
 
177
    } // end Test Sine and Cosine Engine
178
 
179
    // Test Sinh Cosh Engine
180
    for(i = 0; i < SINHCOSH_NUM_TEST; i++) {
181
        wait();
182
        a = 1.0*((rand()>>2)%90)-45.0;
183
        if(a < 0 && a > -3) a = -3;       // adjust for algorithm inaccuracies
184
        cout << MODULE_NAME << "Sinh and Cosh(" << a << ") " << endl;
185
        // activate the rotate engine
186
        engine_select.write(I_SINHCOSH);
187
        operand1.write(toint(a));       // orgX
188
        instructions_valid.write(true);
189
        wait();
190
 
191
        // pulse instructions valid
192
        instructions_valid.write(false);
193
        wait_until(compute_done.delayed()==true);
194
 
195
        // Read Computed Results
196
        computed_v1 = tofp(result1.read());
197
        computed_v2 = tofp(result2.read());
198
 
199
        // Check Result
200
        rad=(3.1415926*a)/180.0;
201
        correct_x=sinh(rad); /* Perform "perfect" Cosine */
202
        correct_y=cosh(rad);
203
 
204
        if ((fabs(computed_v1-correct_x)>0.06) ||
205
            (fabs(computed_v2-correct_y)>0.06)) {
206
            cout << MODULE_NAME << "ERROR computed=" << computed_v1 << ",";
207
            cout << computed_v2 << " expected=" << correct_x << ",";
208
            cout << correct_y << endl;
209
            success = false;
210
        } else {
211
            cout << MODULE_NAME << "CORRECT" << endl;
212
        }
213
 
214
        wait();
215
 
216
    } // end Test Sinh and Cosh Engine
217
 
218
    cout << MODULE_NAME << "Testbench completed - ";
219
    if(success) {
220
        cout << "SUCCESS" << endl;
221
    } else {
222
        cout << "FAILED" << endl;
223
    }
224
    done.write(true);
225
    // end of test vectors
226
}

powered by: WebSVN 2.1.0

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