一、前言
本文是作者最近的课程设计,花费了不少时间,以下是自己的一些思路,希望可以帮助到正在学习的你,理解关于FM调制的FPGA-DDS实现,接着往下看吧!
平台为 Quartus 17.1
波形生成软件为 Mif_Maker2010
FPGA芯片的型号为5CEFA5F23I7,系统时钟为50MHZ
关于FM:
简单来说就是:幅度改变频率。
怎么理解呢?对FM来说:调制信号的幅度大小决定了已调信号的频率。当调制信号的幅度改变时,已调信号的频率随之改变,而幅度保持不变的。
二、本次设计的要求
FM调制的设计要求:
1、设定载波频率为5MHz,误差绝对值不大于1%,当输入调制信号幅度为0时,输出已调信号频率为中心频率5MHz,即载波频率。
2、DDS产生的调制信号频率为单频500KHz正弦信号。
3、频偏为-2MHz~+2MHz,当输入调制信号幅度最大时,输出已调信号频率为(5M+2M)Hz,当输入调制信号幅度最小时,输出已调信号频率为(5M-2M)Hz。
4、已调信号及解调信号用signal测试,使用modelsim仿真,分析测试结果并做说明。
三、系统硬件电路图
实现FM调制如上图所示,调制信号由DDS产生,由其控制已调信号的频率,图里还包括乘法器及一个定值Freq_I,看不懂没关系,这只是一个大概的轮廓,下面一步一步进行讲解。
四、产生调制信号
调制信号由DDS产生,DDS由相位累加器与ROM组成,当输入调制信号幅度为0时,输出的FM已调信号频率为5MHz,当输入调制信号幅度最大时,输出的FM已调信号频率为7MHz,当输入调制信号幅度最小时,输出的FM已调信号频率为3MHz。下面进行产生调制信号的准备工作。
1.ROM波形文件的配置
500KHz的调制信号通过DDS产生,DDS的实现需要用到ROM IP核,在配置ROM IP核之前需要用Mif_Maker2010生成IP核所需要的.mif文件。(软件放在评论区)
操作如下:打开软件,打开全局参数,设置生成的波形数据为有符号10进制,初始相位为0,如下图:
然后点击正弦波波形,点击文件,点击保存,如下图:
生成mif文件,用记事本打开,如下:
因为设置的初始相位为0,故第一个数据为相位为0时的数据,对应正弦波幅度为0的点
相位为0时,输出数据为0000,如上图
相位为90度时,对应正弦波幅度最大的点,输出数据为2047,如下图:
相位为270度时,对应正弦波幅度最小的点,输出数据为-2048,如下图:
2.调用一个单口ROM IP核
设置ROM位宽为12为,深度为1024,如下图:
选择刚刚设置好的mif文件,如下:
配置完以上几部分,就开始来到了我们的DDS设计了,跟着往下看看吧!
3.DDS的设计
由于公式重新打一份太麻烦了,直接看以下我写的报告的截图吧,以下分析非常重要,特别是累加器的递进值的设计(也就是频率控制字)建议慢慢理解,DDS的设计分析如下:
由以上所得,编写代码如下:
module DDS_Mod(
input clk,
input rst_n,
output signed [11:0] sin //调制信号
);
parameter Freq = 41943; //题目要求500kHz 设置频率控制字 10.24 * 2的12次方
reg [21:0]cnt_I = 0; //22位
wire [9:0] addr_I;
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
cnt_I <= 0;
end
else begin
cnt_I <= cnt_I + Freq;
end
end
assign addr_I = cnt_I[21:12]; //右移12位,相当于除以2的12次方
rom1 b2v_inst2( //调用ROM,将右移后的值送入ROM的地址端
.clock(clk),
.address(addr_I),
.q(sin));
endmodule
通过以上的论述分析,此部分首先设置频率控制字,通过累加器控制读取ROM数据的速度,再通过例化语句,调用ROM,将ROM的输出端命名为sin,将移位后的累加值送入ROM的地址输入端,完成DDS模块的代码设计。
总之,理解DDS的就是要理解 频率控制字为什么这么设置,累加器的位数为什么这么设置。明白后,我们进行FM的设计。
五、产生已调信号
以下是FM模块的设计,FM实际上就是一个DDS,其频率变化是建立在载波之上的,只要确定载波的频率控制字,再其基础上,加上一个会变化的频偏控制字,即可调节输出的频率。放上三张长长的图片进行说明,可以仔细观看,相信一定有所理解。
由以上分析可知,需要配置乘法器,配置如下,为12位与13位的输入,有符号型:
FM的ROM的配置可以与DDS的一致,也可以不同,这里的ROM与DDS的不是同一个,请注意。
FM的代码如下:
module FM_Mod(
input clk,
input rst_n,
input signed [11:0] adc_data,
output [11:0] FM_Mod
);
parameter signed Freq_I = 31'd6710886; // 102.4 * 2的16次方
parameter signed Freq_Word = 23'd2684356; // 40.96 * 2的16次方
wire signed [34:0] mult_data;
wire signed [23:0] Freq_Offset;
mult1 b2v_inst6(
.clock(clk),
.dataa(adc_data),
.datab(Freq_Word),
.result(mult_data)
);
assign Freq_Offset = mult_data[34:11]; //移位 除法 2的11次方
reg signed [25:0] cnt_I;
wire [9:0] addr_I;
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
cnt_I <= 0;
end
else begin
cnt_I <= cnt_I + Freq_I + Freq_Offset;
end
end
assign addr_I = cnt_I[25:16] ; //移位 除法 2的16次方
myrom b2v_inst(
.clock(clk),
.address(addr_I),
.q(FM_Mod)
);
endmodule
通过以上的论述分析,此部分首先设置Freq_I与Freq_Word的值,设置输入端为adc_data(DDS的输出端,在顶层文件将其关联),通过例化语句调用乘法器计算出频偏控制字,因为ROM的输出数据为有符号型,故将有关数据定义为有符号型,将频率控制字与频偏控制字的和作为累加器的递进值,控制读取ROM数据的速度,以控制波形的频率。再通过例化语句,调用ROM,将ROM的输出端命名为FM_Mod,将移位后的累加值addr_I送入ROM的地址输入端,完成FM模块的代码设计。
六、顶层模块设计
顶层模块就是将其例化,再将他们关联起来,具体可看前文的系统硬件电路图,代码如下:
module TOP(
input clk,
input rst_n,
output [11:0] FM_Mod_data,
output [11:0] adc_data
);
//----------------DDS-----------------//
DDS_Mod DDS_Mod_inst(
.clk (clk),
.rst_n (rst_n),
.sin (adc_data)
);
//---------------FM调制----------------//
FM_Mod FM_Mod_inst(
.clk (clk),
.rst_n (rst_n),
.adc_data (adc_data),
.FM_Mod (FM_Mod_data)
);
endmodule
前面已经设计好了DDS与FM模块的代码,顶层文件只需将其关联起来,此部分首先定义了顶层文件的输入端clk与rst_n, 输出端FM_Mod_data和adc_data,其中,FM_Mod_data为已调信号的输出,adc_data为DDS调制信号的输出。然后,通过例化语句调用DDS模块,将DDS的输出端sin命名为adc_data,再通过例化语句调用FM模块,将其输入端命名为adc_data,与DDS的输出端相关联,即调制信号输入至FM模块,将其输出端命名为FM_Mod_data,完成顶层文件TOP的代码设计。
七、TestBench的设置
将顶层文件转换成vt文件,即可编写测试文件的代码,测试文件首先确定了仿真的精度为1ps,时钟为1ns。定义输出端 FM_Mod_data与 adc_data;设置clk为10ns翻转一次,即周期为20ns,即clk为50MHZ,复位信号 rst_n为0(各模块为低电平复位),在100ns后复位信号变为高电平。然后通过例化语句调用TOP模块,输出调制信号adc_data,已调信号FM_Mod_data,在复位信号撤销后,输出调制信号与已调信号,便可测试设计的正确与否,完成测试文件的设计,代码如下图:
`timescale 1 ns/ 1 ps
module TOP_vlg_tst();
reg clk;
reg rst_n;
wire [11:0] FM_Mod_data;
wire [11:0] adc_data;
TOP i1 (
.FM_Mod_data(FM_Mod_data),
.adc_data(adc_data),
.clk(clk),
.rst_n(rst_n)
);
initial clk = 1;
always #10 clk = !clk;
initial begin
rst_n = 0;
#100
rst_n =1;
end
endmodule
八、仿真波形
调制信号的波形图如下
频率为500KHZ,如下图
已调信号的波形如下(调制信号幅度最小时)
已调信号的波形如下(调制信号幅度最大时)
从仿真结果来看,效果明显,符号题目要求。
另外,下图是signal测试的结果,与仿真结果一致。
八、总结
以上的实现过程,只能从仿真与实验的层面去大致实现一个FM调制的效果,实际应用远非如此。
FM调制在实现方式上还是比较简单的,多看一些文章后应该能理解。文章来源:https://www.toymoban.com/news/detail-767305.html
另外,如有需要改进的地方,欢迎各位指出。文章来源地址https://www.toymoban.com/news/detail-767305.html
到了这里,关于FM调制的FPGA-DDS实现的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!