使用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 算法原理,公式,模式,伸缩因子,旋转方向等,推荐以下链接视频了解 cordic 算法。哔哩哔哩-cordic算法原理讲解 ● 用matlab 或者 c 实现一遍算法 ● 在FPGA中用 verilog 实现,注意…...
【css】width:100%;padding:20px;造成超出100%宽度的解决办法 - box-sizing的使用方法 - CSS布局
问题 修改效果 解决方法 .xx {width: 100%;padding: 0 20px;box-sizing: border-box; } 默认box-sizing: content-box下, width 内容的宽度 height 内容的高度 宽度和高度的计算值都不包含内容的边框(border)和内边距(padding&…...
贪心算法_翻硬币
蓝桥账户中心 依次遍历 不符合条件就反转 题目要干嘛 你就干嘛 #include <bits/stdc.h>#define endl \n using namespace std;int main() {ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); string s; cin >> s;string t; cin >> t;int ret 0;for ( i…...
vue开发06:前端通过webpack配置代理处理跨域问题
1.定义 在浏览器尝试请求不同源(域名、协议、端口号不同)的资源时,浏览器的同源策略会阻止这种跨域请求。(比如前端端口15500,后端端口5050,前端界面不可以直接调用5050端口) 2.解决方案 使用前…...
深入HBase——引入
引入 前面我们通过深入HDFS到深入MapReduce ,从设计和落地,去深入了解了大数据最底层的基石——存储与计算是如何实现的。 这个专栏则开始来看大数据的三驾马车中最后一个。 通过前面我们对于GFS和MapReduce论文实现的了解,我们知道GFS在数…...
2025年02月12日Github流行趋势
项目名称:data-formulator 项目地址url:https://github.com/microsoft/data-formulator 项目语言:TypeScript 历史star数:4427 今日star数:729 项目维护者:danmarshall, Chenglong-MS, apps/dependabot, mi…...
【落羽的落羽 数据结构篇】双向链表
文章目录 一、链表的分类二、双向链表1. 结构2. 申请一个新节点3. 尾部插入数据4. 头部插入数据5. 尾部删除数据6. 头部删除数据7. 在指定位置之后插入数据8. 删除指定位置节点9. 销毁链表 一、链表的分类 链表的分类实际上要从这三个方向分析:是否带头、单向还是双…...
Golang的并发编程问题解决思路
Golang的并发编程问题解决思路 一、并发编程基础 并发与并行 在计算机领域,“并发”和“并行”经常被混为一谈,但它们有着不同的含义。并发是指一段时间内执行多个任务,而并行是指同时执行多个任务。在 Golang 中,通过 goroutines…...
vsftpd 配置项说明
目录 一:vsftpd 配置文件说明二:vsftpd 服务和连接设置三:vsftpd 用户根目录管理四:vsftpd 匿名用户模式管理五:vsftpd 本地用户模式管理六: vsftpd 虚拟用户模式管理 一:vsftpd 配置文件说明 …...
剑指offer第2版:搜索算法(二分/DFS/BFS)
查找本质就是排除的过程,不外乎顺序查找、二分查找、哈希查找、二叉排序树查找、DFS/BFS查找 一、p39-JZ3 找出数组中重复的数字(利用特性) 数组中重复的数字_牛客题霸_牛客网 方法1:全部排序再进行逐个扫描找重复。 时间复杂…...
Pytorch与大模型有什么关系
PyTorch 是 深度学习领域最流行的框架之一,在大模型的训练、推理、优化等方面发挥了重要作用。 大模型(如 GPT、LLaMA、Stable Diffusion)大多是基于 PyTorch 进行开发和训练的。 1. PyTorch 在大模型中的作用 大模型(如 ChatGP…...
在 CentOS 上更改 SSH 默认端口以提升服务器安全性
🚀 作者主页: 有来技术 🔥 开源项目: youlai-mall ︱vue3-element-admin︱youlai-boot︱vue-uniapp-template 🌺 仓库主页: GitCode︱ Gitee ︱ Github 💖 欢迎点赞 👍 收藏 ⭐评论 …...
PyTorch Lightning pytorch.loggers模块介绍
pytorch.loggers 是 PyTorch Lightning 提供的一个模块,用于集成多种日志记录工具,方便开发者在训练过程中记录和监控模型的性能指标、超参数等信息。日志记录器(Loggers)是 PyTorch Lightning 的重要组成部分,可以通过…...
2025年:边缘计算崛起下运维应对新架构挑战
一、引言 随着科技的飞速发展,2025年边缘计算正以前所未有的速度崛起,给运维行业带来了全新的架构挑战。在这个充满机遇与挑战的时代,美信时代公司的美信监控易运维管理软件成为运维领域应对这些挑战的有力武器。 二、边缘计算崛起带来的运维…...
什么是UV环形光源
UV环形光源是一种用于特定照明需求的设备,以下是其关键点: 定义 UV环形光源:发出紫外光的环形照明装置,常用于机器视觉、工业检测等领域。特点 均匀照明:环形设计确保光线均匀分布,减少阴影。 高亮度&…...
怎么理解 Spring Boot 的约定优于配置 ?
在传统的 Spring 开发中,大家可能都有过这样的经历:项目还没开始写几行核心业务代码,就已经在各种配置文件中耗费了大量时间。比如,要配置数据库连接,不仅要在 XML 文件里编写冗长的数据源配置,还要处理事务…...
学习总结2.14
深搜将题目分配,如果是两个题目,就可以出现左左,左右,右左,右右四种时间分配,再在其中找最小值,即是两脑共同处理的最小值 #include <stdio.h> int s[4]; int sum0; int brain[25][25]; …...
Electron 客户端心跳定时任务调度库调研文档 - Node.js 任务调度库技术调研文档
Electron 客户端心跳定时任务调度库调研文档 - Node.js 任务调度库技术调研文档 本文将对七个流行的定时任务调度库:node-cron、rxjs、bull、node-schedule、agenda、bree、cron。这些库都可以用来处理定时任务,但它们的特点和适用场景有所不同。我们将从…...
【学术投稿-第四届智能电网和绿色能源国际学术会议(ICSGGE 2025)】CSS基本选择器详解:掌握基础,轻松布局网页
可线上 官网:www.icsgge.org 时间:2025年2月28-3月2日 目录 前言 一、基本选择器简介 1. 元素选择器(Type Selector) 基本语法 示例 注意事项 2. 类选择器(Class Selector) 基本语法 示例 注意…...
singleTaskAndroid的Activity启动模式知识点总结
一. 前提知识 1.1. 任务栈知识 二. Activity启动模式的学习 2.1 standard 2.2 singleTop 2.3.singleTask 2.4.singleInstance 引言: Activity作为四大组件之一,也可以说Activity是其中最重要的一个组件,其负责调节APP的视图ÿ…...
Java Stream 全面解析
Java Stream 全面解析 Java 8 引入的 Stream API 提供了一种高效且声明式的方式来处理集合数据。Stream 允许你以函数式编程风格操作数据,支持并行处理,并且可以显著简化代码。下面我们将从 创建操作、中间操作 和 终端操作 三个方面进行全面深入的解析…...
OpenCV识别电脑摄像头中的圆形物体
思路步骤 初始化摄像头:使用cv2.VideoCapture打开电脑摄像头。处理每一帧图像:对摄像头捕获的每一帧图像进行处理,包括灰度化、高斯模糊、霍夫圆变换等操作。绘制圆形和圆心:如果检测到圆形,使用cv2.circle函数用黄线…...
如何在 Tomcat 中屏蔽错误报告
Tomcat 屏蔽错误信息 <h1>HTTP状态 400 - 错误的请求</h1><hr class"line" /><p><b>类型</b> 异常报告</p><p><b>消息</b> 在请求目标中找到无效字符。有效字符在RFC 7230和RFC 3986中定义</p>&…...
Vue 入门到实战 十
第10章 Vue Router 目录 10.1 什么是路由 10.2 Vue Router的安装 10.2.1 本地独立版本方法 10.2.2 CDN方法 10.2.3 NPM方法 10.2.4 命令行工具(Vue CLI)方法 10.3 Vue Router的基本用法 10.3.1 跳转与传参 10.3.2 配置路由 10.…...
jenkins-获取当前时间戳
一. 简述: 很多场景下,需要获取当前时间戳。 二. 使用方法: 1. 安装: 最简单的, 莫过于直接部署相关插件: Build Timestamp Plugin 2. 配置: 3. 使用: post {success {script…...
springboot mybatis-plus 集成多数据源
在 Spring Boot 项目中集成 MyBatis-Plus 并配置多数据源,可以按照以下步骤进行。这个示例将展示如何配置两个数据源,并确保每个数据源都有自己对应的 SqlSessionFactory 和事务管理器。 1. 添加依赖 首先,在你的 pom.xml 文件中添加必要的…...
SSH 登录到 Linux 服务器为什么没有要求输入密码
如果你通过 SSH 登录到 Linux 服务器时没有要求输入密码,通常有以下几种可能性: 1. 使用 SSH 密钥认证 最常见的原因是你的 SSH 登录使用了 公钥认证,而不是密码认证。在这种情况下,服务器上已经配置了你的公钥,并且…...
Kafka 中基于 Segment 和 Offset 查找消息的过程
Kafka 中基于 Segment 和 Offset 查找消息的过程 假设我们有一个 Kafka Topic,其 Partition 划分为多个 Segment 文件。每个 Segment 文件包含 .log、.index 和 .timeindex 文件。现在我们需要查找 Offset 为 368801 的消息。 假设条件 Partition:par…...
【Jenkins流水线搭建】
Jenkins流水线搭建 01、SpringBoot项目 - Jenkins基于Jar持续集成搭建文档基于手动方式发布项目基于dockerfile基于jenkins + dockerfile + jenkinsfile +pieline基于jenkins + jar方式的发布01、环境说明01、准备项目02、准备服务器03、安装git04、安装jdk1.805、安装maven依赖…...
【Java】规则引擎 Drools
https://www.bilibili.com/video/BV1nW421R7qJ 来自尚硅谷 背景 /*** 设置订单积分*/ public void setOrderPoint(Order order){if (order.getAmout() < 100){order.setScore(0);}else if(order.getAmout() > 100 && order.getAmout() < 500){order.setScore(…...
