URL
https://opencores.org/ocsvn/systemc_cordic/systemc_cordic/trunk
Subversion Repositories systemc_cordic
[/] [systemc_cordic/] [trunk/] [cordic_ip/] [testbench.cpp.nop] - Rev 4
Compare with Previous | Blame | View Log
// testbench.cpp: source file
/********************************************************************
//
// Module:
// Testbench feeding instructions into Cordic core
//
// Implementation:
// This module tests the Rotate, Magnitude-Phase, Sin-Cos and
// Sinh-Cosh CORDIC engines.
//
//
// Authors: Winnie Cheng<wwcheng@stanford.edu>,
// Peter Wu<peter5@stanford.edu>
//
*********************************************************************/
#include "testbench.h"
#include "opcode.h"
#include "convert.h"
#include <math.h>
#define ROTATE_NUM_TEST 5
#define MAGPHASE_NUM_TEST 5
#define SINCOS_NUM_TEST 5
#define SINHCOSH_NUM_TEST 500
#ifdef MODULE_NAME
#undef MODULE_NAME
#endif
#define MODULE_NAME "[testbench]"
void testbench::testbench_process()
{
short i;
double x, y, a;
double rad, correct_x, correct_y;
double computed_v1, computed_v2;
bool success;
// Initialize output
done.write(false);
instructions_valid.write(false);
wait();
wait_until(start.delayed()==true);
printf("%s Testbench for CORDIC engines\n", MODULE_NAME);
success = true;
// Test Rotate Engine
for(i = 0; i < ROTATE_NUM_TEST; i++) {
wait();
// Generate random input
a = 1.0*((rand()>>2)%360)-180.0;
x = 1.0*((rand()>>2)%100);
y = 1.0*((rand()>>2)%100);
cout << MODULE_NAME << "Rotate(" << x << ", " << y << ", " << a << ")" << endl;
// activate the rotate engine
engine_select.write(I_ROTATE);
operand1.write(toint(x)); // orgX
operand2.write(toint(y)); // orgY
operand3.write(toint(a)); // angle
instructions_valid.write(true);
wait();
// pulse instructions valid
instructions_valid.write(false);
wait_until(compute_done.delayed()==true);
// Read Computed Results
computed_v1 = tofp(result1.read());
computed_v2 = tofp(result2.read());
// Check Result
rad=(3.1415926*a)/180.0;
correct_x=x*cos(rad)-y*sin(rad); /* Perform "perfect" rotation by */
correct_y=y*cos(rad)+x*sin(rad); /* using f.p. and transcendentals */
if ((fabs(computed_v1-correct_x)>0.15) ||
(fabs(computed_v2-correct_y)>0.15)) {
cout << MODULE_NAME << "ERROR computed=" << computed_v1 << ",";
cout << computed_v2 << " expected=" << correct_x << ",";
cout << correct_y << endl;
success = false;
} else {
cout << MODULE_NAME << "CORRECT" << endl;
}
wait();
} // end Test Rotate Engine
// Test MagPhase Engine
for(i = 0; i < MAGPHASE_NUM_TEST; i++) {
wait();
x = 2.0*((rand()>>2)%100) - 100;
y = 2.0*((rand()>>2)%100) - 100;
cout << MODULE_NAME << "Mag and Phase(" << x << ", " << y << ") " << endl;
// activate the rotate engine
engine_select.write(I_MAGPHASE);
operand1.write(toint(x)); // orgX
operand2.write(toint(y)); // orgY
instructions_valid.write(true);
wait();
// pulse instructions valid
instructions_valid.write(false);
wait_until(compute_done.delayed()==true);
// Read Computed Results
computed_v1 = tofp(result1.read());
computed_v2 = tofp(result2.read());
// Check Result
correct_x=sqrt(x*x+y*y); /* Perform "perfect" magnitude */
correct_y=atan(y/x)*180/3.1415926;
if (x<0 && y>0)
correct_y = 180 + correct_y;
if (x<0 && y<=0)
correct_y = -180 + correct_y;
if ((fabs(computed_v1-correct_x)>0.15) ||
(fabs(computed_v2-correct_y)>0.15)) {
cout << MODULE_NAME << "ERROR computed=" << computed_v1 << ",";
cout << computed_v2 << " expected=" << correct_x << ",";
cout << correct_y << endl;
success = false;
} else {
cout << MODULE_NAME << "CORRECT" << endl;
}
wait();
} // end Test Magnitude and Phase Engine
// Test Sine Cosine Engine
for(i = 0; i < SINCOS_NUM_TEST; i++) {
wait();
a = 1.0*((rand()>>2)%360)-180.0;
cout << MODULE_NAME << "Sine and Cosine(" << a << ") " << endl;
// activate the rotate engine
engine_select.write(I_SINCOS);
operand1.write(toint(a)); // orgX
instructions_valid.write(true);
wait();
// pulse instructions valid
instructions_valid.write(false);
wait_until(compute_done.delayed()==true);
// Read Computed Results
computed_v1 = tofp(result1.read());
computed_v2 = tofp(result2.read());
// Check Result
rad=(3.1415926*a)/180.0;
correct_x=sin(rad); /* Perform "perfect" Cosine */
correct_y=cos(rad);
if ((fabs(computed_v1-correct_x)>0.06) ||
(fabs(computed_v2-correct_y)>0.06)) {
cout << MODULE_NAME << "ERROR computed=" << computed_v1 << ",";
cout << computed_v2 << " expected=" << correct_x << ",";
cout << correct_y << endl;
success = false;
} else {
cout << MODULE_NAME << "CORRECT" << endl;
}
wait();
} // end Test Sine and Cosine Engine
// Test Sinh Cosh Engine
for(i = 0; i < SINHCOSH_NUM_TEST; i++) {
wait();
a = 1.0*((rand()>>2)%90)-45.0;
if(a < 0 && a > -3) a = -3; // adjust for algorithm inaccuracies
cout << MODULE_NAME << "Sinh and Cosh(" << a << ") " << endl;
// activate the rotate engine
engine_select.write(I_SINHCOSH);
operand1.write(toint(a)); // orgX
instructions_valid.write(true);
wait();
// pulse instructions valid
instructions_valid.write(false);
wait_until(compute_done.delayed()==true);
// Read Computed Results
computed_v1 = tofp(result1.read());
computed_v2 = tofp(result2.read());
// Check Result
rad=(3.1415926*a)/180.0;
correct_x=sinh(rad); /* Perform "perfect" Cosine */
correct_y=cosh(rad);
if ((fabs(computed_v1-correct_x)>0.06) ||
(fabs(computed_v2-correct_y)>0.06)) {
cout << MODULE_NAME << "ERROR computed=" << computed_v1 << ",";
cout << computed_v2 << " expected=" << correct_x << ",";
cout << correct_y << endl;
success = false;
} else {
cout << MODULE_NAME << "CORRECT" << endl;
}
wait();
} // end Test Sinh and Cosh Engine
cout << MODULE_NAME << "Testbench completed - ";
if(success) {
cout << "SUCCESS" << endl;
} else {
cout << "FAILED" << endl;
}
done.write(true);
// end of test vectors
}