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

HLS实现CORDIC算法计算正余弦并上板验证

硬件:ZYNQ7010
软件:MATLAB 2019b、Vivado 2017.4、HLS 2017.4、System Generator 2017.4

1、CORDIC算法计算正余弦

  CORDIC算法详细分析网上有很多资料,它的原理是用一系列旋转去逼近目标角度,这一系列旋转的角度为 θ = a r c t a n ( 2 − i ) \theta=arctan(2^{-i}) θ=arctan(2i) i i i 是迭代次数。下面给出了用CORDIC算法计算正余弦的代码,其中 s1 不做任何优化,数据类型都用的 float 型;s2 对数据类型做了定点数优化;s3 在 s2 的基础上,对迭代的循环做了流水线优化。

//cordic.h
#ifndef _CORDIC_H_
#define _CORDIC_H_
#include <ap_int.h>
#include <ap_fixed.h>
#define NUM_ITERATIONS 9
//#define s1
//#define s2
#define s3
#if defined s1
typedef float THETA_TYPE;
typedef float COS_SIN_TYPE;
#endif
#if defined s2 || defined s3
typedef ap_fixed<16,8> THETA_TYPE;
typedef ap_fixed<16,2> COS_SIN_TYPE;
#endif
void cordic(THETA_TYPE theta, COS_SIN_TYPE &s, COS_SIN_TYPE &c);
#endif
//cordic.cpp
#include "cordic.h"
const THETA_TYPE cordic_phase[NUM_ITERATIONS] = {45, 26.565, 14.036, 7.125, 3.576, 1.790, 0.895, 0.448, 0.224};
#if defined s1
void cordic(THETA_TYPE theta, COS_SIN_TYPE &s, COS_SIN_TYPE &c)
{COS_SIN_TYPE current_cos = 0.607255; // 6, 1/1.64669COS_SIN_TYPE current_sin = 0;COS_SIN_TYPE factor = 1.0;for(int i=0; i<NUM_ITERATIONS; i++){ap_int<2> sigma = (theta < 0)?-1:1;COS_SIN_TYPE temp_cos = current_cos;current_cos = current_cos-current_sin*sigma*factor;current_sin = temp_cos*sigma*factor+current_sin;theta = theta-sigma*cordic_phase[i];factor = factor/2.0;}s = current_sin;c = current_cos;
}
#endif
#if defined s2 || defined s3
void cordic(THETA_TYPE theta, COS_SIN_TYPE &s, COS_SIN_TYPE &c)
{COS_SIN_TYPE current_cos = 0.607255; // 6, 1/1.64669COS_SIN_TYPE current_sin = 0;COS_SIN_TYPE factor = 1.0;
ITERATIONS_LOOP:for(int i=0; i<NUM_ITERATIONS; i++){ap_int<2> sigma = (theta < 0)?-1:1;COS_SIN_TYPE temp_cos = current_cos;current_cos = current_cos-current_sin*sigma*factor;current_sin = temp_cos*sigma*factor+current_sin;theta = theta-sigma*cordic_phase[i];factor >>= 1;}s = current_sin;c = current_cos;
}
#endif

  三个 solution 的资源使用量和计算性能如下图所示。

在这里插入图片描述

2、上板验证

  把 s3 的模块端口设置成 ap_ctrl_none, 重新综合,导出 IP 核。在FPGA的顶层文件里例化 cordic IP 核和一个 ila IP 核,让 cordic 计算 30° 和 60° 角的正余弦值。

module cordic_test_top(input resetn,input clk);wire [15:0] w_theta;
reg [15:0] r_theta;
reg [31:0] cnt;
always @(posedge clk or negedge resetn) beginif(!resetn) begincnt <= 32'd0;endelse beginif(cnt == 32'd1000) cnt <= 32'd0;else cnt <= cnt+1'd1;end
end
always @(posedge clk or negedge resetn) beginif(!resetn) beginr_theta <= 16'd0;endelse beginif(cnt == 32'd500) r_theta <= {8'd30, 8'd0};else if(cnt == 32'd1000) r_theta <= {8'd60, 8'd0};else r_theta <= r_theta;end
end
assign w_theta = r_theta;
wire [15:0] s, c;
wire s_V_ap_vld, c_V_ap_vld;
reg [15:0] r_s, r_c;
cordic_0 cordic_inst (.s_V_ap_vld(s_V_ap_vld),  // output wire s_V_ap_vld.c_V_ap_vld(c_V_ap_vld),  // output wire c_V_ap_vld.ap_clk(clk),          // input wire ap_clk.ap_rst(~resetn),          // input wire ap_rst.theta_V(w_theta),        // input wire [15 : 0] theta_V.s_V(s),                // output wire [15 : 0] s_V.c_V(c)                // output wire [15 : 0] c_V
);
always @(posedge clk or negedge resetn) beginif(!resetn) beginr_s <= 16'd0;endelse beginif(s_V_ap_vld) beginr_s <= s;endend
end
always @(posedge clk or negedge resetn) beginif(!resetn) beginr_c <= 16'd0;endelse beginif(c_V_ap_vld) beginr_c <= c;endend
end
ila_0 ila0 (.clk(clk), // input wire clk.probe0(w_theta), // input wire [15:0]  probe0  .probe1(r_s), // input wire [15:0]  probe1 .probe2(s_V_ap_vld), // input wire [0:0]  probe2 .probe3(r_c), // input wire [15:0]  probe3 .probe4(c_V_ap_vld) // input wire [0:0]  probe4
);

   ila 上看到的波形如下图所示。注意要正确设置观测量的数据类型,即定点数和小数点位置。从图中可以看出计算的角度比较准确。

在这里插入图片描述
完整工程下载:HLS设计CORDIC算法计算正余弦

http://www.lryc.cn/news/142231.html

相关文章:

  • 高阶数据结构并查集
  • WSL2连接不了外网怎么办?
  • 【C/C++】探索内存对齐的奥秘与优势
  • leetcode分类刷题:滑动窗口(二、重复元素类型)
  • MySQL—buffer pool
  • 《C和指针》笔记8: 枚举类型
  • Python爬虫框架之Selenium库入门:用Python实现网页自动化测试详解
  • docker swarm 部署服务网络问题
  • 1.00001git源码clone后进行编译(带调试)
  • 使用StorageClass动态创建pv
  • 数据结构(Java实现)-ArrayList与顺序表
  • 性能优化维度
  • PMP P-06 Resource Management
  • 【C++】map的奇葩用法:和函数结合
  • 关于JVM的参数类型
  • HTTP协议中的Content-Type及其常见类型
  • android Junit4编写自测用例
  • arcgis:画一幅自己城市的shp地图
  • 采购油封时要考虑的因素
  • 【无标题】科目一笔记
  • java八股文面试[数据结构]——HashMap和HashTable区别
  • 乐趣无限:10款基于Pygame的经典游戏合集
  • php检测数组是否存在某个键,和是否存在某个变量
  • c++中的const与constexpt的区别
  • android系统启动流程之SystemServer运行过程
  • Leetcode 1812。判断国际象棋棋盘中一个格子的颜色
  • 9个python自动化脚本,PPT批量生成缩略图、添加图片、重命名
  • 计算机竞赛 基于大数据的社交平台数据爬虫舆情分析可视化系统
  • 基于Java的旅游信息推荐系统设计与实现,springboot+vue,MySQL数据库,前后端分离,完美运行,有三万字论文。
  • 合宙Air724UG LuatOS-Air LVGL API控件--曲线 (Arc)