使用verilog 实现 cordic 算法 ----- 旋转模式

article/2025/8/16 14:26:17

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;	
endendmodule

2-2 核心代码:

//运算公式:
//x(i+1) = x(i) - y(i) * di * 2^(-i)
//y(i+1) = y(i) + x(i) * di * 2^(-i)
//z(i+1) = 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  <= 2'b00;// 处理 二象限 90° ~ 180°end else if (i_valid && (i_set_angle > 5898240 && i_set_angle <= 11796480 )) beginr_angle <= 11796480 - i_set_angle;r_site  <= 2'b10;// 处理 三象限 -180° ~ -90°end else if (i_valid && (i_set_angle >= -11796480 && i_set_angle < -5898240 )) beginr_angle <= -11796480 - i_set_angle ;r_site  <= 2'b11;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 == 2'b00 && r_count == i_iteration_count -1) beginr_sin <= r_sety;r_cos <= r_setx;		end else if (r_site == 2'b10 && r_count == i_iteration_count -1) beginr_sin <= r_sety;r_cos <= -r_setx;	end else if (r_site == 2'b11 && 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;	
endendmodule

2-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));endmodule

3-仿真

a. 首先 有符号的信号需要设置 小数点位数,如下图所示:
在这里插入图片描述
b. 以第一象限为例子:0 ~ 90°
在这里插入图片描述
c. 运算处理 持续周期 就是 迭代次数:
在这里插入图片描述

d. 可借助 计算机科学模式验证结果:
在这里插入图片描述

4-可优化空间

● r_ange逻辑级数;
● 360°以内,高于180°和小于-180°处理
● 迭代运算拆成流水线形式;
● 加上向量模式
● 整体其它逻辑的优化

http://www.hkcw.cn/article/gWtketWcut.shtml

相关文章

Openharmony 命令行工具hdc的获取与安装

hdc(OpenHarmony Device Connector)是为开发人员提供的用于设备连接调试的命令行工具,该工具需支持部署在 Windows/Linux/Mac 等系统上与 OpenHarmony 设备(或模拟器)进行连接调试通信。hdc是 OpenHarmony 应用、硬件开发及测试人员的调试、入门工具。 本文以在Window系统…

FPGA-DDS信号发生器

FPGA-DDS信号发生器 DDS基本原理 ​ FPGA实现的DDS&#xff08;直接数字频率合成&#xff09;波形生成器是一种高效、灵活的数字信号生成技术&#xff0c;广泛应用于通信、雷达和测试设备中。其核心原理是通过数字计算生成特定频率的波形。 ​ DDS通过相位累加、查找表(LUT)…

紫光同创FPGA实现AD9280数据采集转UDP网络传输,分享PDS工程源码和技术支持和QT上位机

目录 1、前言工程概述免责声明 2、相关方案推荐我已有的所有工程源码总目录----方便你快速找到自己喜欢的项目紫光同创FPGA相关方案推荐我这里已有的以太网方案本方案在Xilinx系列FPGA的应用方案 3、设计思路框架工程设计原理框图AD输入源AD9280数据采集AD9280数据缓存控制模块…

不用官方EDA怎么开发FPGA?

目前FPGA的开发和官方的EDA工具是高度绑定的&#xff0c;用哪家的芯片只能用其配套的EDA工具进行开发&#xff08;综合可选工具&#xff0c;布局布线没有可选的工具&#xff09;&#xff0c;那么有没有其他的开发方式呢&#xff1f;今天就介绍一个使用开源工具链来开发FPGA的方…

群体智能优化算法-沙丁鱼群优化算法(Salp Swarm Algorithm (SSA,含Matlab源代码)

摘要 Salp Swarm Algorithm&#xff08;SSA&#xff0c;沙丁鱼群优化算法&#xff09;是一种基于群体智能的元启发式优化算法&#xff0c;灵感来自沙丁鱼群在水中的游动模式。SSA 在求解复杂优化问题时表现出良好的全局搜索能力和收敛性能。本文详细介绍SSA的数学原理&#xf…

Linux网络基础全面解析:从协议分层到局域网通信原理

Linux系列 文章目录 Linux系列前言一、计算机网络背景1.1 认识网络1.2 认识协议 二、网络协议初识2.1 协议分层2.2 OSI七层模型2.3 TCP/IP协议栈2.4 网络协议栈与OS的关系2.5 网络协议在网络传输时的作用 三、网络通信局域网通信的安全隐患与应对总结 前言 Linux系统部分的学习…

【网络协议】一文带你搞懂Tcp和Udp(万字详解)

文章目录 前言一、端口号端口号的范围划分 二、UDP和TCP2.1 UDP2.2 UDP的特点 三、TCP四、TCP的十个核心机制1.确认应答机制2.超时重传3.连接管理--三次握手 四次挥手**三次握手**四次挥手 4.滑动窗口5.流量控制6.阻塞控制7.延迟应答8.捎带应答9.粘包问题10.异常情况 前言 再上…

Kile5报错—>Target ‘Target 1‘ uses ARM-Compiler ‘Default Compiler Version 5‘ which is not available

一、错误分析 出现这个报错Target l uses ARM-Compiler Default Compiler Version 5 which is not available.是因为使用的 ARM 编译器“ Use Default Compiler Version 5”不可用&#xff0c;这是因为最新版本Keil5不再自动提供编译器&#xff08;旧版本是自动安装编译器的&…

假水玩具超半数硼迁移超标 安全隐患引担忧

网红“假水”在部分中小学校园周边和电商平台热销,这种颜色丰富、黏性强的起泡胶玩具,别称史莱姆、水晶泥或“不沾手的水”,因其解压特性和价格低廉受到欢迎。然而,这类玩具存在安全隐患。电商平台上的“假水”名称和内容五花八门,价格低廉且销量大。六一儿童节前夕,从多…

美国提出伊核协议新方案 伊朗将回应 基于国家利益

伊朗外交部长阿巴斯阿拉格齐表示,阿曼外交大臣赛义德巴德尔布赛义迪访问了德黑兰,并介绍了美国提出的新伊核协议部分内容。伊朗将根据原则、国家利益和人民权利对美方提议作出回应。美国白宫新闻秘书卡罗琳莱维特称,美国中东问题特使史蒂文威特科夫已向伊朗发出一份详细的可…

印军高官称赞印巴两国军人都很理性 避免核冲突风险

在新加坡出席香格里拉对话会的印度国防参谋长阿尼尔乔汉5月31日在接受媒体采访时,称赞印度和巴基斯坦军人都很理性,不会因常规冲突诱发核冲突。他表示,当冲突发生时,最理性的人是身穿制服的人,因为他们明白冲突可能朝任何一方倾斜,并且理解这种冲突的后果。此前,乔汉在接…

买基金亏损30万状告银行 法院判了 二审驳回投资者请求

一位年过八旬的投资者在2021年投入105万元购买了一只公募基金产品,两年多时间亏损约30万元,随后将相关代销银行告上法庭,要求赔偿损失。案件经过两次审理,一审法院判决银行承担70%的损失赔偿责任并支付利息,但二审法院认为投资者自主决定购买理财产品,且亏损原因是金融市…

江苏省城市足球联赛 全民足球热潮席卷江苏

虎扑App紧急新增了“江苏联”频道。在“苏超”第三轮于5月31日开打之前,一票难求和诸梗风行的情势深度交织,让越来越多的网友沉醉其间。玩梗层出不穷:“我从来不关心足球,这次特别关注”“我都不是球迷,我就是为了争口气”“没有假球,全是世仇”“比赛第一,友谊第十四”…

安徽4300多万亩小麦丰收 生产形势良好

安徽省农业农村厅发布的信息显示,2024年安徽小麦收获期间天气状况良好,有利于机械化收割。截至5月31日17时,全省已收割小麦超过3833万亩,进度接近九成。安徽作为中国农村改革的发源地之一,是中国主要的粮食生产和调出省份,其粮食种植面积和产量一直位居全国前列。2024年,…

孙中山长孙女孙穗瑛去世 享年103岁 家人举办追思会

2025年5月,孙穗瑛的家人在美国加州为她举办了追思会。孙中山长孙女孙穗瑛于2025年3月24日在美国去世,享年103岁。孙穗瑛出生于1922年1月16日,出生地为中国广州,父亲是时任广州市长的孙科,母亲为陈淑英。她的两位兄长孙治平、孙治强以及妹妹孙穗华此前均已辞世。童年时期,…

知情人回应迪士尼情侣和一家三口扭打 因拍照起冲突

5月31日,有网友发布视频称,上海迪士尼内一对情侣和一家三口发生冲突并扭打起来,此事引发热议。视频显示,双方在现场激烈争执,周围游客纷纷上前劝阻。据了解,事件发生在5月31日,地点并非排队区域,而是游客自由打卡拍照的地方。情侣与一家三口因拍照问题产生矛盾,进而发…

2025年渗透测试面试题总结-匿名[校招]渗透测试工程师(题目+回答)

安全领域各种资源&#xff0c;学习文档&#xff0c;以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具&#xff0c;欢迎关注。 目录 匿名[校招]渗透测试工程师 1. 自我介绍 2. 印象深刻的一次渗透 3. 渗透测试流程 4. SQL注入原理及Payl…

“公安英模”邱建军雕像揭幕 缅怀英烈激励警心

6月1日是邱建军牺牲一周年,当天,他的雕像回到了汉兴派出所,仿佛又将大家带回到他保护群众安全而壮烈牺牲的那一瞬间,诉说着往昔的故事。为缅怀英烈、弘扬楷模精神,激励担当作为、凝聚奋进力量,江汉区公安分局邀请武汉泥塑艺术家胡作林制作了邱建军的雕像,并将其存放在汉…

硬核龙舟祝福端午 粽香飘飘竞渡忙

今天,端午节粽香飘飘、龙舟竞渡在守护家国安宁的“赛道”上战士们时刻奋楫争先硬核端午壁纸上新,请查收↓责任编辑:zhangxiaohua

专家谈以色列在约旦河西岸行事激进 侵蚀“两国方案”基础

当地时间5月30日,以色列国防部长卡茨宣布将在约旦河西岸地区建立“犹太人以色列国家”。此前,以色列安全内阁已决定在该地区新建22处犹太人定居点。中国国际问题研究院助理研究员李子昕指出,当前以色列的激进做法源于国内形势。以色列在加沙地带和约旦河西岸继续开展军事行动…