目录
放在前面:
有疑惑或者补充的地方欢迎大家在评论区进行探讨,共同进步!
预备知识
零扩展和符号扩展
(1)补零扩展:填充一定位数的0。
(2)补符号位扩展:填充一定位数的符号位(非负数填充0,负数填充1)。
(1)使用补零扩展能够保证二进制存储的一致性(和我们数学常理一致),但不能保证十进制值不变。所以,处理无符号二进制数的时候,可以使用零扩展(zero extension)将小位数的无符号数扩展到大位数的无符号数
(2)使用补符号位扩展能够保证十进制值不变,但不能保证二进制存储的一致性(负数的补码变了,需要 &0xff),而处理不同长度的有符号数时,我们必须使用符号扩展。
————————————————————————————————---------------------------------
DDS
使用DDS_IP核的一些小结
在FPGA系统的设计中,笔者目前经常使用到vivado中提供的IP核,例如乘法器、DDS等,每次设计都会搜搜相关的案例进行学习,copy一下代码什么的,主要以功能的实现为主,所以学习的不是特别深入,IP核的配置其实每次都不是特别清晰。尤其是此次卡了两天的模块,光顾着改代码调试了,没抓住DDS的原理,白白的把时间都浪费了。所以说,还得搞明白原理,理论知识和IP相关配置都要搞明白才能灵活的运用IP核完成设计需求。
DDS说的通俗简单一点,主要涉及到两个核心部分:相位累加器和波形查找表,DDS主要就是用来产生不同频率的正弦信号。那么如何产生呢?使用过DAC模块跟ROM_IP核的同学应该会比较熟悉,我们通常往ROM_IP中存入正弦波一个周期的离散点数据,通过读ROM的方式产生这个正弦波。DDS中的波形查找表LUT也是这个作用,就是存放了一个周期正弦波波形的数据。通过相位累加器输出的地址在波形查找表中查找对应的幅值信息,从而生成正弦波,也就完成了DDS的功能。
DDS_IP中的三种配置模式就很清晰了:
①相位累加器和波形查找表(Phase Generator and SIN COS LUT)即能完成DDS的功能;
②仅相位累加器(Phase Generator only),配置为此项后你会发现,输入只有时钟信号,只能输出供波形输出用的相位信息也就是查找地址。作用就是控制输出信号的频率。
③仅波形查找表(SIN COS LUT only),配置为此项后,输入有时钟信号和相位信号(即查找地址),此时的作用相当于一个存放了波形信息的ROM,通过输入的相位信息(地址),来查找对应波形的幅值信息输出,产生正弦波。
关于DDS的使用一定要把相位累加器和波形查找表两部分及其关系搞懂。
DDS_IP核的配置
打开IP仓库找到DDS的IP核-DDS Compiler
可以看到底框为蓝色的其实都是同一个IP核,这里只不过是根据不同的类查询出来的。
打开配置页面
这里关于输出宽度和相位宽度该怎么考虑呢?
输出宽度:就是我们让DDS输出数据的宽度,例如此处我想让我的12bit数据和DDS通过乘法器进行混频,那么我的DDS的输出数据就要是12bit。大家根据自己的实际需求进行选择和计算。
相位宽度:即相位累加器的精度,影响频率分辨率,例如,假设DDS的时钟频率是100 MHz,且使用一个 16位 的相位宽度,最小的频率步长为1.53 Hz。较大的相位宽度提供更小的频率分辨率,从而使频率的变化更加精细。
相位增量控制字Streaming应用于频繁改变频率,或者FM频率调制;
相位增量值直接取自phase通道
相位偏移控制字Streaming经常改变,应用于相位调制;
到此配置完毕,其他配置默认即可,输出产生IP核。
DDS_IP核的例化
介绍几个关键的参数(个人理解):
s_axis_config_tvalid:相当于一个配置通道的使能信号,高电平有效
s_axis_config_tdata:高16位用于储存相位信息(偏移的相位=2p*此值除以2^相位累加器位宽),后16位为频率控制字
m_axis_data_tvalid:输出有效信号
m_axis_data_tdata:(关键)输出信号,高位是sin,低位是cos
m_axis_data_tdata只能按字节处理,即位宽为8的倍数,缺位的话就要进行符号扩展处理。这里是对输出数据12bit而言,所以输出数据实际上输出16bit。例如此处我的输出数据为12bit。sin信号有12bit,cos信号有12bit。这两路信号均扩展到了16bit,则总的输出信号为32bit。参考下面的图
sin和cos均输出的情况对应 a)类
则输出中sin信号有效位为[27:16];cos信号有效位为[11:0]。
底下附一些相关博主的文章参考学习
使用IP核实现DDS - Duruofu's 个人测试
————————————————----------------------------------———--------------------------------------
Mult乘法器
Mult_IP核的配置
乘法器IP核的配置比较简单,打开配置页面,图片里都进行了详细标注
其他保持默认即可,至此乘法器IP配置完毕,输出。
Mult_IP核的例化
可以看到乘法器的参数配置非常简单
配置好时钟和A、B两路乘法器输入数据;P为输出数据。
注意乘法器我在配置时两个乘数都是有符号数据,所以这里的输入数据也必须为有符号类型。
————————————————----------------------------------———--------------------------------------
FIR
FIR_IP核的配置
这里我们使用了MATLAB生成coe文件的方式进行FIR滤波器设计
这里注意系统时钟(即例化FIR_IP的时钟)和数据采集时钟保持一致。
量化位数12/16一般选16即可。
FIR_IP核的例化
--------------------------------------------------------------------------------------------------------------------------------
AXI接口的_tdata位宽是以字节为单位,即只会是8的倍数,需要结合设计的实际位宽做相应处理。
如输入数据为12位宽,由于s_axis_data_tdata为16bit位宽,但输入信号数据为12bit位宽,因此用拼接运算符{}在高位填充补码的符号位;
.s_axis_data_tdata ({ {4{Xin[11]}},Xin}),
这个表达式将Xin[11]这个单独的位复制4次,然后与原始的Xin信号拼接在一起。
由于m_axis_data_tdata为32bit位宽,但输出信号数据有效位仅有25bit位宽,因此仅需取低25bit作为FIR滤波器输出。当然不这么操作,直接将信号赋值到实例化接口,(DDS例化里这么干了)结果也是正确的,这样做只是为了更严谨。
--------------------------------------------------------------------------------------------------------------------------------