基于简易信号发生器实现2FSK(频移键控)的调整

二进制移频键控(2FSK)

用二进制数字基带信号去控制正弦载波的载频称为二进制移频键控(2FSK)。此时对应于传号与空号的载波频率分别为f1及f2。

频移键控(FSK):

FSK时域波形:

相位不连续的2FSK信号:

相位连续的2FSK信号:

采用top_down设计思想,将正弦波产生器分为三个模块。分别是顶层模块A_sin_gen,子模块B1_addr和子模B2_sin。

 图1 设计的总体框图

       其中顶层模块主要定义输入输出关系,划分两个子模块的接口,搭建起两个子模块的框架,整个设计要素如图2所示:

 图2 顶层模块A_sin_gen的设计要素

       子模块B1_addr主要用来产生对ROM的寻址。按照时钟街拍,改变寻址的步进,就可以改变输出正弦波的频率。该模块可以采用简单的向上计数器产生。模块设计要素如图3所示:

图3. 子模块B1_addr的设计要素 

        子模块B2_sin则主要用LPM_ROM宏模块产生。

一、总体方案设计

图 1 FSK总体设计方案

图1为本次课程设计的总体方案,输入信号为时钟信号CLK和使能信号ENABLE,输出信号为调制信号。

其中输入信号CLK为50MHz的时钟信号,通过PLL锁相环实现分频和倍频,输出三路信号,分别为445MHz、890MHz和2MHz。

输入信号ENABLE分别为PLL锁相环和两个7位计数器提供使能,高电平启动,低电平关机。

正弦波数据存储ROM的地址信号发生器由7位计数器担任,其中ROM的数据长度为128,数据位宽为8,当地址发生器接收到特定时钟信号频率为f ,ROM输出的信号频率为fn=f128 ,为实现输出两路信号分别为6.5MHz和3.5MHz的频率的载波,代入公式求得两路分别输入的时钟信号频率约为445MHz和890MHz。

为了满足码元速率为1MHz的数字信号处理需求,模拟基带信号是由PLL锁相环经过分频得到的2MHz的方波信号。

在二选一数据选择器进行频率选择,根据输入的模拟基带信号的高低电平,在两个独立的正弦载波之间进行切换输出调制信号。

二、系统硬件电路设计

图2 RTL原理图

图2为Verilog语言实现的RTL原理图

三、系统软件设计

3.1主流程图

图3.1 总体流程图

3.2开始

使能信号ENABLE置高电平,启动所有时序。

3.3 频率信号发生器

该部分由三部分构成:分频和倍频器——PLL(锁相环)、ROM地址发生器——7位计数器、正弦波数据存储器——ROM。

锁相环PLL和正弦波数据存储器是调用IP核实现,ROM地址发生器是通过Verilog语言编写的,三部分是通过例化组合成的。

3.3.1锁相环配置

图 3.3.1配置输入时钟

图 3.3.2选择输入使能信号

图3.3.3配置输出时钟1

图3.3.4 配置输出时钟2

图3.3.4配置输出时钟3

图3.3.5生成可例化的.v文件

3.3.2地址发生器(7位计数器)

module addr #(parameter step = 1) //抽样频率
(clk,rst_n,RD_addr);
	input clk;
	input rst_n;
	output[6:0] RD_addr;
 
	reg[6:0] addr;
 
assign RD_addr = addr;
 
always @(posedge clk or negedge rst_n)begin
	if(!rst_n)
		addr <= 0;
	else addr <= addr + step;
end
 
endmodule

使用Verilog语言编写实现

图3.3.6地址发生器的RTL图

在输入使能信号enable为高电平时,加法器addr启动,当时钟频率来一个上升沿,就进行一位加1,当计满七位,地址发生器自动清零。地址发生器产生控制ROM波形数据表的地址,输出信号的频率由ROM地址的变化速率决定,变化越快,输出频率越高。由于ROM的容量会受到地址位宽的影响,为防止ROM的容量过大,设定地址发生器的输出位宽为7位。

3.3.3正弦波数据存储器ROM

ROM用于存放波形数据,选取ALTERA中的单端口ROM,单端口ROM只提供一个地址端口和一个读数据端口,数据位宽设为8,数据长度设为128,则数据总位数为8×128=1024。

使用quartus Ⅱ自带的Mif_Maker2010.exe波形数据生成器)

设定波形全局参数

图3.3.7配置数据长度和位宽

图3.3.8将对应的mif文件导入

图3.3.9生成可例化的.v文件

将地址发生器和正弦波数据存储器ROM组合起来即可构成最简单的DDS(直接数字合成器),根据DDS原理:fOUT=B∆θ2NfCLK ,其中fOUT 为输出信号,fCLK 为输入时钟信号,B∆θ 为频率输入字,2N 为数据长度,N 为加法器的数据位宽。在这设置的地址发生器的输出位宽为7位,而频率输入字(B∆θ )为0,则输出频率fOUT=fCLK2N ,因此,当地址发生器选择7为的加法器时,fOUT=fCLK27

3.4二选一数据选择器

module modulation(clk,DDSin,DA_Data1,DA_Data2,DDS_out);//定义模块和端口
	input clk;//输入的时钟
	input DDSin;//需要调制的信号
	input wire [7:0]DA_Data1;//输入的载波=‘0’
	input wire [7:0]DA_Data2;//输入的载波=‘1’
	output wire[7:0]DDS_out;//输出的调制完成的信号
	reg [7:0]DOUT;//模块定义内部寄存器
	always @(posedge clk)//每当时钟上升沿时触发
	begin
		if(DDSin==0)//如果输入的基带信号为0则输出位载波1
			DOUT=DA_Data1;
		else //如果输入的基带信号为1则输出位载波2
			DOUT=DA_Data2;
	end
	assign DDS_out=DOUT;//
endmodule

图3.4.1二选一数据选择器的RTL图

通过判断模拟基带信号的高低电平,对两个独立的正弦载波之间进行切换,其中clk为选择器的采样频率。

3.5频移键控FSK顶层文件例化

module FSK_2(
	input CLK,
	input ENABLE,
	output wire SIGNAL,
	output wire CLK1,
	output wire CLK2,
	output wire [7:0]DA_Data1,
	output wire [7:0]DA_Data2,
	output wire [7:0]DDS_OUT
);

MYPLL PLL(          // 例化锁相环
		.inclk0(CLK),
		.pfdena(ENABLE),
		.c0(CLK1),
		.c1(CLK2),
		.c2(SIGNAL)
	);	

addr #(.step(1))
u1(                             //例化地址发生器1
	.clk(CLK1),
	.enable(ENABLE),
	.RD_addr(RD_addr1)	
);
 
sin_rom u2(                              //例化正弦波数据存储ROM1
	.clock(CLK1),
	.address(RD_addr1),
	.q(DA_Data1)
);

addr #(.step(1))
u3(                             //例化地址发生器2
	.clk(CLK2),
	.enable(ENABLE),
	.RD_addr(RD_addr2)	
);
 
sin_rom u4(                              //例化正弦波数据存储ROM2
	.clock(CLK2),
	.address(RD_addr2),
	.q(DA_Data2)
);

modulation choose(  //例化数据选择器
	.clk(CLK1),
	.DDSin(SIGNAL),
	.DA_Data1(DA_Data1),
	.DA_Data2(DA_Data2),
	.DDS_out(DDS_OUT)
);
endmodule

图3.5.1 RTL原理图

2FSK(频移键控)原本只有两路输入信号(使能信号ENABLE和输入时钟信号CLK)和一路输出信号(已调信号DDS_OUT),但为了方便后续的signal测试和modelsim仿真,另外引出了5路输出,其中DD_Data1和DD_Data2代表的输出两路不同频率的载波信号;CLK1和CLK2是经过锁相环PLL倍频后,输出的两路更高频率的时钟信号;最后一个SIGNAL——模拟基带信号,为了实现2FSK(频移键控)调整,且码元速率为1MHz的条件,将输入时钟信号CLK经过锁相环PLL分频得到0.5MHz的模拟基带信号SIGNAL,一高电平和一低电平为一周期,分别代表数据比特的“0”和“1”,一高电平或一低电平所占的时间为1000ns,相当于码元速率1MHz。

3.6配置modelsim仿真程序

`timescale 1 ns/ 1 ps
module FSK_2_vlg_tst();
// constants                                           
// general purpose registers
// test vector input registers
reg clk;
reg rst;
// wires                                               
wire [7:0]  DA_Data1;
wire [7:0]  DA_Data2;
wire [7:0]  DDS_out;
wire canshu;

// assign statements (if any)                          
FSK_2 i1 (
// port map - connection between master ports and signals/registers   
	.DA_Data1(DA_Data1),
	.DA_Data2(DA_Data2),
	.DDS_out(DDS_out),
	.canshu(canshu),
	.clk(clk),
	.rst(rst)
);
initial                                                
begin                                                  
clk = 0;
rst = 0;
#5 rst = 1;                                            
$display("Running testbench");                       
end                                                    
always #10 clk = ~clk;                                                 
                                                  
endmodule

  • 21
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值