📄 c_model.c
字号:
// c_model.c
//
// This C file is intended to provide DirectC functions
// to calculate trigonometric functions within Verilog.
//
// Angles are scaled in the same way as for the CORDIC
// rotator: as 16-bit signed integers, with +/-maxint
// scaled to +/-pi. Hence 0x8000 represents -180deg
// and 0x7FFF represents almost +180deg.
// Likewise, sine and cosine values are scaled to 15-bit
// width (so that they fit into 16 bits with a guard):
// +1 scales to 0x4000, and -1 scales to 0xC000.
// Revision information:
//
// v0.0 15-Jan-2004 Jonathan Bromley
// First version incorporating VCS-generated header output
//
// v1.0 24-Jan-2004 Jonathan Bromley
// Added new function vlog_CORDIC_model to provide a model of the
// intended function of the CORDIC rotator design for SNUG '04
#ifdef __cplusplus
extern "C" {
#endif
#include <math.h>
#include <stdio.h>
#ifndef M_PI
#define M_PI (atan(1.0) * 4.0)
#endif
#ifndef _VC_TYPES_
#define _VC_TYPES_
/* common definitions shared with DirectC.h */
typedef unsigned int U;
typedef unsigned char UB;
typedef unsigned char scalar;
typedef struct { U c; U d;} vec32;
#define scalar_0 0
#define scalar_1 1
#define scalar_z 2
#define scalar_x 3
typedef struct VeriC_Descriptor *vc_handle;
#endif /* _VC_TYPES_ */
#define CORDIC_GAIN 1.646760258
#define CORDIC_MAX_ROTATION 1.74328662
extern void vlog_CORDIC_model (
scalar reduceNotRotate,
int angleIn,
int xIn,
int yIn,
/*OUT*/int* angleOut,
/*OUT*/int* xOut,
/*OUT*/int* yOut
);
// _______________________________________________ Helper functions ___
// Scale an angle between Verilog 16-bit and maths
static double verilog_to_radians (int a) {
return M_PI * a / 32768.0;
}
static int radians_to_verilog (double a) {
return a * 32768.0 / M_PI;
}
// Scale a -1..+1 integer to/from Verilog 15-bit
static double verilog_to_trig (int a) {
return a / 16384.0;
}
static int trig_to_verilog (double a) {
return (int)(a * 16384.0);
}
// ____________________________________________________________________
// ___________________________________________ DirectC entry points ___
int vlog_cos(int a) {
return trig_to_verilog(cos(verilog_to_radians(a)));
}
int vlog_sin(int a) {
return trig_to_verilog(sin(verilog_to_radians(a)));
}
int vlog_atan2(int y, int x) {
return radians_to_verilog(atan2(y,x));
}
void vlog_CORDIC_model(
scalar reduceNotRotate,
int angleIn,
int xIn,
int yIn,
int* angleOut,
int* xOut,
int* yOut
) {
double a, x, y, xR, yR, s, c;
// Get trig values from Verilog info
x = verilog_to_trig(xIn);
y = verilog_to_trig(yIn);
if (reduceNotRotate == scalar_1) {
// Determine rotation required to reduce y to 0
a = -atan2(y, x);
// Input angle is ignored in this case.
// Zeroing the input angle makes later code common.
angleIn = 0;
} else {
// Input angle specifies required rotation
a = verilog_to_radians(angleIn);
}
// Limit angle to maximum available rotation
if (a > CORDIC_MAX_ROTATION)
a = CORDIC_MAX_ROTATION;
if (a < -CORDIC_MAX_ROTATION)
a = -CORDIC_MAX_ROTATION;
// Do the rotation
s = sin(a);
c = cos(a);
xR = CORDIC_GAIN * (c*x - s*y);
yR = CORDIC_GAIN * (s*x + c*y);
// Create Verilog results
*angleOut = angleIn - radians_to_verilog(a);
*xOut = trig_to_verilog(xR);
*yOut = trig_to_verilog(yR);
}
#ifdef __cplusplus
}
#endif
// ____________________________________________________________________
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -