当前位置: 首页 > news >正文

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

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°处理
● 迭代运算拆成流水线形式;
● 加上向量模式
● 整体其它逻辑的优化

相关文章:

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

1-设计流程 ● 了解cordic 算法原理&#xff0c;公式&#xff0c;模式&#xff0c;伸缩因子&#xff0c;旋转方向等&#xff0c;推荐以下链接视频了解 cordic 算法。哔哩哔哩-cordic算法原理讲解 ● 用matlab 或者 c 实现一遍算法 ● 在FPGA中用 verilog 实现&#xff0c;注意…...

2.14寒假

这几天复习的搜索把之前做过的题目看了一下。 解析&#xff1a;int dx[5]{0,0,1,0,-1}; 和 int dy[5]{0,1,0,-1,0};&#xff1a;这两个数组用于表示上下左右四个方向的偏移量&#xff0c;方便在 DFS 中访问相邻的元素。o 和 p 分别表示当前搜索位置的行和列。边界条件判断&…...

基于逻辑概率的语义信道容量(Semantic Channel Capacity)和语义压缩理论(Semantic Compression Theory)

基于逻辑概率的语义信道容量&#xff08;Semantic Channel Capacity&#xff09;和语义压缩理论&#xff08;Semantic Compression Theory&#xff09;是语义通信&#xff08;Semantic Communication, SemCom&#xff09;的核心研究方向&#xff0c;它们旨在优化通信效率&#…...

DeepSeek R1本地部署教程

尽管许多卖课博主声称能轻松运行满血版DeepSeek R1&#xff0c;但满血版R1模型参数高达671B&#xff0c;仅模型文件就需要404GB存储空间&#xff0c;运行时更需要约1300GB显存。 对于没有卡的普通玩家来说&#xff0c;运行的条件苛刻&#xff0c;且门槛极高。基于此&#xff0…...

CEF132编译指南 MacOS 篇 - 获取 CEF 源码 (五)

1. 引言 在完成了所有必要工具的安装和配置之后&#xff0c;我们正式进入获取 CEF132 源码的阶段。对于 macOS 平台&#xff0c;CEF 的源码获取过程需要特别注意不同芯片架构&#xff08;Intel 和 Apple Silicon&#xff09;的区别以及版本管理。本篇将作为 CEF132 编译指南系…...

TypeScript装饰器 ------- 学习笔记分享

目录 一. 简介 二. 类装饰器 1. 基本语法 2. 应用举例 3. 关于返回值 4. 关于构造类型 5. 替换被装饰的类 三. 装饰器工厂 四. 装饰器组合 五. 属性装饰器 1. 基本语法 2. 关于属性遮蔽 3. 应用举例 六. 方法装饰器 1. 基本语法 2. 应用举例 七. 访问器装饰器 …...

FPGA实现UltraScale GTH光口视频转USB3.0传输,基于FT601+Aurora 8b/10b编解码架构,提供2套工程源码和技术支持

目录 1、前言工程概述免责声明 2、相关方案推荐我已有的所有工程源码总目录----方便你快速找到自己喜欢的项目我这里已有的 GT 高速接口解决方案本博已有的FPGA驱动USB通信方案 3、工程详细设计方案工程设计原理框图输入Sensor之-->OV5640摄像头动态彩条输入视频之-->ADV…...

蓝桥杯篇---实时时钟 DS1302

文章目录 前言特点简介1.低功耗2.时钟/日历功能3.32字节的额外RAM4.串行接口 DS1302 引脚说明1.VCC12.VCC23.GND4.CE5.I/O6.SCLK DS1302 寄存器1.秒寄存器2.分钟寄存器3.小时寄存器4.日寄存器5.月寄存器6.星期寄存器7.年寄存器8.控制寄存器 DS1302 与 IAP25F2K61S2 的连接1.CE连…...

C语言蓝桥杯1003: [编程入门]密码破译

要将"China"译成密码&#xff0c;译码规律是&#xff1a;用原来字母后面的第4个字母代替原来的字母&#xff0e; 例如&#xff0c;字母"A"后面第4个字母是"E"&#xff0e;"E"代替"A"。因此&#xff0c;"China"应译…...

【MySQL在Centos 7环境安装】

文章目录 一. 卸载不必要的环境二. 检查系统安装包三. 卸载这些默认安装包四. 获取mysql官⽅yum源五. 安装mysql yum 源&#xff0c;对⽐前后yum源六. 看看能不能正常⼯作七. 安装mysql服务八. .查看配置⽂件和数据存储位置九. 启动服务并查看服务是否存在十. 登陆⽅法十一. 设…...

科技引领未来,中建海龙C-MiC 2.0技术树立模块化建筑新标杆

在建筑行业追求高效与品质的征程中&#xff0c;中建海龙科技有限公司&#xff08;简称“中建海龙”&#xff09;以其卓越的创新能力和强大的技术实力&#xff0c;不断书写着装配式建筑领域的新篇章。1 月 10 日&#xff0c;由深圳安居集团规划&#xff0c;中建海龙与中海建筑共…...

玩转观察者模式

文章目录 什么是观察者模式解决方案结构适用场景实现方式观察者模式优缺点优点:缺点:什么是观察者模式 观察者模式通俗点解释就是你在观察别人,别人有什么变化,你就做出什么调整。观察者模式是一种行为设计模式,允许你定义一种订阅机制,可在对象事件发生时通知多个“观察…...

Baklib知识中台构建企业智能运营核心架构

内容概要 在数字化转型的浪潮中&#xff0c;企业对于知识的系统化管理需求日益迫切。Baklib作为新一代的知识中台&#xff0c;通过构建智能运营核心架构&#xff0c;为企业提供了一套从知识汇聚到场景化落地的完整解决方案。其核心价值在于将分散的知识资源整合为统一的资产池…...

Anaconda +Jupyter Notebook安装(2025最新版)

Anaconda安装&#xff08;2025最新版&#xff09; Anaconda简介安装1&#xff1a;下载anaconda安装包2&#xff1a; 安装anaconda3&#xff1a;配置环境变量4&#xff1a;检查是否安装成功5&#xff1a;更改镜像源6&#xff1a;更新包7&#xff1a;检查 Jupyter Notebook一.Jup…...

正成为现代城市发展的必然趋势的智慧交通开源了

智慧交通视觉监控平台是一款功能强大且简单易用的实时算法视频监控系统。它的愿景是最底层打通各大芯片厂商相互间的壁垒&#xff0c;省去繁琐重复的适配流程&#xff0c;实现芯片、算法、应用的全流程组合&#xff0c;从而大大减少企业级应用约95%的开发成本。通过人流密集检测…...

手撕Transformer编码器:从Self-Attention到Positional Encoding的PyTorch逐行实现

Transformer 编码器深度解读 代码实战 1. 编码器核心作用 Transformer 编码器的核心任务是将输入序列&#xff08;如文本、语音&#xff09;转换为富含上下文语义的高维特征表示。它通过多层自注意力&#xff08;Self-Attention&#xff09;和前馈网络&#xff08;FFN&#x…...

Webpack和Vite插件的开发与使用

在现代开发中一般各公司都有自己的监控平台&#xff0c;对前端而言如果浏览器报错的话就可以通过埋点收集错误日志&#xff0c;再结合sourcemap文件可以帮助我们定位到错误代码&#xff0c;帮助我们排查问题。这里就记录一下之前在webpack和vite两个环境中的插件开发&#xff0…...

HTTP的状态码

HTTP 状态码 当浏览者访问一个网页时&#xff0c;浏览者的浏览器会向网页所在服务器发出请求。当浏览器接收并显示网页前&#xff0c;此网页所在的服务器会返回一个包含 HTTP 状态码的信息头&#xff08;server header&#xff09;用以响应浏览器的请求。 常见的HTTP状态码 …...

Python函数-装饰器

装饰器 写好的函数&#xff0c;不做任何修改&#xff0c;就可以改变执行内容&#xff0c;在其头或尾部加入新的流程代码本质上就是使用函数嵌套&#xff0c;在内部嵌套定义的函数中调用原函数&#xff0c;从而可读在前或后加入新的代码使用的关键&#xff1a; 将原函数作为参数…...

【数据可视化-17】基于pyecharts的印度犯罪数据可视化分析

&#x1f9d1; 博主简介&#xff1a;曾任某智慧城市类企业算法总监&#xff0c;目前在美国市场的物流公司从事高级算法工程师一职&#xff0c;深耕人工智能领域&#xff0c;精通python数据挖掘、可视化、机器学习等&#xff0c;发表过AI相关的专利并多次在AI类比赛中获奖。CSDN…...

离线优先的Markdown编辑器:inkdown如何实现极致专注写作

1. 项目概述&#xff1a;一个为创作者而生的轻量级写作工具如果你和我一样&#xff0c;经常需要在不同设备间切换写作&#xff0c;或者对市面上那些功能臃肿、界面花哨的写作软件感到厌倦&#xff0c;那么你可能会对inkdown产生兴趣。这不是一个功能大而全的“巨无霸”&#xf…...

AI与空间计算融合:在Vision Pro上部署与优化机器学习模型的工程实践

1. 项目概述&#xff1a;当苹果Vision Pro遇上开源AI&#xff0c;一场空间计算的“化学反应”最近在GitHub上闲逛&#xff0c;发现了一个挺有意思的项目&#xff0c;叫imclab/Apple-Vision-PRO-AR-VR-XR-AI。光看这个仓库名&#xff0c;信息量就爆炸了&#xff0c;直接把苹果的…...

056、步进电机加减速曲线:梯形曲线

步进电机加减速曲线:梯形曲线 从一次丢步事故说起 去年做一台三轴点胶机,Z轴用57步进电机带丝杆,升降频率设成固定2000Hz。客户反馈点胶到第37个点的时候,针头突然扎歪,胶水涂到PCB板外面去了。我连夜赶去现场,用示波器抓驱动器的STEP脉冲——好家伙,电机在启动瞬间脉…...

Scikit-learn:从数据到结构——无监督学习的最小闭环

在 Scikit-learn 中&#xff0c;学习无监督学习并不只是学习某个聚类算法或降维方法的调用方式&#xff0c;更重要的是理解&#xff1a;当数据没有现成标签时&#xff0c;如何从一批样本中发现结构、生成结果&#xff0c;并判断这种结构是否具有解释价值。与监督学习不同&#…...

ARM架构特权级别与安全监控机制解析

1. ARM架构特权级别与安全监控机制解析在ARMv8/v9架构中&#xff0c;异常级别(EL)构成了系统安全的基础隔离机制。EL3作为最高特权级别&#xff0c;承担着安全监控器(Secure Monitor)的关键角色。不同于EL0/1/2主要处理应用、操作系统和虚拟化需求&#xff0c;EL3专门负责安全世…...

基于Tauri+React+TS构建跨平台开发者效率工具:集成AI编程与Git Worktree

1. 项目概述&#xff1a;一个为现代开发者打造的桌面效率工具 如果你和我一样&#xff0c;每天的工作流都离不开终端、代码编辑器和各种AI助手&#xff0c;那你一定也经历过这种场景&#xff1a;在多个项目间频繁切换&#xff0c;终端里塞满了十几个标签页&#xff0c;想找个昨…...

边缘AI安全与隐私实战:从联邦学习到可信执行环境

1. 项目概述&#xff1a;当边缘计算遇上AI&#xff0c;安全与隐私的新战场最近几年&#xff0c;我身边做物联网和移动应用开发的朋友&#xff0c;聊天的主题都绕不开两个词&#xff1a;边缘计算和AI。大家一边兴奋于把AI模型塞进摄像头、网关甚至手机里带来的实时性提升&#x…...

主动学习加速广义Benders分解求解混合整数经济模型预测控制

1. 项目概述与核心价值最近在做一个挺有意思的项目&#xff0c;核心是把一个听起来很“学术”的算法——广义Benders分解&#xff0c;和工业界里越来越火的经济模型预测控制给揉到了一起&#xff0c;并且用主动学习这个思路去优化整个求解过程。乍一听&#xff0c;这标题里又是…...

共探 AI 转型新路径,数式科技黄梦瑶在 “走进云谷中心” 活动分享核心实战经验

近日&#xff0c;“智领未来・名企对标行”系列活动&#xff08;第五期&#xff1a;走进云谷中心&#xff09;隆重召开。本次活动汇聚了数百位制造业CIO、CEO、CTO及行业专家&#xff0c;围绕“AI赋能制造业高质量发展”展开深度探讨。作为深耕企业AI转型培训与咨询的专业机构&…...

基于CRealNVP深度生成模型的gNTS过程拟合与Quanto期权定价实践

1. 项目概述&#xff1a;当深度生成模型遇上复杂衍生品定价最近在琢磨一个挺有意思的课题&#xff0c;就是怎么把前沿的深度生成模型&#xff0c;具体来说是CRealNVP&#xff0c;给“塞”进金融衍生品定价这个传统上由随机微分方程和蒙特卡洛模拟主导的领域里&#xff0c;去解决…...