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

Subversion Repositories systemc_cordic

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 2 to Rev 3
    Reverse comparison

Rev 2 → Rev 3

/trunk/cordic_ip/cordic.cpp
0,0 → 1,170
// cordic.cpp: source file
/********************************************************************
//
// Module:
// Cordic Engine Pipeline Stage
//
// Implementation:
// This module implements one pipeline stage of the cordic engine.
//
//
// Authors: Winnie Cheng <wwcheng@stanford.edu>,
// Peter Wu <peter5@stanford.edu>
//
*********************************************************************/
 
#include "cordic.h"
#include "opcode.h"
 
#ifdef MODULE_NAME
#undef MODULE_NAME
#endif
 
#define MODULE_NAME "cordic"
 
#define DEBUG 1
#if DEBUG
#define dprintf printf
#else
#define dprintf
#endif
 
void cordic::cordic_process()
{
bool enable;
short opcode;
short desired_phase;
 
short x, y, acc_phase;
 
short type, tmp_x, table_value, cond;
// stage parameters
short reg_stage_num, reg_tablep, reg_tableh;
// On Reset, initialize output
done.write(false);
out_x.write(0);
out_y.write(0);
out_acc_phase.write(0);
out_opcode.write(I_NOP);
out_desired_phase.write(0);
// Get stage parameters for this stage
reg_stage_num = stage_num.read();
reg_tablep = tablep.read();
reg_tableh = tableh.read();
 
while(1) {
 
wait();
// Registered Input
enable = start.read();
// input data from previous stage
x = in_x.read();
y = in_y.read();
acc_phase = in_acc_phase.read();
// input data propagated
opcode = in_opcode.read();
desired_phase = in_desired_phase.read();
 
if(enable) {
// do stage operation
// condition varies for different opcode
if(opcode == I_ROTATE) {
cond = (acc_phase < 0);
type = TYPE_NONHYPER;
table_value = -reg_tablep;
dprintf("[%s%02d] ROTATE\n", MODULE_NAME, reg_stage_num);
} else if (opcode == I_MAGPHASE) {
cond = (y >= 0);
type = TYPE_NONHYPER;
table_value = reg_tablep;
dprintf("[%s%02d] MAG-PHASE\n", MODULE_NAME, reg_stage_num);
} else if (opcode == I_SINCOS) {
cond = (desired_phase - acc_phase < 0);
type = TYPE_NONHYPER;
table_value = reg_tablep;
dprintf("[%s%02d] SIN-COS\n", MODULE_NAME, reg_stage_num);
} else if (opcode == I_SINHCOSH) {
cond = (desired_phase - acc_phase < 0);
type = TYPE_HYPER;
table_value = reg_tableh;
dprintf("[%s%02d] SINH-COSH\n", MODULE_NAME, reg_stage_num);
} else {
// treat as NOP
type = TYPE_NOP;
dprintf("[%s%02d] NOP\n", MODULE_NAME, reg_stage_num);
}
 
tmp_x = x;
if(type == TYPE_NONHYPER) {
// non-hyperbolic functions
if(cond) {
x += y >> reg_stage_num;
y -= tmp_x >> reg_stage_num;
acc_phase -= table_value;
} else {
x -= y >> reg_stage_num;
y += tmp_x >> reg_stage_num;
acc_phase += table_value;
}
// Output results
done.write(true);
out_x.write(x);
out_y.write(y);
out_acc_phase.write(acc_phase);
out_opcode.write(opcode);
out_desired_phase.write(desired_phase);
 
} else if (type == TYPE_HYPER) {
// hyperbolic functions
if(cond) {
x -= y >> (reg_stage_num+1);
y -= tmp_x >> (reg_stage_num+1);
acc_phase -= table_value;
} else {
x += y >> (reg_stage_num+1);
y += tmp_x >> (reg_stage_num+1);
acc_phase += table_value;
}
 
// Output results
done.write(true);
out_x.write(x);
out_y.write(y);
out_acc_phase.write(acc_phase);
out_opcode.write(opcode);
out_desired_phase.write(desired_phase);
 
} else {
 
// NOP, same output as reset condition except done is true
done.write(true);
out_x.write(0);
out_y.write(0);
out_acc_phase.write(0);
out_opcode.write(I_NOP);
out_desired_phase.write(0);
}
 
} else {
// same output as reset condition
done.write(false);
out_x.write(0);
out_y.write(0);
out_acc_phase.write(0);
out_opcode.write(I_NOP);
out_desired_phase.write(0);
}
 
} // forever loop
}
/trunk/cordic_ip/testrun.log
1,3 → 1,5
Your license(s) for feature `SystemCSim' expire within 5 days.
WARNING: Default time step is used for VCD tracing.
[testbench] Testbench for CORDIC engines
[cordic00] NOP
[cordic01] NOP
/trunk/cordic_ip/decoder.cpp
0,0 → 1,201
// decoder.cpp: source file
/********************************************************************
//
// Module:
// Instruction Decoding Unit
//
// Implementation:
// This module decodes the instruction and sets up the 12-stage
// CORDIC pipeline
//
//
// Authors: Winnie Cheng <wwcheng@stanford.edu>,
// Peter Wu <peter5@stanford.edu>
//
*********************************************************************/
 
#include "decoder.h"
#include "opcode.h"
#include "convert.h"
 
#ifdef MODULE_NAME
#undef MODULE_NAME
#endif
 
#define MODULE_NAME "decoder"
 
#define DEBUG 1
#if DEBUG
#define dprintf printf
#else
#define dprintf
#endif
 
#define NUM_STAGES 12
#define IDLE_SLACK 2*NUM_STAGES
 
void decoder::decoder_process()
{
short flush;
sc_uint<UNIT_SEL_WIDTH> ir;
short op1, op2, op3;
 
short x, y, acc_phase, desired_phase;
short tmp_x;
 
// On reset, initialize output
enable_pipeline.write(false);
out_x.write(0);
out_y.write(0);
out_acc_phase.write(0);
out_opcode.write(I_NOP);
out_desired_phase.write(0);
flush = NUM_STAGES + IDLE_SLACK;
 
while(1) {
wait();
if(start.read()==true) {
flush = NUM_STAGES + IDLE_SLACK; // reset counter
// Registered input
if(instruction_valid.read()==true) {
// Read registered input
ir = opcode.read();
op1 = operand1.read();
op2 = operand2.read();
op3 = operand3.read();
 
// Decode the opcode and adjust input
if(ir == I_ROTATE) {
// Rotate Instruction Format
// operand1 : orgX
// operand2 : orgY
// operand3 : angle
// returns
// result1 : rotated x-coordinate
// result2 : rotated y-coordinate
x = op1;
y = op2;
acc_phase = op3;
 
if(acc_phase < 0) {
// If vector lies in fourth-quadrant, position to first-quadrant
x = -op1;
y = -op2;
acc_phase += INT180;
}
if (acc_phase > INT90) {
// If vector lies in third-quadrant, position to first-quadrant
tmp_x = x;
x = -y;
y = tmp_x;
acc_phase -=INT90;
}
dprintf("[%s] ROTATE\n", MODULE_NAME);
} else if (ir == I_MAGPHASE) {
 
// Magphase Instruction Format
// operand1 : X
// operand2 : Y
// returns
// result1 : magnitude
// result2 : phase
 
x = op1;
y = op2;
 
if(x < 0) {
// rotate by an initial +/- 90 degrees
tmp_x = x;
if( y > 0) {
x = y;
y = -tmp_x;
acc_phase = -INT90; // subtract 90 deg
} else {
x = -y;
y = tmp_x;
acc_phase = INT90; // add 90 deg
}
} else {
acc_phase = 0;
}
dprintf("[%s] MAG-PHASE\n", MODULE_NAME);
} else if (ir == I_SINCOS) {
 
// SinCos Instruction Format
// operand1 : phase
// return
// result1 : sin(phase)
// result2 : cos(phase)
 
desired_phase = op1;
 
// start with +90, -90, or 0 degrees
if(desired_phase > INT90) {
x = 0;
y = START_SINCOS_Y; // adjust with mult factor
acc_phase = INT90;
} else if (desired_phase < -INT90) {
x = 0;
y = -START_SINCOS_Y;
acc_phase = -INT90;
} else {
x = START_SINCOS_Y;
y = 0;
acc_phase = 0;
}
dprintf("[%s] SIN-COS\n", MODULE_NAME);
} else if (ir == I_SINHCOSH) {
// SinhCosh Instruction Format
// operand1 : phase
// return
// result1 : sinh(phase)
// result2 : cosh(phase)
 
desired_phase = op1;
x = START_SINHCOSH_X;
y = 0;
acc_phase = 0;
dprintf("[%s] SINH-COSH\n", MODULE_NAME);
}
// write output
enable_pipeline.write(true);
out_x.write(x);
out_y.write(y);
out_acc_phase.write(acc_phase);
out_opcode.write(ir);
out_desired_phase.write(desired_phase);
} else {
// feed with NOP
enable_pipeline.write(true);
out_x.write(0);
out_y.write(0);
out_acc_phase.write(0);
out_opcode.write(I_NOP);
out_desired_phase.write(0);
}
} else {
if(flush > 0) {
// keep pipeline enable, flush with NOP
enable_pipeline.write(true);
flush--;
} else {
enable_pipeline.write(false);
printf("[%s] Pipeline shutdown for power-save mode\n", MODULE_NAME);
}
out_x.write(0);
out_y.write(0);
out_acc_phase.write(0);
out_opcode.write(I_NOP);
out_desired_phase.write(0);
}
} // forever-loop
}
/trunk/cordic_ip/cordic.h
0,0 → 1,67
// cordic.h: header file
/********************************************************************
//
// Module:
// Cordic Engine Pipeline Stage
//
// Interface:
// Registered input, non-registered output
//
//
// Authors: Winnie Cheng <wwcheng@stanford.edu>,
// Peter Wu <peter5@stanford.edu>
//
*********************************************************************/
 
#include "systemc.h"
#include "opcode.h"
 
SC_MODULE(cordic) {
 
// Clock Declaration
sc_in_clk clk;
// Input ports Declaration
sc_in<bool> start; // enables the stage
sc_in<bool> reset;
// Input data - previous stage results
sc_in<short> in_x;
sc_in<short> in_y;
sc_in<short> in_acc_phase;
 
// Input data - propagated instruction info
sc_in<sc_uint<UNIT_SEL_WIDTH> > in_opcode;
sc_in<short> in_desired_phase;
 
// Input data - stage parametrization
sc_in<short> stage_num;
sc_in<short> tablep;
sc_in<short> tableh;
 
// Output ports Declaration
sc_out<bool> done;
 
// Output data - results of this stage
sc_out<short> out_x;
sc_out<short> out_y;
sc_out<short> out_acc_phase;
 
// Output data - propagated instruction info
sc_out<sc_uint<UNIT_SEL_WIDTH> > out_opcode;
sc_out<short> out_desired_phase;
 
// Declare implementation functions
void cordic_process();
 
// Constructor
SC_CTOR(cordic)
{
// Register processes and define active clock edge
SC_CTHREAD(cordic_process, clk.pos());
 
// Watching for global reset
watching(reset.delayed()==true);
}
 
}; // end module cordic
/trunk/cordic_ip/decoder.h
0,0 → 1,61
// decoder.h: header file
/********************************************************************
//
// Module:
// Instruction Decoding Unit
//
// Interface:
// This module interfaces to the testbench and the pipeline.
// Registered input, non-registered output
//
//
// Authors: Winnie Cheng <wwcheng@stanford.edu>,
// Peter Wu <peter5@stanford.edu>
//
*********************************************************************/
 
#include "systemc.h"
#include "opcode.h"
 
SC_MODULE(decoder) {
 
// Clock Declaration
sc_in_clk clk;
// Input ports Declaration
sc_in<bool> start;
sc_in<bool> reset;
// Input data - instruction
sc_in<bool> instruction_valid;
sc_in<sc_uint<UNIT_SEL_WIDTH> > opcode;
sc_in<short> operand1;
sc_in<short> operand2;
sc_in<short> operand3;
 
// Output ports declaration
sc_out<bool> enable_pipeline;
 
// Output data - feed to first stage of pipeline
sc_out<short> out_x;
sc_out<short> out_y;
sc_out<short> out_acc_phase;
 
// Output data - propagated instruction info
sc_out<sc_uint<UNIT_SEL_WIDTH> > out_opcode;
sc_out<short> out_desired_phase;
 
// Declare implementation functions
void decoder_process();
 
// Constructor
SC_CTOR(decoder)
{
// Register processes and define active clock edge
SC_CTHREAD(decoder_process, clk.pos());
 
// Watching for global reset
watching(reset.delayed()==true);
}
 
}; // end module cordic
/trunk/cordic_ip/cordpipe.h
0,0 → 1,423
// cordpipe.h: header file
/********************************************************************
//
// Module:
// Cordic Engine 12-stage Pipeline
//
// Interface:
// This module connects the 12-stages together.
// Registered input, non-registered output
//
//
// Authors: Winnie Cheng <wwcheng@stanford.edu>,
// Peter Wu <peter5@stanford.edu>
//
*********************************************************************/
 
#include "systemc.h"
#include "cordic.h"
#include "opcode.h"
 
SC_MODULE(cordpipe) {
 
// Clock Declaration
sc_in_clk clk;
// Input ports Declaration
sc_in<bool> start;
sc_in<bool> reset;
// Input data - first stage results
sc_in<short> in_x;
sc_in<short> in_y;
sc_in<short> in_acc_phase;
 
// Input data - propagated instruction info
sc_in<sc_uint<UNIT_SEL_WIDTH> > in_opcode;
sc_in<short> in_desired_phase;
 
// Output ports Declaration
sc_out<bool> done;
 
// Output data - results of this stage
sc_out<short> out_x;
sc_out<short> out_y;
sc_out<short> out_acc_phase;
 
// Output data - propagated instruction info
sc_out<sc_uint<UNIT_SEL_WIDTH> > out_opcode;
sc_out<short> out_desired_phase;
 
// constants to parametrize pipeline module on system reset
sc_in<short> stage0;
sc_in<short> stage1;
sc_in<short> stage2;
sc_in<short> stage3;
sc_in<short> stage4;
sc_in<short> stage5;
sc_in<short> stage6;
sc_in<short> stage7;
sc_in<short> stage8;
sc_in<short> stage9;
sc_in<short> stage10;
sc_in<short> stage11;
 
sc_in<short> tablep_0;
sc_in<short> tablep_1;
sc_in<short> tablep_2;
sc_in<short> tablep_3;
sc_in<short> tablep_4;
sc_in<short> tablep_5;
sc_in<short> tablep_6;
sc_in<short> tablep_7;
sc_in<short> tablep_8;
sc_in<short> tablep_9;
sc_in<short> tablep_10;
sc_in<short> tablep_11;
 
sc_in<short> tableh_0;
sc_in<short> tableh_1;
sc_in<short> tableh_2;
sc_in<short> tableh_3;
sc_in<short> tableh_4;
sc_in<short> tableh_5;
sc_in<short> tableh_6;
sc_in<short> tableh_7;
sc_in<short> tableh_8;
sc_in<short> tableh_9;
sc_in<short> tableh_10;
sc_in<short> tableh_11;
 
// Signals
sc_signal<short> out0_x;
sc_signal<short> out1_x;
sc_signal<short> out2_x;
sc_signal<short> out3_x;
sc_signal<short> out4_x;
sc_signal<short> out5_x;
sc_signal<short> out6_x;
sc_signal<short> out7_x;
sc_signal<short> out8_x;
sc_signal<short> out9_x;
sc_signal<short> out10_x;
sc_signal<short> out0_y;
sc_signal<short> out1_y;
sc_signal<short> out2_y;
sc_signal<short> out3_y;
sc_signal<short> out4_y;
sc_signal<short> out5_y;
sc_signal<short> out6_y;
sc_signal<short> out7_y;
sc_signal<short> out8_y;
sc_signal<short> out9_y;
sc_signal<short> out10_y;
sc_signal<short> out0_acc_phase;
sc_signal<short> out1_acc_phase;
sc_signal<short> out2_acc_phase;
sc_signal<short> out3_acc_phase;
sc_signal<short> out4_acc_phase;
sc_signal<short> out5_acc_phase;
sc_signal<short> out6_acc_phase;
sc_signal<short> out7_acc_phase;
sc_signal<short> out8_acc_phase;
sc_signal<short> out9_acc_phase;
sc_signal<short> out10_acc_phase;
 
sc_signal<sc_uint<UNIT_SEL_WIDTH> > out0_opcode;
sc_signal<sc_uint<UNIT_SEL_WIDTH> > out1_opcode;
sc_signal<sc_uint<UNIT_SEL_WIDTH> > out2_opcode;
sc_signal<sc_uint<UNIT_SEL_WIDTH> > out3_opcode;
sc_signal<sc_uint<UNIT_SEL_WIDTH> > out4_opcode;
sc_signal<sc_uint<UNIT_SEL_WIDTH> > out5_opcode;
sc_signal<sc_uint<UNIT_SEL_WIDTH> > out6_opcode;
sc_signal<sc_uint<UNIT_SEL_WIDTH> > out7_opcode;
sc_signal<sc_uint<UNIT_SEL_WIDTH> > out8_opcode;
sc_signal<sc_uint<UNIT_SEL_WIDTH> > out9_opcode;
sc_signal<sc_uint<UNIT_SEL_WIDTH> > out10_opcode;
 
sc_signal<short> out0_desired_phase;
sc_signal<short> out1_desired_phase;
sc_signal<short> out2_desired_phase;
sc_signal<short> out3_desired_phase;
sc_signal<short> out4_desired_phase;
sc_signal<short> out5_desired_phase;
sc_signal<short> out6_desired_phase;
sc_signal<short> out7_desired_phase;
sc_signal<short> out8_desired_phase;
sc_signal<short> out9_desired_phase;
sc_signal<short> out10_desired_phase;
 
sc_signal<bool> stage0_done;
sc_signal<bool> stage1_done;
sc_signal<bool> stage2_done;
sc_signal<bool> stage3_done;
sc_signal<bool> stage4_done;
sc_signal<bool> stage5_done;
sc_signal<bool> stage6_done;
sc_signal<bool> stage7_done;
sc_signal<bool> stage8_done;
sc_signal<bool> stage9_done;
sc_signal<bool> stage10_done;
 
// 12 stage instances
cordic *s0_instance;
cordic *s1_instance;
cordic *s2_instance;
cordic *s3_instance;
cordic *s4_instance;
cordic *s5_instance;
cordic *s6_instance;
cordic *s7_instance;
cordic *s8_instance;
cordic *s9_instance;
cordic *s10_instance;
cordic *s11_instance;
// Constructor
SC_CTOR(cordpipe)
{
// instantiate and connect stage 0
s0_instance = new cordic("stage0_in_pipe");
s0_instance->clk(clk);
s0_instance->start(start);
s0_instance->reset(reset);
s0_instance->in_x(in_x);
s0_instance->in_y(in_y);
s0_instance->in_acc_phase(in_acc_phase);
s0_instance->in_opcode(in_opcode);
s0_instance->in_desired_phase(in_desired_phase);
s0_instance->stage_num(stage0);
s0_instance->tablep(tablep_0);
s0_instance->tableh(tableh_0);
s0_instance->done(stage0_done);
s0_instance->out_x(out0_x);
s0_instance->out_y(out0_y);
s0_instance->out_acc_phase(out0_acc_phase);
s0_instance->out_opcode(out0_opcode);
s0_instance->out_desired_phase(out0_desired_phase);
 
// instantiate and connect stage 1
s1_instance = new cordic("stage1_in_pipe");
s1_instance->clk(clk);
s1_instance->start(start);
s1_instance->reset(reset);
s1_instance->in_x(out0_x);
s1_instance->in_y(out0_y);
s1_instance->in_acc_phase(out0_acc_phase);
s1_instance->in_opcode(out0_opcode);
s1_instance->in_desired_phase(out0_desired_phase);
s1_instance->stage_num(stage1);
s1_instance->tablep(tablep_1);
s1_instance->tableh(tableh_1);
s1_instance->done(stage1_done);
s1_instance->out_x(out1_x);
s1_instance->out_y(out1_y);
s1_instance->out_acc_phase(out1_acc_phase);
s1_instance->out_opcode(out1_opcode);
s1_instance->out_desired_phase(out1_desired_phase);
// instantiate and connect stage 2
s2_instance = new cordic("stage2_in_pipe");
s2_instance->clk(clk);
s2_instance->start(start);
s2_instance->reset(reset);
s2_instance->in_x(out1_x);
s2_instance->in_y(out1_y);
s2_instance->in_acc_phase(out1_acc_phase);
s2_instance->in_opcode(out1_opcode);
s2_instance->in_desired_phase(out1_desired_phase);
s2_instance->stage_num(stage2);
s2_instance->tablep(tablep_2);
s2_instance->tableh(tableh_2);
s2_instance->done(stage2_done);
s2_instance->out_x(out2_x);
s2_instance->out_y(out2_y);
s2_instance->out_acc_phase(out2_acc_phase);
s2_instance->out_opcode(out2_opcode);
s2_instance->out_desired_phase(out2_desired_phase);
// instantiate and connect stage 3
s3_instance = new cordic("stage3_in_pipe");
s3_instance->clk(clk);
s3_instance->start(start);
s3_instance->reset(reset);
s3_instance->in_x(out2_x);
s3_instance->in_y(out2_y);
s3_instance->in_acc_phase(out2_acc_phase);
s3_instance->in_opcode(out2_opcode);
s3_instance->in_desired_phase(out2_desired_phase);
s3_instance->stage_num(stage3);
s3_instance->tablep(tablep_3);
s3_instance->tableh(tableh_3);
s3_instance->done(stage3_done);
s3_instance->out_x(out3_x);
s3_instance->out_y(out3_y);
s3_instance->out_acc_phase(out3_acc_phase);
s3_instance->out_opcode(out3_opcode);
s3_instance->out_desired_phase(out3_desired_phase);
// instantiate and connect stage 4
s4_instance = new cordic("stage4_in_pipe");
s4_instance->clk(clk);
s4_instance->start(start);
s4_instance->reset(reset);
s4_instance->in_x(out3_x);
s4_instance->in_y(out3_y);
s4_instance->in_acc_phase(out3_acc_phase);
s4_instance->in_opcode(out3_opcode);
s4_instance->in_desired_phase(out3_desired_phase);
s4_instance->stage_num(stage4);
s4_instance->tablep(tablep_4);
s4_instance->tableh(tableh_4);
s4_instance->done(stage4_done);
s4_instance->out_x(out4_x);
s4_instance->out_y(out4_y);
s4_instance->out_acc_phase(out4_acc_phase);
s4_instance->out_opcode(out4_opcode);
s4_instance->out_desired_phase(out4_desired_phase);
// instantiate and connect stage 5
s5_instance = new cordic("stage5_in_pipe");
s5_instance->clk(clk);
s5_instance->start(start);
s5_instance->reset(reset);
s5_instance->in_x(out4_x);
s5_instance->in_y(out4_y);
s5_instance->in_acc_phase(out4_acc_phase);
s5_instance->in_opcode(out4_opcode);
s5_instance->in_desired_phase(out4_desired_phase);
s5_instance->stage_num(stage5);
s5_instance->tablep(tablep_5);
s5_instance->tableh(tableh_5);
s5_instance->done(stage5_done);
s5_instance->out_x(out5_x);
s5_instance->out_y(out5_y);
s5_instance->out_acc_phase(out5_acc_phase);
s5_instance->out_opcode(out5_opcode);
s5_instance->out_desired_phase(out5_desired_phase);
// instantiate and connect stage 6
s6_instance = new cordic("stage6_in_pipe");
s6_instance->clk(clk);
s6_instance->start(start);
s6_instance->reset(reset);
s6_instance->in_x(out5_x);
s6_instance->in_y(out5_y);
s6_instance->in_acc_phase(out5_acc_phase);
s6_instance->in_opcode(out5_opcode);
s6_instance->in_desired_phase(out5_desired_phase);
s6_instance->stage_num(stage6);
s6_instance->tablep(tablep_6);
s6_instance->tableh(tableh_6);
s6_instance->done(stage6_done);
s6_instance->out_x(out6_x);
s6_instance->out_y(out6_y);
s6_instance->out_acc_phase(out6_acc_phase);
s6_instance->out_opcode(out6_opcode);
s6_instance->out_desired_phase(out6_desired_phase);
// instantiate and connect stage 7
s7_instance = new cordic("stage7_in_pipe");
s7_instance->clk(clk);
s7_instance->start(start);
s7_instance->reset(reset);
s7_instance->in_x(out6_x);
s7_instance->in_y(out6_y);
s7_instance->in_acc_phase(out6_acc_phase);
s7_instance->in_opcode(out6_opcode);
s7_instance->in_desired_phase(out6_desired_phase);
s7_instance->stage_num(stage7);
s7_instance->tablep(tablep_7);
s7_instance->tableh(tableh_7);
s7_instance->done(stage7_done);
s7_instance->out_x(out7_x);
s7_instance->out_y(out7_y);
s7_instance->out_acc_phase(out7_acc_phase);
s7_instance->out_opcode(out7_opcode);
s7_instance->out_desired_phase(out7_desired_phase);
// instantiate and connect stage 8
s8_instance = new cordic("stage8_in_pipe");
s8_instance->clk(clk);
s8_instance->start(start);
s8_instance->reset(reset);
s8_instance->in_x(out7_x);
s8_instance->in_y(out7_y);
s8_instance->in_acc_phase(out7_acc_phase);
s8_instance->in_opcode(out7_opcode);
s8_instance->in_desired_phase(out7_desired_phase);
s8_instance->stage_num(stage8);
s8_instance->tablep(tablep_8);
s8_instance->tableh(tableh_8);
s8_instance->done(stage8_done);
s8_instance->out_x(out8_x);
s8_instance->out_y(out8_y);
s8_instance->out_acc_phase(out8_acc_phase);
s8_instance->out_opcode(out8_opcode);
s8_instance->out_desired_phase(out8_desired_phase);
// instantiate and connect stage 9
s9_instance = new cordic("stage9_in_pipe");
s9_instance->clk(clk);
s9_instance->start(start);
s9_instance->reset(reset);
s9_instance->in_x(out8_x);
s9_instance->in_y(out8_y);
s9_instance->in_acc_phase(out8_acc_phase);
s9_instance->in_opcode(out8_opcode);
s9_instance->in_desired_phase(out8_desired_phase);
s9_instance->stage_num(stage9);
s9_instance->tablep(tablep_9);
s9_instance->tableh(tableh_9);
s9_instance->done(stage9_done);
s9_instance->out_x(out9_x);
s9_instance->out_y(out9_y);
s9_instance->out_acc_phase(out9_acc_phase);
s9_instance->out_opcode(out9_opcode);
s9_instance->out_desired_phase(out9_desired_phase);
// instantiate and connect stage 10
s10_instance = new cordic("stage10_in_pipe");
s10_instance->clk(clk);
s10_instance->start(start);
s10_instance->reset(reset);
s10_instance->in_x(out9_x);
s10_instance->in_y(out9_y);
s10_instance->in_acc_phase(out9_acc_phase);
s10_instance->in_opcode(out9_opcode);
s10_instance->in_desired_phase(out9_desired_phase);
s10_instance->stage_num(stage10);
s10_instance->tablep(tablep_10);
s10_instance->tableh(tableh_10);
s10_instance->done(stage10_done);
s10_instance->out_x(out10_x);
s10_instance->out_y(out10_y);
s10_instance->out_acc_phase(out10_acc_phase);
s10_instance->out_opcode(out10_opcode);
s10_instance->out_desired_phase(out10_desired_phase);
// instantiate and connect stage 11
s11_instance = new cordic("stage11_in_pipe");
s11_instance->clk(clk);
s11_instance->start(start);
s11_instance->reset(reset);
s11_instance->in_x(out10_x);
s11_instance->in_y(out10_y);
s11_instance->in_acc_phase(out10_acc_phase);
s11_instance->in_opcode(out10_opcode);
s11_instance->in_desired_phase(out10_desired_phase);
s11_instance->stage_num(stage11);
s11_instance->tablep(tablep_11);
s11_instance->tableh(tableh_11);
s11_instance->done(done);
s11_instance->out_x(out_x);
s11_instance->out_y(out_y);
s11_instance->out_acc_phase(out_acc_phase);
s11_instance->out_opcode(out_opcode);
s11_instance->out_desired_phase(out_desired_phase);
}
 
}; // end module cordpipe
/trunk/cordic_ip/opcode.h
0,0 → 1,39
#ifndef _OPCODE_H_
#define _OPCODE_H_
// opcode.h: header file
/********************************************************************
//
// Module:
// A collection of opcode related decodings and settings
//
// Authors: Winnie Cheng<wwcheng@stanford.edu>,
// Peter Wu<peter5@stanford.edu>
*********************************************************************/
 
// specification in user program file
#define ROT_OPNAME "rot"
#define MAG_OPNAME "mgp"
#define SIN_OPNAME "sin"
#define COS_OPNAME "cos"
#define SINH_OPNAME "sinh"
#define COSH_OPNAME "cosh"
#define NOP_OPNAME "nop"
 
// decode which function unit
#define UNIT_SEL_WIDTH 4
#define I_NOP (short)0
#define I_ROTATE (short)1
#define I_MAGPHASE (short)2
#define I_SINCOS (short)8 // selects the SIN-COS unit
#define I_SIN (short)8
#define I_COS (short)9
#define I_SINHCOSH (short)10 // selects the SINH-COSH unit
#define I_SINH (short)10
#define I_COSH (short)11
 
// differentiate operations within a pipeline stage
#define TYPE_NOP 0
#define TYPE_NONHYPER 1
#define TYPE_HYPER 2
 
#endif // _OPCODE_H_
/trunk/cordic_ip/testbench.cpp
0,0 → 1,494
// 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 100
#define MAGPHASE_NUM_TEST 100
#define SINCOS_NUM_TEST 100
#define SINHCOSH_NUM_TEST 100
 
#ifdef MODULE_NAME
#undef MODULE_NAME
#endif
 
#define MODULE_NAME "[testbench]"
 
#define PROGFILE "userprog.dat"
#define LOGFILE "testpipe.log"
#define MAX_PROGSIZE 24
#define MAX_STR_LEN 128
 
void testbench::testbench_process()
{
short i;
double x, y, a;
double rad, correct_x, correct_y;
double computed_v1, computed_v2;
int fixed1, fixed2;
bool success, skip;
int retval;
char ir[MAX_STR_LEN];
char op[3][MAX_STR_LEN];
int file_opcode;
int num_instr;
FILE *logfile;
 
// Opens user program file for reading
FILE *infile = fopen(PROGFILE, "r");
if(!infile) {
cout << MODULE_NAME << "File does not exist: " << PROGFILE << endl;
exit(-1);
}
// Initialize output
done.write(false);
instructions_valid.write(false);
start_monitor.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
// Testing Pipeline
wait();
cout << MODULE_NAME << "Testing Pipeline Mode" << endl;
start_monitor.write(true);
wait();
 
// Translates user program
i = 0;
 
while(i < MAX_PROGSIZE) {
wait();
 
retval = fscanf(infile, "%s", ir);
if(retval==EOF) break;
if(!strcmp(ir, "rot")) {
// Rotate type functions
printf("%s Opcode ROTATE[%s]: ", MODULE_NAME, ir);
// get operands
if((retval=fscanf(infile, "%s %s %s\n", op[0], op[1], op[2]))!= 3) {
printf("Parse Error\n");
break;
} else {
printf("[%s], [%s], [%s]\n", op[0], op[1], op[2]);
engine_select.write(I_ROTATE);
operand1.write(toint(atof(op[0])));
operand2.write(toint(atof(op[1])));
operand3.write(toint(atof(op[2])));
instructions_valid.write(true);
}
} else if(!strcmp(ir, MAG_OPNAME)){
// Magnitude-Phase type functions
printf("%s Opcode MAG-PHASE[%s]: ", MODULE_NAME, ir);
// get operands
if((retval=fscanf(infile, "%s %s\n", op[0], op[1]))!= 2) {
printf("Parse Error\n");
break;
} else {
printf("%s, %s\n", op[0], op[1]);
engine_select.write(I_MAGPHASE);
operand1.write(toint(atof(op[0])));
operand2.write(toint(atof(op[1])));
instructions_valid.write(true);
}
} else if(!strcmp(ir, SIN_OPNAME) || !strcmp(ir, COS_OPNAME)) {
// Trig type functions
printf("%s Opcode SIN-COS[%s]: ", MODULE_NAME, ir);
// get operands
if((retval=fscanf(infile, "%s\n", op[0]))!= 1) {
printf("Parse Error\n");
break;
} else {
printf("%s\n", op[0]);
engine_select.write(I_SINCOS);
operand1.write(toint(atof(op[0])));
instructions_valid.write(true);
}
} else if(!strcmp(ir, SINH_OPNAME) || !strcmp(ir, COSH_OPNAME)) {
// Trig Hyperbolic type functions
printf("%s Opcode SINH-COSH[%s]: ", MODULE_NAME, ir);
// get operands
if((retval=fscanf(infile, "%s\n", op[0]))!= 1) {
printf("Parse Error\n");
break;
} else {
printf("%s\n", op[0]);
engine_select.write(I_SINHCOSH);
operand1.write(toint(atof(op[0])));
instructions_valid.write(true);
}
} else if (!strcmp(ir, NOP_OPNAME)) {
// NOP function
printf("%s Opcode NOP[%s]\n", MODULE_NAME, ir);
engine_select.write(I_NOP);
instructions_valid.write(true);
} else {
printf("Unknown Opcode %s\n", ir);
engine_select.write(I_NOP);
instructions_valid.write(false);
break;
}
i++;
}
 
if(i == MAX_PROGSIZE) wait();
 
instructions_valid.write(false);
fclose(infile);
cout << MODULE_NAME << "Interpreted " << i << " instructions\n";
num_instr = i;
 
wait_until(monitor_idle.delayed()==true);
start_monitor.write(false);
wait();
// Check results
cout << MODULE_NAME << "Checking Pipeline Mode results" << endl;
infile = fopen(PROGFILE, "r");
logfile = fopen(LOGFILE, "r");
if(!infile) {
cout << MODULE_NAME << "Prog file cannot be opened: " << PROGFILE << endl;
exit(-1);
}
if(!logfile) {
cout << MODULE_NAME << "Log file cannot be opened: " << LOGFILE << endl;
exit(-1);
}
 
i = 0;
skip = false;
 
while(i < MAX_PROGSIZE) {
wait();
 
retval = fscanf(infile, "%s", ir);
if(retval==EOF) break;
if(skip==false) {
retval = fscanf(logfile, "%d %x %x\n", &file_opcode, &fixed1, &fixed2);
if(retval!=3) {
cout << MODULE_NAME << "ERROR mismatch num_arg in " << LOGFILE << " found " << retval << endl;
break;
}
computed_v1 = tofp((short)fixed1);
computed_v2 = tofp((short)fixed2);
}
skip = false;
if(!strcmp(ir, "rot")) {
// Rotate type functions
printf("%s Opcode ROTATE[%s]: ", MODULE_NAME, ir);
// get operands
if((retval=fscanf(infile, "%s %s %s\n", op[0], op[1], op[2]))!= 3) {
printf("Parse Error\n");
break;
} else {
printf("[%s], [%s], [%s]\n", op[0], op[1], op[2]);
// Check
rad=(3.1415926*atof(op[2]))/180.0;
correct_x=atof(op[0])*cos(rad)-atof(op[1])*sin(rad);
correct_y=atof(op[1])*cos(rad)+atof(op[0])*sin(rad);
 
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;
}
}
} else if(!strcmp(ir, MAG_OPNAME)){
// Magnitude-Phase type functions
printf("%s Opcode MAG-PHASE[%s]: ", MODULE_NAME, ir);
// get operands
if((retval=fscanf(infile, "%s %s\n", op[0], op[1]))!= 2) {
printf("Parse Error\n");
break;
} else {
printf("%s, %s\n", op[0], op[1]);
// Check
x = atof(op[0]);
y = atof(op[1]);
correct_x=sqrt(x*x+y*y);
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;
}
}
} else if(!strcmp(ir, SIN_OPNAME) || !strcmp(ir, COS_OPNAME)) {
// Trig type functions
printf("%s Opcode SIN-COS[%s]: ", MODULE_NAME, ir);
// get operands
if((retval=fscanf(infile, "%s\n", op[0]))!= 1) {
printf("Parse Error\n");
break;
} else {
printf("%s\n", op[0]);
// Check
rad=(3.1415926*atof(op[0]))/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;
}
}
} else if(!strcmp(ir, SINH_OPNAME) || !strcmp(ir, COSH_OPNAME)) {
// Trig Hyperbolic type functions
printf("%s Opcode SINH-COSH[%s]: ", MODULE_NAME, ir);
// get operands
if((retval=fscanf(infile, "%s\n", op[0]))!= 1) {
printf("Parse Error\n");
break;
} else {
printf("%s\n", op[0]);
// Check
rad=(3.1415926*atof(op[0]))/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;
}
}
} else if (!strcmp(ir, NOP_OPNAME)) {
// NOP function
printf("%s Opcode NOP[%s]\n", MODULE_NAME, ir);
skip = true;
} else {
printf("Unknown Opcode %s\n", ir);
break;
}
i++;
}
if(i != num_instr) {
cout << MODULE_NAME << "ERROR num of instruction mismatched " ;
cout << i << " vs " << num_instr << endl;
success = false;
} else {
cout << MODULE_NAME << "Pipeline processed " << i << " instructions" <<endl;
}
fclose(infile);
fclose(logfile);
 
cout << MODULE_NAME << "Testbench completed - ";
if(success) {
cout << "SUCCESS" << endl;
} else {
cout << "FAILED" << endl;
}
done.write(true);
// end of test vectors
}
/trunk/cordic_ip/main.cpp
19,7 → 19,6
#include "decoder.h"
#include "cordpipe.h"
#include "adjust.h"
#include "resultfifo.h"
#include "monitor.h"
#include "opcode.h"
#include "table.h"
63,14 → 62,7
sc_signal<short> pipe_acc_phase;
sc_signal<short> pipe_desired_phase;
sc_signal<sc_uint<UNIT_SEL_WIDTH> > pipe_opcode;
// result fifo
sc_signal<bool> fifo_read_request;
sc_signal<bool> fifo_out_valid;
sc_signal<sc_uint<UNIT_SEL_WIDTH> > fifo_out_opcode;
sc_signal<short> fifo_out_result1;
sc_signal<short> fifo_out_result2;
 
// constants to parametrize pipeline module on system reset
sc_signal<short> stage0;
sc_signal<short> stage1;
124,10 → 116,6
testbench1.result1(result1);
testbench1.result2(result2);
testbench1.monitor_idle(monitor_idle);
testbench1.fifo_valid(fifo_out_valid);
testbench1.fifo_opcode(fifo_out_opcode);
testbench1.fifo_result1(fifo_out_result1);
testbench1.fifo_result2(fifo_out_result2);
// outputs
testbench1.instructions_valid(instruction_valid);
testbench1.done(powerdown);
136,8 → 124,7
testbench1.operand1(operand1);
testbench1.operand2(operand2);
testbench1.operand3(operand3);
testbench1.fifo_read_request(fifo_read_request);
 
// instantiate decoder
decoder decoder1("decoder");
decoder1.clk(CLOCK);
223,27 → 210,11
adjust1.in_acc_phase(pipe_acc_phase);
adjust1.in_opcode(pipe_opcode);
// output
adjust1.result_valid(compute_done); // compute_done
adjust1.out_opcode(adjust_opcode); // adjust_opcode
adjust1.out_result1(result1); // result1
adjust1.out_result2(result2); // result2
adjust1.result_valid(compute_done);
adjust1.out_opcode(adjust_opcode);
adjust1.out_result1(result1);
adjust1.out_result2(result2);
 
// instantiate result fifo
resultfifo resultfifo1("resultfifo1");
resultfifo1.clk(CLOCK);
resultfifo1.reset(reset);
// inputs
resultfifo1.read_request(fifo_read_request);
resultfifo1.write_request(compute_done);
resultfifo1.in_opcode(adjust_opcode);
resultfifo1.in_result1(result1);
resultfifo1.in_result2(result2);
// outputs
resultfifo1.out_valid(fifo_out_valid);
resultfifo1.out_opcode(fifo_out_opcode);
resultfifo1.out_result1(fifo_out_result1);
resultfifo1.out_result2(fifo_out_result2);
 
// instantiate monitor unit
monitor monitor1("monitor1");
monitor1.clk(CLOCK);
250,10 → 221,10
monitor1.reset(reset);
// inputs
monitor1.start(start_monitor);
monitor1.in_valid(compute_done); // compute_done
monitor1.in_opcode(adjust_opcode); // adjust_opcode
monitor1.in_result1(result1); // result1
monitor1.in_result2(result2); // result2
monitor1.in_valid(compute_done);
monitor1.in_opcode(adjust_opcode);
monitor1.in_result1(result1);
monitor1.in_result2(result2);
monitor1.idle(monitor_idle);
 
// create trace file
/trunk/cordic_ip/testbench.h
29,12 → 29,6
sc_in<short> result2;
sc_in<bool> monitor_idle;
 
// Input ports from result fifo
sc_in<bool> fifo_valid;
sc_in<sc_uint<UNIT_SEL_WIDTH> > fifo_opcode;
sc_in<short> fifo_result1;
sc_in<short> fifo_result2;
 
// Output ports Declaration
sc_out<bool> instructions_valid;
sc_out<bool> done;
46,12 → 40,8
sc_out<short> operand2;
sc_out<short> operand3;
 
// Output to result fifo
sc_out<bool> fifo_read_request;
// Declare implementation functions
void testbench_process();
void readfifo_process();
 
// Constructor
SC_CTOR(testbench)
58,7 → 48,6
{
// Register processes and define active clock edge
SC_CTHREAD(testbench_process, clk.pos());
SC_CTHREAD(readfifo_process, clk.pos());
 
// Watching for global reset
watching(reset.delayed()==true);
/trunk/cordic_ip/adjust.cpp
0,0 → 1,134
// adjust.cpp: source file
/********************************************************************
//
// Module:
// Pipeline Output Adjusting Unit
//
// Implementation:
// This module performs some of the shifts there are needed to
// obtain final results.
//
//
// Authors: Winnie Cheng <wwcheng@stanford.edu>,
// Peter Wu <peter5@stanford.edu>
//
*********************************************************************/
 
#include "adjust.h"
#include "opcode.h"
 
#ifdef MODULE_NAME
#undef MODULE_NAME
#endif
 
#define MODULE_NAME "adjust"
 
#define DEBUG 1
#if DEBUG
#define dprintf printf
#else
#define dprintf
#endif
 
void adjust::adjust_process()
{
sc_uint<UNIT_SEL_WIDTH> opcode;
short x, y, acc_phase;
short result1, result2;
 
// On Reset, initialize output
result_valid.write(true);
out_opcode.write(I_NOP);
out_result1.write(0);
out_result2.write(0);
wait();
 
while(1) {
 
wait();
// propagate through
opcode = in_opcode.read();
out_opcode.write(opcode);
 
if(in_valid.read()==true){
// Register input
x = in_x.read();
y = in_y.read();
acc_phase = in_acc_phase.read();
 
// Adjust according to opcode
if(opcode == I_ROTATE) {
 
// Rotate Instruction Format
// operand1 : orgX
// operand2 : orgY
// operand3 : angle
// returns
// result1 : rotated x-coordinate
// result2 : rotated y-coordinate
 
// Reduce vector size by multiplier
// (1/2+1/8-1/64-1/512)
// adjust
result1=(x>>1)+(x>>3)-(x>>6)-(x>>9);
result2=(y>>1)+(y>>3)-(y>>6)-(y>>9);
 
// output results
out_result1.write(result1);
out_result2.write(result2);
result_valid.write(true);
dprintf("[%s] Adjust ROTATE\n", MODULE_NAME);
 
} else if (opcode == I_MAGPHASE) {
 
// Magphase Instruction Format
// operand1 : X
// operand2 : Y
// returns
// result1 : magnitude
// result2 : phase
 
// adjust
result1 = (x>>1)+(x>>3)-(x>>6)-(x>>9);
result2 = -acc_phase;
 
// output results
out_result1.write(result1);
out_result2.write(result2);
result_valid.write(true);
 
dprintf("[%s] Adjust MAG-PHASE\n", MODULE_NAME);
 
} else if (opcode == I_SINCOS || opcode == I_SINHCOSH) {
// SinCos/SinhCosh Instruction Format
// operand1 : phase
// return
// result1 : sin/sinh(phase)
// result2 : cos/cosh(phase)
 
// no adjustment needed
 
// output results
out_result1.write(y); // sin/sinh result
out_result2.write(x); // cos/cosh result
result_valid.write(true);
 
dprintf("[%s] Adjust SINCOS or SINHCOSH\n", MODULE_NAME);
 
} else {
// filter out NOP results
result_valid.write(false);
dprintf("[%s] Adjust ignored NOP\n", MODULE_NAME);
}
 
} else {
result_valid.write(false);
dprintf("[%s] Nothing to adjust\n", MODULE_NAME);
}
} // forever loop
}
/trunk/cordic_ip/names.fof
0,0 → 1,6
cordic.cpp
decoder.cpp
adjust.cpp
monitor.cpp
testbench.cpp
main.cpp
/trunk/cordic_ip/table.h
0,0 → 1,42
#ifndef _TABLE_H_
#define _TABLE_H_
// table.h: header file
/********************************************************************
//
// Module:
// A collection of lookup tables used in CORDIC computation
//
//
// Authors: Winnie Cheng<wwcheng@stanford.edu>,
// Peter Wu<peter5@stanford.edu>
*********************************************************************/
 
// table for non-hyperbolic functions
#define TABLEP_0 0x1680
#define TABLEP_1 0x0d48
#define TABLEP_2 0x0705
#define TABLEP_3 0x0390
#define TABLEP_4 0x01ca
#define TABLEP_5 0x00e5
#define TABLEP_6 0x0073
#define TABLEP_7 0x0039
#define TABLEP_8 0x001d
#define TABLEP_9 0x000e
#define TABLEP_10 0x0007
#define TABLEP_11 0x0004
 
// table for hyperbolic functions
#define TABLEH_0 0x0fbd
#define TABLEH_1 0x0751
#define TABLEH_2 0x039a
#define TABLEH_3 0x01cb
#define TABLEH_4 0x00e5
#define TABLEH_5 0x0073
#define TABLEH_6 0x0039
#define TABLEH_7 0x001d
#define TABLEH_8 0x000e
#define TABLEH_9 0x0007
#define TABLEH_10 0x0004
#define TABLEH_11 0x0002
 
#endif // _TABLE_H_

powered by: WebSVN 2.1.0

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