关于FPGA之CORDIC算法的纯逻辑实现,善良的一休军“https://blog.csdn.net/qq_39210023/article/details/77456031”的博文均给出了较为详细完整的代码,整个算法的思想较为简单,就

是利用迭代流水线的思想,让角度不停逼近所求角度,一般迭代16次就已经比较接近所求角度值:

1、算法实现步骤:

1)设置迭代次数为16,则x0 = 0.607253,y0 = 0(关于初值的设定,上一篇博文有写到)并输入待计算的角度θ,θ在[-99.7°,99.7°]范围内。

2)根据三个迭代公式进行迭代,i从0至15:
xi+1 = xi – d iy i2-i
yi+1 = yi + d ix i2-i
zi+1 = zi - diθi
注:z0 = θ,di与zi同符号。

3) 经过16次迭代计算后,得到的x16 和y16分别为cosθ和sinθ。

2、代码解析:

1)16级流水线迭代实现

  1. always @(posedge clk or negedge rst_n)begin
  2. if(rst_n=='b0)begin
  3. x[] <= ;
  4. y[] <= ;
  5. z[] <= (din<<);
  6. end
  7. else if(din_vld_ff[]) begin //初始化设置赋值 x0==0.607253*2^16,y0=0;
  8. x[] <= {'b0,COS_LM};
  9. y[] <= ;
  10. z[] <= {'b0,din_ff,16'b0}; //角度初始化设置
  11. end
  12. end
  13.  
  14. always @(posedge clk or negedge rst_n)begin
  15. if(rst_n=='b0)begin
  16. x[] <= ;
  17. y[] <= ;
  18. z[] <= ;
  19. end
  20. else if(din_vld_ff[])begin
  21. if(z[][]==)begin
  22. x[] <= x[] - (y[]>>>);
  23. y[] <= y[] + (x[]>>>);
  24. z[] <= z[] - `ROT0;
  25. end
  26. else begin
  27. x[] <= x[] + (y[]>>>);
  28. y[] <= y[] - (x[]>>>);
  29. z[] <= z[] + `ROT0;
  30. end
  31. end
  32. end
  33.  
  34. always @(posedge clk or negedge rst_n)begin
  35. if(rst_n=='b0)begin
  36. x[] <= ;
  37. y[] <= ;
  38. z[] <= ;
  39. end
  40. else if(din_vld_ff[])begin
  41. if(z[][]==)begin
  42. x[] <= x[] - (y[]>>>);
  43. y[] <= y[] + (x[]>>>);
  44. z[] <= z[] - `ROT1;
  45. end
  46. else begin
  47. x[] <= x[] + (y[]>>>);
  48. y[] <= y[] - (x[]>>>);
  49. z[] <= z[] + `ROT1;
  50. end
  51. end
  52. end
  53.  
  54. always @(posedge clk or negedge rst_n)begin
  55. if(rst_n=='b0)begin
  56. x[] <= ;
  57. y[] <= ;
  58. z[] <= ;
  59. end
  60. else if(din_vld_ff[])begin
  61. if(z[][]==)begin
  62. x[] <= x[] - (y[]>>>);
  63. y[] <= y[] + (x[]>>>);
  64. z[] <= z[] - `ROT2;
  65. end
  66. else begin
  67. x[] <= x[] + (y[]>>>);
  68. y[] <= y[] - (x[]>>>);
  69. z[] <= z[] + `ROT2;
  70. end
  71. end
  72. end
  73.  
  74. always @(posedge clk or negedge rst_n)begin
  75. if(rst_n=='b0)begin
  76. x[] <= ;
  77. y[] <= ;
  78. z[] <= ;
  79. end
  80. else if(din_vld_ff[])begin
  81. if(z[][]==)begin
  82. x[] <= x[] - (y[]>>>);
  83. y[] <= y[] + (x[]>>>);
  84. z[] <= z[] - `ROT3;
  85. end
  86. else begin
  87. x[] <= x[] + (y[]>>>);
  88. y[] <= y[] - (x[]>>>);
  89. z[] <= z[] + `ROT3;
  90. end
  91. end
  92. end
  93.  
  94. always @(posedge clk or negedge rst_n)begin
  95. if(rst_n=='b0)begin
  96. x[] <= ;
  97. y[] <= ;
  98. z[] <= ;
  99. end
  100. else if(din_vld_ff[])begin
  101. if(z[][]==)begin
  102. x[] <= x[] - (y[]>>>);
  103. y[] <= y[] + (x[]>>>);
  104. z[] <= z[] - `ROT4;
  105. end
  106. else begin
  107. x[] <= x[] + (y[]>>>);
  108. y[] <= y[] - (x[]>>>);
  109. z[] <= z[] + `ROT4;
  110. end
  111. end
  112. end
  113.  
  114. always @(posedge clk or negedge rst_n)begin
  115. if(rst_n=='b0)begin
  116. x[] <= ;
  117. y[] <= ;
  118. z[] <= ;
  119. end
  120. else if(din_vld_ff[])begin
  121. if(z[][]==)begin
  122. x[] <= x[] - (y[]>>>);
  123. y[] <= y[] + (x[]>>>);
  124. z[] <= z[] - `ROT5;
  125. end
  126. else begin
  127. x[] <= x[] + (y[]>>>);
  128. y[] <= y[] - (x[]>>>);
  129. z[] <= z[] + `ROT5;
  130. end
  131. end
  132. end
  133.  
  134. always @(posedge clk or negedge rst_n)begin
  135. if(rst_n=='b0)begin
  136. x[] <= ;
  137. y[] <= ;
  138. z[] <= ;
  139. end
  140. else if(din_vld_ff[])begin
  141. if(z[][]==)begin
  142. x[] <= x[] - (y[]>>>);
  143. y[] <= y[] + (x[]>>>);
  144. z[] <= z[] - `ROT6;
  145. end
  146. else begin
  147. x[] <= x[] + (y[]>>>);
  148. y[] <= y[] - (x[]>>>);
  149. z[] <= z[] + `ROT6;
  150. end
  151. end
  152. end
  153.  
  154. always @(posedge clk or negedge rst_n)begin
  155. if(rst_n=='b0)begin
  156. x[] <= ;
  157. y[] <= ;
  158. z[] <= ;
  159. end
  160. else if(din_vld_ff[])begin
  161. if(z[][]==)begin
  162. x[] <= x[] - (y[]>>>);
  163. y[] <= y[] + (x[]>>>);
  164. z[] <= z[] - `ROT7;
  165. end
  166. else begin
  167. x[] <= x[] + (y[]>>>);
  168. y[] <= y[] - (x[]>>>);
  169. z[] <= z[] + `ROT7;
  170. end
  171. end
  172. end
  173.  
  174. always @(posedge clk or negedge rst_n)begin
  175. if(rst_n=='b0)begin
  176. x[] <= ;
  177. y[] <= ;
  178. z[] <= ;
  179. end
  180. else if(din_vld_ff[])begin
  181. if(z[][]==)begin
  182. x[] <= x[] - (y[]>>>);
  183. y[] <= y[] + (x[]>>>);
  184. z[] <= z[] - `ROT8;
  185. end
  186. else begin
  187. x[] <= x[] + (y[]>>>);
  188. y[] <= y[] - (x[]>>>);
  189. z[] <= z[] + `ROT8;
  190. end
  191. end
  192. end
  193.  
  194. always @(posedge clk or negedge rst_n)begin
  195. if(rst_n=='b0)begin
  196. x[] <= ;
  197. y[] <= ;
  198. z[] <= ;
  199. end
  200. else if(din_vld_ff[])begin
  201. if(z[][]==)begin
  202. x[] <= x[] - (y[]>>>);
  203. y[] <= y[] + (x[]>>>);
  204. z[] <= z[] - `ROT9;
  205. end
  206. else begin
  207. x[] <= x[] + (y[]>>>);
  208. y[] <= y[] - (x[]>>>);
  209. z[] <= z[] + `ROT9;
  210. end
  211. end
  212. end
  213.  
  214. always @(posedge clk or negedge rst_n)begin
  215. if(rst_n=='b0)begin
  216. x[] <= ;
  217. y[] <= ;
  218. z[] <= ;
  219. end
  220. else if(din_vld_ff[])begin
  221. if(z[][]==)begin
  222. x[] <= x[] - (y[]>>>);
  223. y[] <= y[] + (x[]>>>);
  224. z[] <= z[] - `ROT10;
  225. end
  226. else begin
  227. x[] <= x[] + (y[]>>>);
  228. y[] <= y[] - (x[]>>>);
  229. z[] <= z[] + `ROT10;
  230. end
  231. end
  232. end
  233.  
  234. always @(posedge clk or negedge rst_n)begin
  235. if(rst_n=='b0)begin
  236. x[] <= ;
  237. y[] <= ;
  238. z[] <= ;
  239. end
  240. else if(din_vld_ff[])begin
  241. if(z[][]==)begin
  242. x[] <= x[] - (y[]>>>);
  243. y[] <= y[] + (x[]>>>);
  244. z[] <= z[] - `ROT11;
  245. end
  246. else begin
  247. x[] <= x[] + (y[]>>>);
  248. y[] <= y[] - (x[]>>>);
  249. z[] <= z[] + `ROT11;
  250. end
  251. end
  252. end
  253.  
  254. always @(posedge clk or negedge rst_n)begin
  255. if(rst_n=='b0)begin
  256. x[] <= ;
  257. y[] <= ;
  258. z[] <= ;
  259. end
  260. else if(din_vld_ff[])begin
  261. if(z[][]==)begin
  262. x[] <= x[] - (y[]>>>);
  263. y[] <= y[] + (x[]>>>);
  264. z[] <= z[] - `ROT12;
  265. end
  266. else begin
  267. x[] <= x[] + (y[]>>>);
  268. y[] <= y[] - (x[]>>>);
  269. z[] <= z[] + `ROT12;
  270. end
  271. end
  272. end
  273.  
  274. always @(posedge clk or negedge rst_n)begin
  275. if(rst_n=='b0)begin
  276. x[] <= ;
  277. y[] <= ;
  278. z[] <= ;
  279. end
  280. else if(din_vld_ff[])begin
  281. if(z[][]==)begin
  282. x[] <= x[] - (y[]>>>);
  283. y[] <= y[] + (x[]>>>);
  284. z[] <= z[] - `ROT13;
  285. end
  286. else begin
  287. x[] <= x[] + (y[]>>>);
  288. y[] <= y[] - (x[]>>>);
  289. z[] <= z[] + `ROT13;
  290. end
  291. end
  292. end
  293.  
  294. always @(posedge clk or negedge rst_n)begin
  295. if(rst_n=='b0)begin
  296. x[] <= ;
  297. y[] <= ;
  298. z[] <= ;
  299. end
  300. else if(din_vld_ff[])begin
  301. if(z[][]==)begin
  302. x[] <= x[] - (y[]>>>);
  303. y[] <= y[] + (x[]>>>);
  304. z[] <= z[] - `ROT14;
  305. end
  306. else begin
  307. x[] <= x[] + (y[]>>>);
  308. y[] <= y[] - (x[]>>>);
  309. z[] <= z[] + `ROT14;
  310. end
  311. end
  312. end
  313.  
  314. always @(posedge clk or negedge rst_n)begin
  315. if(rst_n=='b0)begin
  316. x[] <= ;
  317. y[] <= ;
  318. z[] <= ;
  319. end
  320. else if(din_vld_ff[])begin
  321. if(z[][]==)begin
  322. x[] <= x[] - (y[]>>>);
  323. y[] <= y[] + (x[]>>>);
  324. z[] <= z[] - `ROT15;
  325. end
  326. else begin
  327. x[] <= x[] + (y[]>>>);
  328. y[] <= y[] - (x[]>>>);
  329. z[] <= z[] + `ROT15;
  330. end
  331. end
  332. end
  1.  

2)打拍同步

这点是我看了博主“洋葱洋葱”的代码,发现的简洁打拍写法。

a、din_vld是单比特信号,假设信号din_vld打4拍输入,可以对比下简洁写法和传统写法的代码量:

  1. //传统写法:将信号din_vld_ff打4拍
  2. always @(posedge clk or negedge rst_n)begin
  3. if(rst_n=='b0)begin
  4. din_vld_ff <=;
  5. din_vld_ff0 <= ;
  6. din_vld_ff1 <= ;
  7. din_vld_ff2 <= ;
  8. end
  9. else begin
  10. din_vld_ff0 <= din_vld_ff;
  11. din_vld_ff1 <= din_vld_ff0;
  12. din_vld_ff2 <= din_vld_ff1;
  13. end
  14. end
  15.  
  16. //简洁写法:将信号din_vld_ff打4拍
  17. always @(posedge clk or negedge rst_n )begin
  18. if(rst_n==) begin
  19. din_vld_ff <= () ;
  20. end
  21. else begin
  22. din_vld_ff <= ({din_vld_ff[:],din_vld}) ; //din_vld为1bit
  23. end
  24. end
  1.  

以上是单比特din_vld打4拍的对比写法,假如是要打十几拍,可以明显看出简洁写法的代码量少很多,这种打拍子的写法值得推崇。

b、din_vld是多比特信号,假设din_vld同样打4拍输入,利用简洁写法可以写成:

  1. always @(posedge clk or negedge rst_n )begin
  2. if(rst_n==) begin
  3. din_vld_ff <= () ;
  4. end
  5. else begin
  6. din_vld_ff <= ({din_vld_ff[5:],din_vld}) ; //din_vld为2bit
  7. end
  8. end

3)反正切函数,要注意由于θ在[-99.7°,99.7°]范围内,因此在角度输入时要注意换成第一、第四象限,最后结果输出时要注意还原成真实角度。

  1. always @(posedge clk or negedge rst_n)begin
  2. if(rst_n=='b0)begin
  3. din_ff <= ;
  4. flag <= ;
  5. end
  6. else if(din_vld)begin
  7. if(din<)begin
  8. din_ff = din;
  9. flag = ;
  10. end
  11. else if(din<)begin
  12. din_ff = din-;
  13. flag = ;
  14. end
  15. else if(din<)begin
  16. din_ff = din-;
  17. flag = ;
  18. end
  19. else begin
  20. din_ff = din-;
  21. flag = ;
  22. end
  23. end
  24. end
  1. //角度还原为真实值
  2. always @(posedge clk or negedge rst_n )begin
  3. if(rst_n==) begin
  4. dout_sin <= () ;
  5. end
  6. else if(flag_ff[:]==)begin //第一象限,y(16) = sin(x)
  7. dout_sin <= (y[]) ;
  8. end
  9. else if(flag_ff[:]==)begin //第二象限,Sin(X)=Sin(A+90)=CosA,Cos(X)=Cos(A+90)=-SinA
  10. dout_sin <= (x[]) ;
  11. end
  12. else if(flag_ff[:]==)begin //第三象限,the Sin(X)=Sin(A+180)=-SinA,Cos(X)=Cos(A+180)=-CosA
  13. dout_sin <= ~(y[]) + 'b1 ;
  14. end
  15. else if(flag_ff[:]==)begin //第四象限,the Sin(X)=Sin(A+270)=-CosA,Cos(X)=Cos(A+270)=SinA
  16. dout_sin <= ~(x[])

至此,基于FPGA的cordic算法代码实现需要注意的问题就讨论到这里。

FPGA之CORDIC算法实现_代码实现(下)的更多相关文章

  1. FPGA之CORDIC算法实现_理论篇(上)

    关于cordic的算法原理核心思想就是规定好旋转角度,然后通过不停迭代逐步逼近的思想来实现数学求解,网上关于这部分的资料非常多,主要可以参考: 1)https://blog.csdn.net/qq_3 ...

  2. 基于FPGA的Cordic算法实现

    CORDIC(Coordinate Rotation Digital Computer)算法即坐标旋转数字计算方法,是J.D.Volder1于1959年首次提出,主要用于三角函数.双曲线.指数.对数的 ...

  3. 基于FPGA的cordic算法的verilog初步实现

    最近在看cordic算法,由于还不会使用matlab,真是痛苦,一系列的笔算才大概明白了这个算法是怎么回事.于是尝试用verilog来实现.用verilog实现之前先参考软件的程序,于是先看了此博文h ...

  4. 定点CORDIC算法求所有三角函数及向量模的原理分析、硬件实现(FPGA)

    一.CORDIC算法 CORDIC(Coordinate Rotation DIgital Computer)是一种通过迭代对多种数学函数求值的方法,它可以对三角函数.双曲函数和平面旋转问题进行求解. ...

  5. cordic算法的fpga实现

    cordic算法参考:http://wenku.baidu.com/view/6c623aa8910ef12d2bf9e732.html 这是百度文库的一个文档,详细介绍了cordic算法的基本内容. ...

  6. [黑金原创教程] FPGA那些事儿《数学篇》- CORDIC 算法

    简介 一本为完善<设计篇>的书,教你CORDIC算法以及定点数等,内容请看目录. 贴士 这本教程难度略高,请先用<时序篇>垫底. 目录 Experiment 01:认识CORD ...

  7. 三角函数计算,Cordic 算法入门

    [-] 三角函数计算Cordic 算法入门 从二分查找法说起 减少乘法运算 消除乘法运算 三角函数计算,Cordic 算法入门 三角函数的计算是个复杂的主题,有计算机之前,人们通常通过查找三角函数表来 ...

  8. (转)三角函数计算,Cordic 算法入门

    由于最近要使用atan2函数,但是时间上消耗比较多,因而网上搜了一下简化的算法. 原帖地址:http://blog.csdn.net/liyuanbhu/article/details/8458769 ...

  9. Cordic算法——verilog实现

    上两篇博文Cordic算法--圆周系统之旋转模式.Cordic算法--圆周系统之向量模式做了理论分析和实现,但是所用到的变量依然是浮点型,而cordic真正的用处是基于FPGA等只能处理定点的平台.只 ...

随机推荐

  1. SRAM(静态)存储器芯片的读/写周期

    一. 要保证正确地读/写,必须注意CPU时序与存储器读/写周期的配合.一般存储器芯片手册都会给出芯片读/写周期的时序图. Intel 2114芯片的读.写周期时序如图所示. 二. 读周期 读操作时,必 ...

  2. HTTP协议图--HTTP 响应状态码(重点分析)

    1. 状态码概述 HTTP 状态码负责表示客户端 HTTP 请求的返回结果.标记服务器端的处理是否正常.通知出现的错误等工作. HTTP 状态码如 200 OK ,以 3 位数字和原因短语组成.数字中 ...

  3. 1、Node.js 我的开始+安装

    内容:为什么开始学习node.js,需要安装哪些东西,及其安装过程 node.js的学习是按照菜鸟教程的node.js教程学习,学习这项技术主要是因为需要使用. 需要安装的东西:解释器,IDE(集成开 ...

  4. java查找字符串里与指定字符串相同的个数

    public class EmployeeDemo { //方法一: public int search(String str,String strRes) {//查找字符串里与指定字符串相同的个数 ...

  5. python 中的set与list,tuple

    __author__ = 'liunnis' #-*-coding:utf-8 -*- a=[1,2,3,4,4] print a print list(set(a)) b=[str(i) for i ...

  6. 消息中间件--"rocketmq"01之环境搭建

    前置知识 ssh工具 连接linux工具SecureCRT 颜色设置,参考 中文乱码,参考 Linux相关知识 centos7 防火墙firewalld的基本使用,参考 启动: systemctl s ...

  7. webpack中使用babel处理es6语法

    index.js const arr = [ new Promise(()=>{}), new Promise(()=>{}) ]; arr.map(item => { consol ...

  8. 安装TA-Lib时报错:ubuntu****, Command "/usr/bin/python -u -c "import setuptools, tokenize;__file__='

    使用pip install TA-Lib 时报错: ERROR: Complete output from command /usr/bin/python3 -u -c 'import setupto ...

  9. weblogic之CVE-2016-0638反序列化分析

    此漏洞是基于CVE-2015-4852漏洞进行黑名单的绕过,CVE-2015-4852补丁主要应用在三个位置上 weblogic.rjvm.InboundMsgAbbrev.class :: Serv ...

  10. 4、Android-数据存储方案(SQLite数据库存储)

    4.4.SQLite数据库存储 这是Android内置的数据库 是一款轻量级的关系型数据库 运算速度非常快.占用资源少.通常只需要几百kb的内存就够了 因而特别适合在移动端设备上使用 SQLite不仅 ...