心理咨询 网站模版,wordpress明星,温州做网站优化,人才交流网站建设与设计1-设计流程
● 了解cordic 算法原理#xff0c;公式#xff0c;模式#xff0c;伸缩因子#xff0c;旋转方向等#xff0c;推荐以下链接视频了解 cordic 算法。哔哩哔哩-cordic算法原理讲解 ● 用matlab 或者 c 实现一遍算法 ● 在FPGA中用 verilog 实现#xff0c;注意…1-设计流程
● 了解cordic 算法原理公式模式伸缩因子旋转方向等推荐以下链接视频了解 cordic 算法。哔哩哔哩-cordic算法原理讲解 ● 用matlab 或者 c 实现一遍算法 ● 在FPGA中用 verilog 实现注意使用有符号变量以及小数点定点化处理
备注 在verilog 需要用 ram 存储的值列举了13次迭代的tan值和对应角度
2-RTL
分享自己写的一个cordic rtl
2-1 测试代码 ,测试 一二三四象限内角度的sin cos 值。
module test_my_cordic(input i_clk,input i_rst);reg signed [31:0] r_angle;
reg r_valid ;wire w_ready;
wire signed [31:0] r_x 39796;
wire signed [31:0] r_y 0;(*dont_touch true*)
my_cordic inst_my_cordic
(.i_clk (i_clk),.i_rst (i_rst),.i_iteration_count (16), //设置迭代次数 最大16次.i_setx (r_x),.i_sety (r_y),.i_set_angle (r_angle),.i_valid (r_valid),.o_sin (),.o_cos (),.o_valid (),.o_ready (w_ready)
);/* 测试 第四象限 0 ~ -90°
always (posedge i_clk or posedge i_rst)
beginif (i_rst) beginr_angle 0;end else if (r_angle -5898240 w_ready) beginr_angle 0; end else if (w_ready r_valid) beginr_angle r_angle - 655360; end else beginr_angle r_angle; end
end
*/// 测试 第一象限 0 ~ 90°
always (posedge i_clk or posedge i_rst)
beginif (i_rst) beginr_angle 0;end else if (r_angle 5898240 w_ready) beginr_angle 0; end else if (w_ready r_valid) beginr_angle r_angle 655360; end else beginr_angle r_angle; end
end/* //测试 第三象限 -180 ~ -90°
always (posedge i_clk or posedge i_rst)
beginif (i_rst) beginr_angle -11796480;end else if (r_angle -5898240 w_ready) beginr_angle -11796480; end else if (w_ready r_valid) beginr_angle r_angle 655360; end else beginr_angle r_angle; end
end
*//*// 测试 第二象限 90° ~ 180 °
always (posedge i_clk or posedge i_rst)
beginif (i_rst) beginr_angle 5898240;end else if (r_angle 11796480 w_ready) beginr_angle 0; end else if (w_ready r_valid) beginr_angle r_angle 655360; end else beginr_angle r_angle; end
end
*/always (posedge i_clk or posedge i_rst)
beginif (i_rst) r_valid 0;else if (w_ready r_valid)r_valid 0;else if (w_ready)r_valid 1; else r_valid 0;
endendmodule2-2 核心代码
//运算公式
//x(i1) x(i) - y(i) * di * 2^(-i)
//y(i1) y(i) x(i) * di * 2^(-i)
//z(i1) z(i) - arctan(di * 2^(-i))
//author 技术小白爱FPGA
//备注cordic 算法旋转模式迭代次数固定 16次可以自己任意设置最大16次module my_cordic (input i_clk ,input i_rst ,input [4:0] i_iteration_count ,input signed [31:0] i_setx ,input signed [31:0] i_sety ,input signed [31:0] i_set_angle ,input i_valid ,output signed [31:0] o_sin ,output signed [31:0] o_cos ,output o_valid ,output o_ready );wire signed [31:0] r_arctan [0:15];
wire r_di ;reg signed [31:0] r_sin;
reg signed [31:0] r_cos;
reg signed [31:0] r_setx ;
reg signed [31:0] r_sety ;
reg signed [31:0] r_angle ;
reg [4:0] r_count;
reg r_run_cal;
reg ro_valid ;
reg ro_ready ;
reg [1:0] r_site;assign o_sin r_sin;
assign o_cos r_cos;
assign o_ready ro_ready;
assign o_valid ro_valid;//存储 arctan 值整体表示-----扩大2^16倍数相当于将小数点定在16bit位置上
assign r_arctan[0] 2949120;
assign r_arctan[1] 1740967;
assign r_arctan[2] 919879;
assign r_arctan[3] 466945;
assign r_arctan[4] 234378;
assign r_arctan[5] 117303;
assign r_arctan[6] 58666;
assign r_arctan[7] 29334;
assign r_arctan[8] 14667;
assign r_arctan[9] 7333;
assign r_arctan[10] 3666;
assign r_arctan[11] 1833;
assign r_arctan[12] 916;
assign r_arctan[13] 458;
assign r_arctan[14] 229;
assign r_arctan[15] 114;//判断旋转的方向
assign r_di (r_angle 0 r_run_cal)?1:0;//运算迭代 --- 算数右移不改变符号位 如果使用 ,移位高位补0
always (posedge i_clk)
beginif (i_valid) beginr_setx i_setx;r_sety i_sety;endelse if (r_run_cal r_di ) beginr_setx r_setx - (r_sety r_count);r_sety r_sety (r_setx r_count); end else if (r_run_cal !r_di) beginr_setx r_setx (r_sety r_count);r_sety r_sety - (r_setx r_count); end
end//旋转角度的迭代,输入角度的象限处理
always (posedge i_clk )
begin// 处理 一四象限 -90° ~ 90°if (i_valid (i_set_angle -5898240 i_set_angle 5898240 ) ) beginr_angle i_set_angle;r_site 2b00;// 处理 二象限 90° ~ 180°end else if (i_valid (i_set_angle 5898240 i_set_angle 11796480 )) beginr_angle 11796480 - i_set_angle;r_site 2b10;// 处理 三象限 -180° ~ -90°end else if (i_valid (i_set_angle -11796480 i_set_angle -5898240 )) beginr_angle -11796480 - i_set_angle ;r_site 2b11;end else if (r_di r_run_cal) beginr_angle r_angle - r_arctan[r_count]; endelse if (!r_di r_run_cal) beginr_angle r_angle r_arctan[r_count]; end else beginr_angle r_angle;r_site r_site ;end
end//迭代运算次数
always (posedge i_clk or posedge i_rst)
beginif (i_rst) beginr_count 0;end else if (r_count i_iteration_count -1) beginr_count 0;endelse if (r_run_cal) beginr_count r_count 1;end
end//迭代运算标志
always (posedge i_clk or posedge i_rst)
beginif (i_rst) beginr_run_cal 0;endelse if (r_count i_iteration_count -1) beginr_run_cal 0; endelse if(i_valid) beginr_run_cal 1; endelse beginr_run_cal r_run_cal; end
end//最终输出的 sin cos 值
always (posedge i_clk or posedge i_rst)
beginif (i_rst) beginr_sin 0;r_cos 0;endelse if (r_site 2b00 r_count i_iteration_count -1) beginr_sin r_sety;r_cos r_setx; end else if (r_site 2b10 r_count i_iteration_count -1) beginr_sin r_sety;r_cos -r_setx; end else if (r_site 2b11 r_count i_iteration_count -1) beginr_sin r_sety;r_cos -r_setx; end
endalways (posedge i_clk or posedge i_rst)
beginif (i_rst) beginro_ready 1;endelse if (i_valid || r_run_cal) beginro_ready 0; end else beginro_ready 1;end
end//最终输出的 sin cos valid 信号
always (posedge i_clk or posedge i_rst)
beginif (i_rst) ro_valid 0;else if (r_count i_iteration_count -1)ro_valid 1; else ro_valid 0;
endendmodule2-3 tb仿真代码
module tb_cordic();reg i_clk;
reg i_rst;initial begin i_clk 0;i_rst 1;#100(posedge i_clk)i_rst 0;
endalways #10 i_clk ~i_clk;test_my_cordic inst_test_my_cordic (.i_clk(i_clk), .i_rst(i_rst));endmodule3-仿真
a. 首先 有符号的信号需要设置 小数点位数如下图所示 b. 以第一象限为例子0 ~ 90° c. 运算处理 持续周期 就是 迭代次数
d. 可借助 计算机科学模式验证结果
4-可优化空间
● r_ange逻辑级数
● 360°以内高于180°和小于-180°处理
● 迭代运算拆成流水线形式
● 加上向量模式
● 整体其它逻辑的优化