当前位置:   article > 正文

FPGA使用查表法实现正弦和余弦函数_fpga查找表如何实现

fpga查找表如何实现

一、实现思路

  1. 使用matlab生成正弦值和余弦值的coe文件;
  2. coe文件写入ROM核中;
  3. 通过查表得到角度所对应的正弦值和余弦值。

二、实现方法

1、使用matlab生成正弦值和余弦值的coe文件;

  1. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2. %% Zheng Wei, 2022/12/05
  3. %%
  4. %% 输入角度范围:[0,2*pi); 输入数据量化位数:10bit;
  5. %% 输出结果范围:[-1,1]; 输出数据量化位数:16bit;
  6. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  7. clc; % 清理命令行
  8. close all; % 关闭所有图形窗口
  9. clear all; % 清理所有工作区变量
  10. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  11. %% 参数定义
  12. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  13. in_quantify_bit = 10; % 输入数据量化位数(无符号数)
  14. alpha = 0:(2*pi/2^in_quantify_bit):(2*pi-2*pi/2^in_quantify_bit); % 弧度
  15. out_quantify_bit = 16; % 输出数据量化位数(有符号数)
  16. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  17. %% 获取三角函数值
  18. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  19. cos_alpha = cos(alpha); % 获得cos函数值
  20. sin_alpha = sin(alpha); % 获得sin函数值
  21. cos_alpha_q = round(cos_alpha *(2^(out_quantify_bit-1)-1)); % 16bit量化
  22. sin_alpha_q = round(sin_alpha *(2^(out_quantify_bit-1)-1)); % 16bit量化
  23. %figure(1); subplot(2,1,1);plot(alpha,cos_alpha);subplot(2,1,2);plot(alpha,cos_alpha_q);
  24. %figure(2); subplot(2,1,1);plot(alpha,sin_alpha);subplot(2,1,2);plot(alpha,sin_alpha_q);
  25. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  26. %% 生成coe文件,第一行定义数据格式, 16代表ROM的数据格式为16进制。
  27. %% 高16bit代表sin值,低16bit代表cos值,各自最高的1bit是符号位。
  28. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  29. for i = 1:1:(2^in_quantify_bit)
  30. if (cos_alpha_q(i)<0)
  31. cos_alpha_q(i) = cos_alpha_q(i) + 2^(out_quantify_bit); % 负数用补码表示
  32. else
  33. cos_alpha_q(i) = cos_alpha_q(i); % 正数的补码为原码
  34. end
  35. if (sin_alpha_q(i)<0)
  36. sin_alpha_q(i) = sin_alpha_q(i) + 2^(out_quantify_bit); % 负数用补码表示
  37. else
  38. sin_alpha_q(i) = sin_alpha_q(i); % 正数的补码为原码
  39. end
  40. end
  41. cos_alpha_q = dec2hex(cos_alpha_q); % 因为dec2hex只能转换正数,因此先将cos_alpha_q取补码
  42. sin_alpha_q = dec2hex(sin_alpha_q); % 因为dec2hex只能转换正数,因此先将sin_alpha_q取补码
  43. % 将cos和sin拼接为32bit(各自16bit),此数据输出到FPGA
  44. fid=fopen('cos_sin_lut_1.coe','wt');
  45. fprintf( fid, 'MEMORY_INITIALIZATION_RADIX = 16;\n');
  46. fprintf( fid, 'MEMORY_INITIALIZATION_VECTOR =\n');
  47. for i = 1:1:(2^in_quantify_bit)
  48. s=strcat(sin_alpha_q(i,1),sin_alpha_q(i,2),sin_alpha_q(i,3),sin_alpha_q(i,4),cos_alpha_q(i,1),cos_alpha_q(i,2),cos_alpha_q(i,3),cos_alpha_q(i,4));
  49. fprintf(fid,'%c%c%c%c%c%c%c%c',s);
  50. if (i < 2^in_quantify_bit)
  51. fprintf(fid,',\n');
  52. else
  53. fprintf(fid,';\n'); % 分号(;) 结束标志位
  54. end
  55. end
  56. fclose(fid);

2、将coe文件写入ROM核中;

3、通过查表得到角度所对应的正弦值和余弦值。

  1. /*----------------------------------------------------------------------
  2. Author: Zheng Wei
  3. Date: 2022-12-05
  4. Version: 1.0
  5. Description: It is a cos_sin_lut_1 testbench.
  6. -----------------------------------------------------------------------*/
  7. `timescale 1ns / 1ps
  8. module tb;
  9. reg i_sys_clk ;
  10. reg i_sys_rst ;
  11. reg [09:0] r_rom_phase ;
  12. wire [15:0] w_cos_rom_val ;
  13. wire [15:0] w_sin_rom_val ;
  14. // clock generate module
  15. parameter period = 6.67; // 150MHz
  16. initial begin
  17. i_sys_clk = 1'b0;
  18. forever #(period/2) i_sys_clk = ~i_sys_clk;
  19. end
  20. //-------------------------------------------------------------------
  21. // system initialization
  22. task task_sysinit;
  23. begin
  24. r_rom_phase = 10'd0;
  25. end
  26. endtask
  27. // system reset
  28. task task_reset;
  29. begin
  30. i_sys_rst = 1'b1;
  31. repeat(20) @(negedge i_sys_clk);
  32. i_sys_rst = 1'b0;
  33. end
  34. endtask
  35. initial begin
  36. task_sysinit;
  37. task_reset ;
  38. repeat(10) @(posedge i_sys_clk);
  39. repeat(100000) @(posedge i_sys_clk);
  40. $stop;
  41. end
  42. always @(posedge i_sys_clk or posedge i_sys_rst) begin
  43. if (i_sys_rst) begin
  44. r_rom_phase <= 10'd0;
  45. end
  46. else begin
  47. r_rom_phase <= r_rom_phase + 10'd1;
  48. end
  49. end
  50. //-----------------------------------------------------------------------------------------------
  51. cos_sin_lut_1 u_cos_sin_lut_1(
  52. .clka ( i_sys_clk ), // input wire clka
  53. .addra ( r_rom_phase ), // input wire [9 : 0] addra
  54. .douta ({w_sin_rom_val, w_cos_rom_val}) // output wire [31 : 0] douta
  55. );
  56. endmodule

4、仿真结果

 

声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号