HDL的matlab定点化算法仿真怎么做?
假设a是量化前的数据,A是量化后的数据。
如果要保留n位二进制小数,则matlab中的量化代码为
A = floor( a*2^n ) / 2^n;
上面是普通情况,还有特殊情况:
比如要将弧度量化,pi量化成“1000”,
那么pi/2量化成“0100”,
2*pi刚好溢出,量化成“0000”
那么对于任意弧度theta的量化,我的做法是
最小单位 unit = pi/8;
THETA = floor( theta/unit ) * unit;
这种量化方法导致matlab仿真速度严重下降。
不知道大家是怎么做量化的,请指点一下,谢谢
第一个方法是正确的。就是Binary Scaling. 有个对应关系就是1=2^n-1; -1 =-2^n-1.
第二个方法更像是取地址,比如查个表什么的。那么对应关系是1=2^3/pi. 做法也没问题,但是比较奇怪。
建议你把具体内容详细说说。
谢谢回复
第一种,1(原数据)= 2^n (rtl)
第二种的l量化关系同你一样
第二种情况具体是这样的:
pi量化为 1000, pi*2量化为0
这种量化有两个好处
1、比如我要在每个节拍时,把theta累加,sum_theta_next <= sum_theta + theta;
因为 pi*2量化为0 ,所以rtl中就不需要对2*pi取余
2、pi*2刚好溢出,所以4bit完全用满了。
在某些情况下,比如在接收机中,数据流为4bit,如果4bit没有用满,就造成了信号的衰减,降低接收机灵敏度。
如果theta是固定的话,可以先用matlab生成一个表,然后查表就可以了。如果每次用到 floor( theta/unit ) * unit都需要计算的话可能比较慢。或者你可以这样考虑,不是每一步都需要把数这样处理,干脆整数化,最后在乘以相应的Scaling. 以下就是一个NCO的例子,里面的变量都整数化了。
% Phase Truncation DDS
clear;clc;
% declare parameter for phase accumulator
fclk = 100e6;
phase_depth = 32;
fout = 20e6;
% declare parameter for lookup table
table_depth = 16;
output_precision = 16;
% phase increment calculation
phase_inc = fout*2^phase_depth/fclk;
phase_inc = floor(phase_inc);
actual_freq = phase_inc*fclk/2^phase_depth;
fprintf('For output frequcecy = %d Hz\n',fout);
fprintf('With clock frequcecy = %d Hz\n',fclk);
fprintf('With phase bit width = %d bit\n',phase_depth);
fprintf('Phase inc value is = %d\n',phase_inc);
fprintf('Aactual frequency is = %d\n',actual_freq);
% build lookup table
N = 2^table_depth;
t = (0:N-1)*2*pi/N;
% sine/cosine calculation
cos_lut = cos(t);
sin_lut = sin(t);
% output scaling
lut_max = 2^(output_precision-1) - 1;
lut_min =-2^(output_precision-1) + 1;
cos_lut = round(cos_lut*2^(output_precision-1));
cos_lut(cos_lut>lut_max) = lut_max;
cos_lut(cos_lut<lut_min) = lut_min;
sin_lut = round(sin_lut*2^(output_precision-1));
sin_lut(sin_lut>lut_max) = lut_max;
cos_lut(cos_lut<lut_min) = lut_min;
% phase accumulator
M = 2^phase_depth;
acc = 0;
num_of_sample = 2^14; % number of samples
l = zeros(1,num_of_sample);
for i = 1:num_of_sample
acc = acc + phase_inc;
l(i) = mod(acc,M);
end
% phase quantization
l = floor(l./2^(phase_depth-table_depth)) + 1;
% sine/cosine output
cos_out = cos_lut(l);
sin_out = sin_lut(l);
谢谢你的热心解答,theta不是固定的,是计算的结果,随机的。
sum_theta也很难用查找表,在rtl中我其实用了12bit来量化的,那么我的查找表就需要2^12个值
可以使用fixed-point工具箱,我觉得比较方便
