转载自:https://www.cnblogs.com/rouwawa/p/7102173.html

上两篇博文Cordic算法——圆周系统之旋转模式、Cordic算法——圆周系统之向量模式做了理论分析和实现,但是所用到的变量依然是浮点型,而cordic真正的用处是基于FPGA等只能处理定点的平台。只需将满足精度的浮点数,放大2^n倍,取整,再进行处理。

1. 旋转模式

假设要通过FPGA计算极坐标(55.6767°,1)的直角坐标。首先,角度值为浮点数,需要进行放大处理,放大10000倍。则预设的旋转角度同样要放大10000倍。

实现伪旋转(忽略模长补偿因子)的代码如下所示,注意,因为是整型运算,起始旋转时x放大了2^15,放大倍数决定计算精度,满足需求即可。最后得到的x,y在缩小2^15,即得到伪旋转后的x,y。最后进行模长波长运算(因为是浮点,同样需要放大)。

#include <stdio.h>
#include <stdlib.h>int cordic_c(int a,int r);
int x = 32768, y = 0;       //以X轴为旋转起始点,放大倍数2^15int main(viod)
{int remain = cordic_c(556767,1);        //极坐标值(极角,极径)printf("旋转角度误差:%d, 直角坐标:x = %d, y = %d\n",remain,x,y);return 0;
}int cordic_c(int a,int r)
{const int theta[] = {450000,265651,140362,71250,35763,17899,8952,4476,2238,1119,560,280,140,70,35,17,9,4,2,1}; //旋转角度int i = 0;int x_temp = 0, y_temp = 0;int angle_new = 0;      //旋转后终止角度int angle_remain = a;   //旋转后,剩余角度char detection;             //旋转方向for( i=0; i<20;i++){if(angle_remain > 0){angle_new = angle_new + theta[i];angle_remain = a - angle_new;x_temp = (x - (y >>i));y_temp = (y + (x >> i));x = x_temp;y = y_temp;detection = '+';}else{angle_new = angle_new - theta[i];angle_remain = a - angle_new;x_temp = (x + (y>>i));y_temp = (y - (x>>i));x = x_temp;y = y_temp;detection = '-'; }printf(" x = %-8d, y = %-8d, 旋转次数 = %-8d 旋转角度 = %-12d  旋转方向:%-8c  终点角度 = %-8d\n", x,y,i+1, theta[i],detection,angle_new);}x = r*x;y = r*y;return angle_remain;
}

完整的FPGA实现过程,包含预处理和后处理,支持{-π,π}的角度,采用流水线方式实现,Verilog完整代码如下,注意在移位过程中要用算术移位(>>>),才能保证带符号的数正确移位:


/****************************************************/
//预处理
module Cordic_Pre(clk,rst_n,phi,    phi_pre,quadrant_flag);/****************************************************/input                   clk;input                   rst_n;input   signed  [23:0]  phi;    output  signed  [23:0]  phi_pre;                        //预处理后的角度值output          [1:0]   quadrant_flag;                  //象限标记/****************************************************/parameter               ANGLE_P90   = 24'sd90_0000,     //输入角度范围{-pi,pi},角度值放大了10000倍ANGLE_N90   = -24'sd90_0000,ANGLE_0     = 24'sd00_0000;/****************************************************/reg     signed  [23:0]  phi_pre_r;reg             [1:0]   quadrant_flag_r;     /****************************************************/always @(posedge clk or negedge rst_n)beginif(rst_n == 1'b0)beginphi_pre_r <= 24'sd0;quadrant_flag_r <= 2'b00;endelse if(phi >= ANGLE_0 && phi <= ANGLE_P90)     //第一象限beginphi_pre_r <= phi;quadrant_flag_r <= 2'b01;           endelse if(phi > ANGLE_P90 )                       //第二象限          beginphi_pre_r <= phi - ANGLE_P90;quadrant_flag_r <= 2'b10;endelse if(phi < ANGLE_0 && phi >= ANGLE_N90)      //第四象限          beginphi_pre_r <= phi;quadrant_flag_r <= 2'b00;endelsebegin                                       //第三象限phi_pre_r <= phi - ANGLE_N90;quadrant_flag_r <= 2'b11;endend/****************************************************/assign  phi_pre         = phi_pre_r;assign  quadrant_flag   = quadrant_flag_r;/****************************************************/endmodule

我的设计要求精度较高,所以采用20次旋转,旋转过程的代码如下:

/****************************************************/module  Cordic_Rotate(clk,rst_n,phi_pre,quadrant_flag,ret_x,ret_y,quadrant);/****************************************************/input                   clk;input                   rst_n;input   signed  [23:0]  phi_pre;input           [1:0]   quadrant_flag;output  signed  [16:0]  ret_x;output  signed  [16:0]  ret_y;output          [1:0]   quadrant;
/****************************************************/parameter               X_ORIGN     = 17'sd32768;   //旋转时x的起始大小,根据精度要求而定。//每次旋转的固定角度值parameter               ANGLE_1     = 24'sd450000,  ANGLE_2     = 24'sd265651,ANGLE_3     = 24'sd140362,  ANGLE_4     = 24'sd71250,ANGLE_5     = 24'sd35763,   ANGLE_6     = 24'sd17899,ANGLE_7     = 24'sd8952,    ANGLE_8     = 24'sd4476,ANGLE_9     = 24'sd2238,    ANGLE_10    = 24'sd1119,ANGLE_11    = 24'sd560,     ANGLE_12    = 24'sd280,ANGLE_13    = 24'sd140,     ANGLE_14    = 24'sd70,ANGLE_15    = 24'sd35,      ANGLE_16    = 24'sd17,ANGLE_17    = 24'sd9,       ANGLE_18    = 24'sd4,ANGLE_19    = 24'sd2,       ANGLE_20    = 24'sd1;/****************************************************/reg     signed  [16:0]  x_r             [20:0];reg     signed  [16:0]  y_r             [20:0];reg     signed  [23:0]  angle_remain    [20:0];reg     signed  [1:0]   quadrant_r      [20:0];/****************************************************/
//旋转的流水线过程always @(posedge clk or negedge rst_n)beginif(rst_n == 1'b0)beginx_r[0] <= 17'sd0;y_r[0] <= 17'sd0;angle_remain[0] <= 24'sd0;endelsebeginx_r[0] <= X_ORIGN;               y_r[0] <= 17'sd0;angle_remain[0] <= phi_pre;endend//第1次旋转 always @(posedge clk or negedge rst_n)beginif(rst_n == 1'b0)beginx_r[1] <= 17'sd0;y_r[1] <= 17'sd0;angle_remain[1] <= 24'sd0;endelse if(angle_remain[0] > 24'sd0)beginx_r[1] <= x_r[0] - y_r[0];y_r[1] <= y_r[0] + x_r[0];angle_remain[1] <= angle_remain[0] - ANGLE_1;endelsebeginx_r[1] <= x_r[0] + y_r[0];y_r[1] <= y_r[0] - x_r[0];angle_remain[1] <= angle_remain[0] + ANGLE_1;endend//第2次旋转     always @(posedge clk or negedge rst_n)beginif(rst_n == 1'b0)beginx_r[2] <= 17'sd0;y_r[2] <= 17'sd0;angle_remain[2] <= 24'sd0;endelse if(angle_remain[1] > 24'sd0)                           //比较时,符号标记s必须带上,对结果有影响beginx_r[2] <= x_r[1] - (y_r[1] >>> 1);              y_r[2] <= y_r[1] + (x_r[1] >>> 1);                  //二元加的优先级高于算术移位angle_remain[2] <= angle_remain[1] - ANGLE_2;endelsebeginx_r[2] <= x_r[1] + (y_r[1] >>> 1);y_r[2] <= y_r[1] - (x_r[1] >>> 1);angle_remain[2] <= angle_remain[1] + ANGLE_2;endend//第3次旋转     always @(posedge clk or negedge rst_n)beginif(rst_n == 1'b0)beginx_r[3] <= 17'sd0;y_r[3] <= 17'sd0;angle_remain[3] <= 24'sd0;endelse if(angle_remain[2] > 24'sd0)beginx_r[3] <= x_r[2] - (y_r[2] >>> 2);y_r[3] <= y_r[2] + (x_r[2] >>> 2);angle_remain[3] <= angle_remain[2] - ANGLE_3;endelsebeginx_r[3] <= x_r[2] + (y_r[2] >>> 2);y_r[3] <= y_r[2] - (x_r[2] >>> 2);angle_remain[3] <= angle_remain[2] + ANGLE_3;endend//第4次旋转     always @(posedge clk or negedge rst_n)beginif(rst_n == 1'b0)beginx_r[4] <= 17'sd0;y_r[4] <= 17'sd0;angle_remain[4] <= 24'sd0;endelse if(angle_remain[3] > 24'sd0)beginx_r[4] <= x_r[3] - (y_r[3] >>> 3);y_r[4] <= y_r[3] + (x_r[3] >>> 3);angle_remain[4] <= angle_remain[3] - ANGLE_4;endelsebeginx_r[4] <= x_r[3] + (y_r[3] >>> 3);y_r[4] <= y_r[3] - (x_r[3] >>> 3);angle_remain[4] <= angle_remain[3] + ANGLE_4;endend//第5次旋转     always @(posedge clk or negedge rst_n)beginif(rst_n == 1'b0)beginx_r[5] <= 17'sd0;y_r[5] <= 17'sd0;angle_remain[5] <= 24'sd0;endelse if(angle_remain[4] > 24'sd0)beginx_r[5] <= x_r[4] - (y_r[4] >>> 4);y_r[5] <= y_r[4] + (x_r[4] >>> 4);angle_remain[5] <= angle_remain[4] - ANGLE_5;endelsebeginx_r[5] <= x_r[4] + (y_r[4] >>> 4);y_r[5] <= y_r[4] - (x_r[4] >>> 4);angle_remain[5] <= angle_remain[4] + ANGLE_5;endend//第6次旋转     always @(posedge clk or negedge rst_n)beginif(rst_n == 1'b0)beginx_r[6] <= 17'sd0;y_r[6] <= 17'sd0;angle_remain[6] <= 24'sd0;endelse if(angle_remain[5] > 24'sd0)beginx_r[6] <= x_r[5] - (y_r[5] >>> 5);y_r[6] <= y_r[5] + (x_r[5] >>> 5);angle_remain[6] <= angle_remain[5] - ANGLE_6;endelsebeginx_r[6] <= x_r[5] + (y_r[5] >>> 5);y_r[6] <= y_r[5] - (x_r[5] >>> 5);angle_remain[6] <= angle_remain[5] + ANGLE_6;endend//第7次旋转 always @(posedge clk or negedge rst_n)beginif(rst_n == 1'b0)beginx_r[7] <= 17'sd0;y_r[7] <= 17'sd0;angle_remain[7] <= 24'sd0;endelse if(angle_remain[6] > 24'sd0)beginx_r[7] <= x_r[6] - (y_r[6] >>> 6);y_r[7] <= y_r[6] + (x_r[6] >>> 6);angle_remain[7] <= angle_remain[6] - ANGLE_7;endelsebeginx_r[7] <= x_r[6] + (y_r[6] >>> 6);y_r[7] <= y_r[6] - (x_r[6] >>> 6);angle_remain[7] <= angle_remain[6] + ANGLE_7;endend//第8次旋转 always @(posedge clk or negedge rst_n)beginif(rst_n == 1'b0)beginx_r[8] <= 17'sd0;y_r[8] <= 17'sd0;angle_remain[8] <= 24'sd0;endelse if(angle_remain[7] > 24'sd0)beginx_r[8] <= x_r[7] - (y_r[7] >>> 7);y_r[8] <= y_r[7] + (x_r[7] >>> 7);angle_remain[8] <= angle_remain[7] - ANGLE_8;endelsebeginx_r[8] <= x_r[7] + (y_r[7] >>> 7);y_r[8] <= y_r[7] - (x_r[7] >>> 7);angle_remain[8] <= angle_remain[7] + ANGLE_8;endend//第9次旋转 always @(posedge clk or negedge rst_n)beginif(rst_n == 1'b0)beginx_r[9] <= 17'sd0;y_r[9] <= 17'sd0;angle_remain[9] <= 24'sd0;endelse if(angle_remain[8] > 24'sd0)beginx_r[9] <= x_r[8] - (y_r[8] >>> 8);y_r[9] <= y_r[8] + (x_r[8] >>> 8);angle_remain[9] <= angle_remain[8] - ANGLE_9;endelsebeginx_r[9] <= x_r[8] + (y_r[8] >>> 8);y_r[9] <= y_r[8] - (x_r[8] >>> 8);angle_remain[9] <= angle_remain[8] + ANGLE_9;endend//第10次旋转    always @(posedge clk or negedge rst_n)beginif(rst_n == 1'b0)beginx_r[10] <= 17'sd0;y_r[10] <= 17'sd0;angle_remain[10] <= 24'sd0;endelse if(angle_remain[9] > 24'sd0)beginx_r[10] <= x_r[9] - (y_r[9] >>> 9);y_r[10] <= y_r[9] + (x_r[9] >>> 9);angle_remain[10] <= angle_remain[9] - ANGLE_10;endelsebeginx_r[10] <= x_r[9] + (y_r[9] >>> 9);y_r[10] <= y_r[9] - (x_r[9] >>> 9);angle_remain[10] <= angle_remain[9] + ANGLE_10;endend//第11次旋转    always @(posedge clk or negedge rst_n)beginif(rst_n == 1'b0)beginx_r[11] <= 17'sd0;y_r[11] <= 17'sd0;angle_remain[11] <= 24'sd0;endelse if(angle_remain[10] > 24'sd0)beginx_r[11] <= x_r[10] - (y_r[10] >>> 10);y_r[11] <= y_r[10] + (x_r[10] >>> 10);angle_remain[11] <= angle_remain[10] - ANGLE_11;endelsebeginx_r[11] <= x_r[10] + (y_r[10] >>> 10);y_r[11] <= y_r[10] - (x_r[10] >>> 10);angle_remain[11] <= angle_remain[10] + ANGLE_11;endend//第12次旋转    always @(posedge clk or negedge rst_n)beginif(rst_n == 1'b0)beginx_r[12] <= 17'sd0;y_r[12] <= 17'sd0;angle_remain[12] <= 24'sd0;endelse if(angle_remain[11] > 24'sd0)beginx_r[12] <= x_r[11] - (y_r[11] >>> 11);y_r[12] <= y_r[11] + (x_r[11] >>> 11);angle_remain[12] <= angle_remain[11] - ANGLE_12;endelsebeginx_r[12] <= x_r[11] + (y_r[11] >>> 11);y_r[12] <= y_r[11] - (x_r[11] >>> 11);angle_remain[12] <= angle_remain[11] + ANGLE_12;endend//第13次旋转always @(posedge clk or negedge rst_n)beginif(rst_n == 1'b0)beginx_r[13] <= 17'sd0;y_r[13] <= 17'sd0;angle_remain[13] <= 24'sd0;endelse if(angle_remain[12] > 24'sd0)beginx_r[13] <= x_r[12] - (y_r[12] >>> 12);y_r[13] <= y_r[12] + (x_r[12] >>> 12);angle_remain[13] <= angle_remain[10] - ANGLE_13;endelsebeginx_r[13] <= x_r[12] + (y_r[12] >>> 12);y_r[13] <= y_r[12] - (x_r[12] >>> 12);angle_remain[13] <= angle_remain[12] + ANGLE_13;endend//第14次旋转    always @(posedge clk or negedge rst_n)beginif(rst_n == 1'b0)beginx_r[14] <= 17'sd0;y_r[14] <= 17'sd0;angle_remain[14] <= 24'sd0;endelse if(angle_remain[13] > 24'sd0)beginx_r[14] <= x_r[13] - (y_r[13] >>> 13);y_r[14] <= y_r[13] + (x_r[13] >>> 13);angle_remain[14] <= angle_remain[13] - ANGLE_14;endelsebeginx_r[14] <= x_r[13] + (y_r[13] >>> 13);y_r[14] <= y_r[13] - (x_r[13] >>> 13);angle_remain[14] <= angle_remain[13] + ANGLE_14;endend//第15次旋转    always @(posedge clk or negedge rst_n)beginif(rst_n == 1'b0)beginx_r[15] <= 17'sd0;y_r[15] <= 17'sd0;angle_remain[15] <= 24'sd0;endelse if(angle_remain[14] > 24'sd0)beginx_r[15] <= x_r[14] - (y_r[14] >>> 14);y_r[15] <= y_r[14] + (x_r[14] >>> 14);angle_remain[15] <= angle_remain[14] - ANGLE_15;endelsebeginx_r[15] <= x_r[14] + (y_r[14] >>> 14);y_r[15] <= y_r[14] - (x_r[14] >>> 14);angle_remain[15] <= angle_remain[14] + ANGLE_15;endend //第16次旋转    always @(posedge clk or negedge rst_n)beginif(rst_n == 1'b0)beginx_r[16] <= 17'sd0;y_r[16] <= 17'sd0;angle_remain[16] <= 24'sd0;endelse if(angle_remain[15] > 24'sd0)beginx_r[16] <= x_r[15] - (y_r[15] >>> 15);y_r[16] <= y_r[15] + (x_r[15] >>> 15);angle_remain[16] <= angle_remain[15] - ANGLE_16;endelsebeginx_r[16] <= x_r[15] + (y_r[15] >>> 15);y_r[16] <= y_r[15] - (x_r[15] >>> 15);angle_remain[16] <= angle_remain[15] + ANGLE_16;endend //第17次旋转    always @(posedge clk or negedge rst_n)beginif(rst_n == 1'b0)beginx_r[17] <= 17'sd0;y_r[17] <= 17'sd0;angle_remain[17] <= 24'sd0;endelse if(angle_remain[16] > 24'sd0)beginx_r[17] <= x_r[16] - (y_r[16] >>> 16);y_r[17] <= y_r[16] + (x_r[16] >>> 16);angle_remain[17] <= angle_remain[16] - ANGLE_17;endelsebeginx_r[17] <= x_r[16] + (y_r[16] >>> 16);y_r[17] <= y_r[16] - (x_r[16] >>> 16);angle_remain[17] <= angle_remain[16] + ANGLE_17;endend //第18次旋转always @(posedge clk or negedge rst_n)beginif(rst_n == 1'b0)beginx_r[18] <= 17'sd0;y_r[18] <= 17'sd0;angle_remain[18] <= 24'sd0;endelse if(angle_remain[17] > 24'sd0)beginx_r[18] <= x_r[17] - (y_r[17] >>> 17);y_r[18] <= y_r[17] + (x_r[17] >>> 17);angle_remain[18] <= angle_remain[17] - ANGLE_18;endelsebeginx_r[18] <= x_r[17] + (y_r[17] >>> 17);y_r[18] <= y_r[17] - (x_r[17] >>> 17);angle_remain[18] <= angle_remain[17] + ANGLE_18;endend //第19次旋转always @(posedge clk or negedge rst_n)beginif(rst_n == 1'b0)beginx_r[19] <= 17'sd0;y_r[19] <= 17'sd0;angle_remain[19] <= 24'sd0;endelse if(angle_remain[18] > 24'sd0)beginx_r[19] <= x_r[18] - (y_r[15] >>> 18);y_r[19] <= y_r[18] + (x_r[15] >>> 18);angle_remain[19] <= angle_remain[18] - ANGLE_19;endelsebeginx_r[19] <= x_r[18] + (y_r[18] >>> 18);y_r[19] <= y_r[18] - (x_r[18] >>> 18);angle_remain[19] <= angle_remain[18] + ANGLE_19;endend //第20次旋转    always @(posedge clk or negedge rst_n)beginif(rst_n == 1'b0)beginx_r[20] <= 17'sd0;y_r[20] <= 17'sd0;angle_remain[20] <= 24'sd0;endelse if(angle_remain[19] > 24'sd0)beginx_r[20] <= x_r[19] - (y_r[19] >>> 19);y_r[20] <= y_r[19] + (x_r[19] >>> 19);angle_remain[20] <= angle_remain[19] - ANGLE_20;endelsebeginx_r[20] <= x_r[19] + (y_r[19] >>> 19);y_r[20] <= y_r[19] - (x_r[19] >>> 19);angle_remain[20] <= angle_remain[19] + ANGLE_20;endend
/****************************************************/
//每个phi值的所在现象的流水线延迟always @(posedge clk or negedge rst_n)beginif(rst_n == 1'b0)beginquadrant_r[0] <= 2'b00;         //不能合并着写quadrant_r[1] <= 2'b00;quadrant_r[2] <= 2'b00;quadrant_r[3] <= 2'b00;quadrant_r[4] <= 2'b00;quadrant_r[5] <= 2'b00;quadrant_r[6] <= 2'b00;quadrant_r[7] <= 2'b00;quadrant_r[8] <= 2'b00;quadrant_r[9] <= 2'b00;quadrant_r[10] <= 2'b00;quadrant_r[11] <= 2'b00;quadrant_r[12] <= 2'b00;quadrant_r[13] <= 2'b00;quadrant_r[14] <= 2'b00;quadrant_r[15] <= 2'b00;quadrant_r[16] <= 2'b00;quadrant_r[17] <= 2'b00;quadrant_r[18] <= 2'b00;quadrant_r[19] <= 2'b00;quadrant_r[20] <= 2'b00;endelsebeginquadrant_r[0]   <= quadrant_flag;quadrant_r[1]   <= quadrant_r[0];quadrant_r[2]   <= quadrant_r[1];quadrant_r[3]   <= quadrant_r[2];quadrant_r[4]   <= quadrant_r[3];quadrant_r[5]   <= quadrant_r[4];quadrant_r[6]   <= quadrant_r[5];quadrant_r[7]   <= quadrant_r[6];quadrant_r[8]   <= quadrant_r[7];quadrant_r[9]   <= quadrant_r[8];quadrant_r[10]  <= quadrant_r[9];quadrant_r[11]  <= quadrant_r[10];quadrant_r[12]  <= quadrant_r[11];quadrant_r[13]  <= quadrant_r[12];quadrant_r[14]  <= quadrant_r[13];quadrant_r[15]  <= quadrant_r[14];quadrant_r[16]  <= quadrant_r[15];quadrant_r[17]  <= quadrant_r[16];quadrant_r[18]  <= quadrant_r[17];quadrant_r[19]  <= quadrant_r[18];quadrant_r[20]  <= quadrant_r[19];endend/****************************************************/  assign ret_x    = x_r[20];assign ret_y    = y_r[20];assign quadrant = quadrant_r[20];
/****************************************************/
endmodule

后处理将象限变换过的坐标还原:

/****************************************************/module  Cordic_Post(clk,rst_n,ret_x,ret_y,quadrant,sin_phi,cos_phi);/****************************************************/input                   clk;input                   rst_n;input   signed  [16:0]  ret_x;input   signed  [16:0]  ret_y;input           [1:0]   quadrant;output  signed  [16:0]  sin_phi;output  signed  [16:0]  cos_phi;/****************************************************/  reg     signed  [16:0]  sin_phi_r;reg     signed  [16:0]  cos_phi_r;/****************************************************/always @(posedge clk or negedge rst_n)beginif(rst_n == 1'b0)beginsin_phi_r <= 17'sd0;cos_phi_r <= 17'sd0;endelsecase(quadrant)                  //根据原始角度所在象限,还原其三角函数值sin_phi和cos_phi2'd01:                      //若再乘上极径和模长补偿因子,则实现直角坐标系变换begincos_phi_r <= ret_x;sin_phi_r <= ret_y;                         end2'd10:begincos_phi_r <= ~ret_y + 1'b1;sin_phi_r <= ret_x;end2'd11:begincos_phi_r <= ret_y;sin_phi_r <= ~ret_x + 1'b1;end 2'd00:begincos_phi_r <= ret_x;sin_phi_r <= ret_y;enddefault:beginsin_phi_r <= 17'sd0;cos_phi_r <= 17'sd0;endendcaseend/****************************************************/assign  sin_phi = sin_phi_r;assign  cos_phi = cos_phi_r;
/****************************************************/
endmodule

在四个象限分别选取一个角度进行仿真,仿真结果如下图所示:

角度从输入到转换完毕,一共延时21个时钟周期。正好是预处理(1个周期)+旋转(20个周期)的结果。

2. 向量模式

至于向量模式,只要理解的算法思想,在编程上大同小异,如果要处理的坐标比较少,可以不采用流水线的方式。FPGA上用非流水线方式实现,Verilog主要代码片段如下,这次是用ROM存着旋转的固定角度值,利用addr地址线来读取相应的旋转角度:

3'd2:if(times < 5'd16)beginif( yn_r !==22'd0)                          //当旋转到y=0时,提前结束,否则继续旋转反而影响精度beginif((yn_r[21]))                      //yn最高位为1时,即坐标在第四象限,则逆时针旋转beginxn_r <= xn_r - (yn_r >>> times);yn_r <= yn_r + (xn_r >>> times);addr_r <= addr_r + 1'd1;times <= addr_r;zn_r <= zn_r-angle;i <= 3'd2;endelsebegin                                   //反之,坐标在第一象限,则顺时针旋转xn_r <= xn_r + (yn_r >>> times);yn_r <= yn_r - (xn_r >>> times);addr_r <= addr_r + 1'd1;times <= addr_r;zn_r <= zn_r+angle;i <= 3'd2;endendelsebegini <= i +1'b1;   endendelsebegini <= i +1'b1;end

至此,cordic基于圆周系统的算法总结完毕,至于还有基于线性系统、双曲系统来实现其它运算,等有机会了再学习。

Cordic算法——verilog实现相关推荐

  1. CORDIC算法原理详解及其Verilog实现

    CORDIC算法原理详解及其Verilog实现 本文的verilog代码 链接:https://pan.baidu.com/s/1GGbRjxO5CxoIODQAg1l6Lw 提取码:jo0h *本文 ...

  2. CORDIC算法计算复数相位角(含verilog源码)

    前言   截止2022年2月15日,中国科学院大学<高等数字集成电路分析及设计>课程终于完结,所以我计划分享几个自己完成的实践作业,供大家交流学习. 设计收获 对cordic算法有了清晰的 ...

  3. 02、cordic算法原理及verilog实现

    发布时间:2021/11/25 发布版本:2021-02 一.cordic算法原理 cordic算法主要应用于三角函数计算,尽管现在随着大规模存储器的普及,设计人员可以将所需三角函数值全部存储在存储器 ...

  4. verilog实现基于Cordic算法的双曲函数计算

    Cordic算法可以用FPGA硬件来实现三角函数,向量旋转,指数函数以及三角函数等数值计算,它是一种从一般的矢量旋转方程中推导得出.采用用不断的旋转求出对应的正弦余弦值,是一种近似求解法.旋转的角度很 ...

  5. 使用帅气的cordic算法进行坐标系互转及log10的求解

    参考博客 https://blog.csdn.net/u010712012/article/details/77755567 https://blog.csdn.net/Reborn_Lee/arti ...

  6. CORDIC算法的matlab和FPGA实现

    目录 1.算法原理 2.matlab实现 2.1 在已知坐标,用cordic算法计算相角 2.2 在已知相角,用cordic算法计算正余弦 3.FPGA实现 3.1 简单的状态机结构 3.1.1 ve ...

  7. cordic算法详解

    作者:善良的一休君 来源:CSDN 原文:https://blog.csdn.net/qq_39210023/article/details/77456031 版权声明:本文为博主原创文章,转载请附上 ...

  8. CORDIC算法详解(五)-统一的 CORDIC 算法形式

    CORDIC算法详解(五)- 统一的 CORDIC 算法形式 文章目录 CORDIC算法详解(五)- 统一的 CORDIC 算法形式 5 统一的 CORDIC 算法形式 相关参考资料及源码   网上有 ...

  9. FPGA实现Cordic算法求解arctan和sqr(x*2 + y* 2)

    一. 简介 由于在项目中需要使用的MPU6050,进行姿态解算,计算中设计到**arctan 和 sqr(x2 + y 2),**这两部分的计算,在了解了一番之后,发现Cordic算法可以很方便的一次 ...

最新文章

  1. php使用位运算来实现日留存的算法
  2. C语言实现数据结构之栈的详解
  3. PHP输出表格的方法
  4. ajax 前端怎么处理数据,如何使用ajax异步处理JSon数据
  5. Apache ZooKeeper - 使用原生的API操作ZK_ACL权限
  6. PMCAFF微课堂|简书大咖彭小六:6年PM是如何利用阅读进行职场提升
  7. kickstart+TFTP+PXE+NFS+DHCP批量安装系统,raid
  8. 初始化跟路由相关的定时器
  9. Python+Opencv图像处理新手入门教程(二):颜色空间转换,图像大小调整,灰度直方图
  10. 机器学习基础(十四)—— 统计计数、majority count 与其数学记号
  11. Flex 4 的ComboBox下拉框滚动条Scroller(VerticalScrollBar)的thumb过小问题的解决
  12. RotatedRect类opencv
  13. RocketMQ 源码之 异步和同步请求 以及异步的回调 是怎么做到的
  14. 汇编指令与机器码地相互转换
  15. 给大家分享学好 Python 的 11 个优秀资源
  16. 史上最搞笑的程序员段子,你看懂了吗?
  17. PS技巧分享,不容错过
  18. 苹果电脑如何同时运行Mac和Windows--pd18
  19. C语言建立循环单链表并输出
  20. 【canvas绘制图形】

热门文章

  1. GRE over IPSEC ×××
  2. android studio 链接编辑,Android Studio怎么连接手机测试程序?
  3. join为什么每个字符都分割了 js_js的join()与 split() (转)
  4. SQL Server基础之存储过程
  5. oracle 伪列访问序列,Oracle数据库对象,同义词、序列、视图、索引
  6. 虚拟机实现二层交换机_局域网SDN技术硬核内幕 5 虚拟化网络的实现
  7. 计算机起源于发展论文,关于计算机起源及发展的论文1500字左右,论文形式.
  8. 通达信板块监控指标_【精选指标】通达信创业板涨停变色主图指标,助你股海捉龙擒牛!...
  9. layui中laydate兼容ie_layui菜鸟教程--乐字节前端
  10. MindMotion MM32F3277 SoftI2C功能测试