⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 c_model.c

📁 systemverilog程序
💻 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 + -