FPGA产生2FSK信号(1)

邮差的信 提交于 2020-11-21 13:28:29

目录

FPGA产生2FSK信号(1)

一、2FSK介绍

1、相干解调:

2、非相干解调

二、FPGA生成2FSK方法

1、正弦ROM表产生

(1)生成mif文件

(2)生成rom IP核并导入mif文件

(3)生成计数器

(4)计数器和rom整合

2、数字基带控制正弦ROM表

3、Modelsim仿真验证


开发环境:

FPGA: cyclone iii

软件:quartus ii13.1+modelsim,matlab2016b

语言:Verilog HDL

一、2FSK介绍

FSK是信息传输中使用得较早的一种调制方式,它的主要优点是:实现起来较容易,抗噪声与抗衰减的性能较好。国际电信联盟(ITU)建议在传输速率低于1200b/s时采用2FSK体制,其在中低速数据传输中得到了广泛的应用。所谓FSK就是用数字信号去调制载波的频率。

调制方法:2FSK可看作是两个不同载波频率的ASK已调信号之和。

解调方法:相干法和非相干法。

2FSK示意图

 

1、相干解调:

相干解调

 

2、非相干解调

过零检测

 

包络检波

 

二、FPGA生成2FSK方法

如图所示,2FSK产生的方案,利用基带信号控制DA的ROM表,从而实现FSK调试。

FPGA生成2FSK方案框图

 

1、正弦ROM表产生

下面详细讲解下如何生成ROM表。

正弦ROM表应该有这样的功能:输入时钟信号,输出幅度值(数字)。然后输出的幅度送给DA让其输出实际对应的模拟电压信号。

正弦rom表功能图

 

想要有这样的功能,首先正弦rom表中要存储正弦数值,以mif的形式导入到创建的rom IP核中;然后创建计数器使其根据时钟信号生成地址,对应为rom表中数据的存储位置。

正弦rom表内部结构

 

要想生成正弦rom表,首先要明确正弦的表达为:Asin(wt+\varphi ),其三要素为幅度A,频率w和相位\varphi。幅度A在二进制中和位宽n有关 2^{n}=A,频率和一个周期的点数有关,相位这里先不考虑。

正弦ROM表里面存储的点数,是根据DA输出一点需要的频率和要输出的正弦频率来确定。

正弦波示意图

图中一个点的频率为f1,正弦波的频率为f2,正弦波一共有16个点,那么三个数之间的关系为f2=f1/16。这里f1也叫做采样率,也就是采样率/(一个周期的点数)=这个周期对应的频率。

这里我的DA输出频率为2M,我想输出的正弦波频率为4k和12.5k,那么需要rom表的点数为2000/4=300,和2000/12.5=160。

(1)生成mif文件

利用matlab生成mif文件,DA的位数为16位,单极性器件,因此这里的mif文件里面正弦波的数据位宽要为16位,无符号型。

这里需要注意的是信号的位宽为16位无符号数,那么可以表示的信号范围为0~2^16-1=65535,在设置信号的幅度A和直流分量的时候要保证不能溢出,比如当A=2^15,ADC=2^15的时候最大值为2^16会溢出。

F1=1; %信号的频率
P1=0;%信号初始相位
Fs=300;%采样频率
N=300;%采样点数为N
t=[0:1/Fs:(N-1)/Fs];%采样时刻
ADC=2^15-1 ;%直流分量
A=2^15-1;%信号幅度
s=A*sin(2*pi*F1*t + pi*P1/180)+ADC;%生成信号
plot(s);%绘制图形
fild = fopen('d:/DA_4k.mif','wt');%创建mif文件
%写入mif文件文件头
fprintf(fild, '%s\n','WIDTH=16;');%位宽
fprintf(fild, '%s\n\n','DEPTH=300;');%深度
fprintf(fild, '%s\n','ADDRESS_RADIX=UNS;');%地址格式
fprintf(fild, '%s\n\n','DATA_RADIX=UNS;');%数据格式
fprintf(fild, '%s\t','CONTENT');%地址
fprintf(fild, '%s\n','BEGIN');%
for i = 1:N
    s2(i) = round(s(i));    %对小数四舍五入以取整
    if s2(i)<0     %强制将负1置0,
       s2(i) = 0;
    end
    fprintf(fild, '\t%g\t',i-1);%地址,从0开始编码
    fprintf(fild, '%s\t',':');
    fprintf(fild, '%d',s2(i));
    fprintf(fild, '%s\n',';');
end
fprintf(fild, '%s\n','END;');%地址

(2)生成rom IP核并导入mif文件

打开工具栏的IP核生成助手

 

创建一个新的自定义的宏文件

选择memory里面的ROM,然后文件输出位置要在project文件下,直接在后面命名就可以。

 

宽度wide指的是mif中的位宽,这里用的是16位,数量我们用的是300个,不能少于这个数量,因此这里选择用512个。

 

保持默认Next

 

选择 mif文件,要注意mif文件也要拷贝放到工程目录下,不然会造成在后面modelsim仿真的时候出现没有波形的奇怪错误(这个bug,调了半天)。

保持默认Next

 

勾选inst初始化调用模板。最后点击finish。

 

在project下打开inst文件,复制到工程中就可以调用rom IP核。

sin_rom   sin_rom_inst (
                         .address ( address_sig ),

                          .clock ( clock_sig ),

                           .q ( q_sig )

                           );

(3)生成计数器

计数器应该有这样的功能:

1、向上计数和向下计数(updown);

2、计数开始数据(基数)输入(data);

3、计数结果输出(q);

4、进位输入(carry in);

5、进位输出(carry out);

6、载入基数(load);

7、时钟输入(clk);

计数器模型

我们想实现300个地址的寻址计数,那需要设置:计数开始值为300,向下计数,当300个初始值计完,产生进位cout这个信号给laod,让其再次载入初始值300,进入下一轮的计数。

 

下面是具体的操作过程:

选择数学运算中的参量化模拟库(Library of parameterized modules)LPM_COUNTER,然后命名

 

数据位宽选择9位的,因为是300个数,至少需要9位(2^9-1=511)来表示。选择向下计数模式。

 

选择进入输出。和load配合保证下一轮的计数。

 

选择同步load

 

保持默认,Next下一步。

选中conter_inst。

 

(4)计数器和rom整合

module DAROM_4k(
clk,
sinromout_A,
);
input clk;
output sinromout_A;
wire [15:0] sinromout_A;


wire cout_sig;
wire [8:0]addr_A;
conter	conter_inst (
	.clock ( clk ),
	.data ( 9'd499),
	.sload ( cout_sig ),
	.cout (cout_sig),
	.q ( addr_A)
	);
sin_rom	sin_rom_inst
(
	.clock(clk), 
	.address(addr_A), 
	.q(sinromout_A)
);
endmodule

 

2、数字基带控制正弦ROM表

基带信号作为判断的依据来控制正弦rom1和rom2的输出,这里使用assign语句来实现。

assign DA_SINROM=(baseband_data==1)?DAROM_12k5:DAROM_4k;

3、Modelsim仿真验证

点击processing-start-start Test Bench Template Writer自动创建test Bench文件

 

生成的文件为project/simulation/modelsim下的.vt文件,打开文件把该文件名修改成和顶层文件相同的名字。

 

 

根据硬件实际情况,添加需要的时钟和基带信号。

 

点击Assignments-Settings,进入仿真设置界面,配置modelsim相关文件。

 

进入simulation界面,更改配置入图中所示,然后点击Test Benches。

 选择新建,然后点击图中file name,在project/simulation/modelsim下选择生成的vt文件。

 

 

然后把文件名字复制一下,粘贴到Test bench name,再点击Add。

 点击OK

 

 

点击OK

点击RTL仿真。

生成了仿真波形图,波形会频率会随着基带信号发生变化,实现调相功能。--成功

 

想生成上图的正弦波形,右击波形的左侧,选择Format-Analog(custom),根据自己的数据大小修改下最大值和最小值。

                                                                                                     

 

 

 

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!