FPGA使用查表法实现正弦和余弦函数 - 变形方法2的一点扩展

在前面几篇文章中,输出数据量化位数都是16bit,但如果想实现非半字节的量化位数,比如18bit,那怎么办呢?只需要修改下matlab程序,产生18bit的输出数据,verilog程序修改起来就比较简单了。

修改后的matlab程序如下所示:

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Zheng Wei, 2022/12/08
%% 
%% 输入角度范围:[0,pi/4); 输入数据量化位数:10bit;
%% 输出结果范围:[0,1];    输出数据量化位数:18bit;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

clc;        % 清理命令行
close all;  % 关闭所有图形窗口 
clear all;  % 清理所有工作区变量


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% 参数定义
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
in_quantify_bit = 10;        % 输入数据量化位数(无符号数)
alpha = 0:(pi/4/2^in_quantify_bit):(pi/4-pi/4/2^in_quantify_bit);  % 弧度

out_quantify_bit = 18;       % 输出数据量化位数(有符号数)


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% 获取三角函数值
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
cos_alpha = cos(alpha);  % 获得cos函数值
sin_alpha = sin(alpha);  % 获得sin函数值
                                                                               
cos_alpha_q = round(cos_alpha *(2^(out_quantify_bit-1)-1));  % 18bit量化
sin_alpha_q = round(sin_alpha *(2^(out_quantify_bit-1)-1));  % 18bit量化

% figure(1); subplot(2,1,1);plot(alpha,cos_alpha);subplot(2,1,2);plot(alpha,cos_alpha_q);
% figure(2); subplot(2,1,1);plot(alpha,sin_alpha);subplot(2,1,2);plot(alpha,sin_alpha_q);


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% 生成coe文件,第一行定义数据格式, 16代表ROM的数据格式为16进制。
%% 高16bit代表sin值,低16bit代表cos值,各自最高的1bit是符号位。
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% 因为都是正数,所以不需要取补码
% for i = 1:1:(2^in_quantify_bit)
%     if (cos_alpha_q(i)<0)
%        cos_alpha_q(i) = cos_alpha_q(i) + 2^(out_quantify_bit); % 负数用补码表示
%     else
%        cos_alpha_q(i) = cos_alpha_q(i); % 正数的补码为原码
%     end
%                                                                                          
%     if (sin_alpha_q(i)<0)
%        sin_alpha_q(i) = sin_alpha_q(i) + 2^(out_quantify_bit); % 负数用补码表示
%     else
%        sin_alpha_q(i) = sin_alpha_q(i); % 正数的补码为原码
%     end
% end

cos_alpha_q = dec2bin(cos_alpha_q,18); 
sin_alpha_q = dec2bin(sin_alpha_q,18);
s=strcat(sin_alpha_q,cos_alpha_q);
s=bin2dec(s);
s=dec2hex(s);

% 将cos和sin拼接为36bit(各自18bit),此数据输出到FPGA
fid=fopen('cos_sin_lut_4.coe','wt');
fprintf( fid, 'MEMORY_INITIALIZATION_RADIX = 16;\n');                     
fprintf( fid, 'MEMORY_INITIALIZATION_VECTOR =\n');

for i = 1:1:(2^in_quantify_bit)
    fprintf(fid,'%c%c%c%c%c%c%c%c',s(i,:));
    if (i < 2^in_quantify_bit)
        fprintf(fid,',\n'); 
    else
        fprintf(fid,';\n');  % 分号(;) 结束标志位
    end    
end
fclose(fid);

有几点需要注意的地方:

  1. 因为是非半字节,所以不能直接去做数据拼接,而是需要先将10进制转换成2进制;
  2. 因为matlab没有2进制直接转16进制的函数,所以拼接完了之后需要先将2进制转换成10进制,然后再将10进制转成16进制;
  3. 10进制转2进制的时候注意制定转换位宽,否则数据拼接的结果就会出现问题。
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jjzw1990

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值