本文是该系列的第15篇。数字控制振荡器(NCO)是FPGA中常用的一个模块,在《FPGA数字信号处理系列》第一篇就对其做了相关介绍。System Generator中的block大致可以分为两类:高层次封装(面向系统级,如第2篇设计中用到的Digital FIR Filter)和低层次封装(面向底层,与FPGA资源的联系更直接)。
本文将采用IIR滤波器、DDS、DDS Compile IP核3种设计原理在System Generator中实现NCO。前两种采样低层次封装block,后一种采用高层次封装block,体会其中的差别。
基于IIR滤波器的NCO实现
1.搭建模型
使用一个二阶IIR滤波器对单位脉冲信号滤波,只要保证系统的极点位于S域的单位圆上,即可得到正弦波输出。在Simulink中添加block按下图连接:
ulse Generator输出单位脉冲信号,采用延迟器(Delay)、乘法器(Mult)、加法器(AddSub)和存储IIR系数的Constant模块(分子为1,分母为b=1.75)。
2.原理分析
使用信号与系统理论知识简单分析上述系统:
本设计采样100MHz系统采样率,b取1.75,代入上式计算可得IIR滤波器输出的正弦波频率为8.0431MHz。在采样率确定的情况下,改变系数b即可改变输出振荡信号的频率。
3.仿真验证
在运行前要确保两点:
运行仿真,Scope中观察到的信号波形如下:
在脉冲信号输入以后,IIR滤波器的输出开始正弦振荡。频谱图如下:
谱峰值在8MHz附近,验证结果正确。
基于DDS原理的NCO实现
1.搭建模型
DDS原理是使用相位累加器器+查找表,完成信号相位到幅度的转换。在《FPGA综合系统设计系列》第4篇中讨论了其原理及列出了相关参考文献。在Simulink中添加block按下图连接:
Constant模块从外部输入频率控制字,地址位宽8Bits,相位累加器由一个加法器(AddSub)和寄存器(Register)构成。ROM作为查找表(LUT)存储正弦波波形数据,设置如下:
深度Depth为256,与地址位宽相对应;Initial value vector中存储一个周期的正弦波数据,即相当于把2π的相位平分为256份。通过ROM,可以完成从相位到幅度的转换。
2.仿真验证
系统采样率设置为100MHz,频率控制字设置为1(最小频率分辨率)。运行仿真,Scope中观察波形如下:
图中1和2两根标签表示了一个信号周期,可以清楚地看到信号相位与幅度之间的关系。
基于DDS Compiler的NCO实现
1.搭建模型
在《FPGA数字信号处理系列》第一篇中介绍了Vivado DDS Compiler IP核的用法,该IP核采样的原理与上一小节相同。上一节中我们搭建了DDS的每一个实现细节,本设计将直接采用高层次封装的block实现NCO功能。添加block按下图连接:
data_tready接口赋1,永远保持有效。使用Scope观察DDS Compiler输出的正弦波和余弦波。此外还有一个输出有效信号data_tvalid,在设计中不需要,为其连接一个Terminator,这样在运行时不会因为管脚没有连接而报错。
2.仿真验证
系统采样率设置为100MHz。DDS Compiler的SFDR设置为95dB(对应数据输出位宽为16Bits),频率分辨率0.4Hz。设置输出信号频率为10Mhz。输出信号的频谱即波形如下所示:
主要频率成分为10Mhz,验证结果正确。
Simulink仿真技巧
这里列出本文在仿真过程中用到的一些基本设置方法:
不同层次封装block对比
在上面第一个和第二个设计中采用了低层次封装的block,最后一个设计采用了高层次封装,主要区别如下:
文章来源:FPGADesigner的博客
*本文由作者授权转发,如需转载请联系作者本人