本文是在做无线信号功率统计时,所涉及到的一些知识点。使用AD936X芯片采集到的无线信号最后转换到两路I、Q信号,什么是IQ信号,学通信的应该都知道,我是简单的把它理解为,IQ信号在数值上相等,相位差90°。
在进行功率统计计算时会有i2+q2这样的运算,不仅有乘法还会有累加,然后再求平均,这里就先说乘法,其他的以后再说了。
在软件设计里两个数的相乘可以直接“*”,但是在FPGA的设计里面,如果直接将两个数相乘,会占用大量的LUT逻辑资源,而且会减慢硬件的运算速度。
Verilog实现乘法有多种方法,一是直接使用官方的IP核简单方便,速度还快;二是自己写RTL代码,对于刚接触的人来说还是要花点功夫的。所以这篇文章介绍Xilinx乘法器IP核的配置使用方法、不同配置下资源占用情况,以及和自己设计的RTL多级流水乘法器对比,本文只针对Xilinx Multiplier IP的使用
Multiplier的配置:对于Multiplier IP核的配置还是比较简单的,个人觉得注意以下几点就行了。Data Type:根据自己输入数据是符号数据还是无符号数据进行选择;Width:输入数据位宽,这个就根据自己的情况设置了。
Multiplier Construction:这个选项是来设置Multiplier是用哪种片上资源来实现(DSP48 or LUT),这需要结合你自己的工程考虑了,如果片子里DSP资源比较紧张,那就选择LUT构成乘法器;LUT资源紧张则可考虑用DSP48来实现;
Optimization Options:这个就牵扯到速度与面积的选择了,这个需要根据具体情况具体来说。
其他的都是默认配置。
既然是乘法运算,那么怎么能少了数据呢?
我这里是在网上找的一段程序用matlab生成一组i q数据,程序运行后只有一个i.coe文件,看了下文件里数据是个正弦波,我将i.coe里数据移了几位生成q.coe文件。
clc
close all
fid = fopen('i.coe','w');
fprintf( fid,'memory_initialization_radix=16;\n');%生成索引
fprintf( fid, 'memory_initialization_vector =\n' );
fs = 1e6;
f = 0.1e6;
N = 10000; %10ms
t = (0:N-1)/fs;
for j = 1:1:32767
i = j*cos(2*pi*f*t);
q = j*sin(2*pi*f*t);
y = i + 1i*q;
y_pow = 10*log(mean(abs(y).^2)/2^31);
if(y_pow >= -16.2)
fprintf('y_pow = %4.2f;j = %d\n',y_pow,j);
break;
end
end
i = round(i);
q = round(q);
for k = 1:1:N
a(k) = q(k);
if(a(k) >= 0)
a(k) = a(k);
else
a(k) = a(k) + 65536;
end
if(k < N)
fprintf(fid,'%x,\n',a(k));
else
fprintf(fid,'%x;\n',a(k));
end
end
fclose(fid);
这里我新建两个ROM,将两组数据存放到ROM中,然后读出来再送到乘法器中做运算。一个工程ROM和DSP都用到了,两个知识点。
工程编译无误之后进行仿真,看看这个乘法运算行不行。这里我使用modelsim进行仿真
可以明显的看到iq两路数据波形,这里为了有那么个意思,就只将两路IQ数据进行乘法运算
用计算器算了一下,结果是一样的。
至于multiplier IP中,使用LUTs和Mults两种资源消耗情况的对比实验没有做。
我的FPGA工程:https://download.csdn.net/download/panweiwen0/22780777