调制技术在通信系统中,由于一般情况下信道不能直接传输基带信号,因此必须用基带信号对载波信号(通常是正弦波)的某些参量进行控制,使其随着基带信号的变化而变化,这个过程称作调制,得到的信号称作调制信号(已调信号)。 正弦波作为载波信号有三个参量可以携带信息:幅度(调幅AM)、频率(调频FM)和相位(调相PM)。在数字系统中,由于信号都是离散化的值,调制的参量也是一些离散的状态,因此调制信号通常被称作键控信号,三种调制方式也对应称作振幅键控ASK、频移键控FSK和相移键控PSK。 ASK调制ASK可分为二进制振幅调制(2ASK)和多进制振幅调制(如4ASK),这里的“进制”指的是信号所携带的信息量。 如2ASK调制系统中,数字信息只有0和1两种,所调制的载波信号的幅度变化状态也只需要两种:无载波输出时代表发送0;有载波输出时代表发送1。4ASK调制系统中,数字信息就有00、01、10、11四种,需要载波信号幅度的4个电平状态表示。显然,进制越大,相同频带内可以传输的数据信息量也就越多,即频带利用率越高。 ASK调制系统的模型如下所示:
基带信号m(n)可以看作一串由0、1组成的矩形脉冲信号,理论上其带宽是无限的,与载波信号调制之后的键控信号s(n)带宽也是无限的。工程中为了提高频带利用率,需要对信号带宽做限制,通常只需要将在主瓣带宽内包含90%能量的信号发送出去即可。 有两种方法可以实现:(1).在输出端加上带通滤波器筛选主瓣带宽;(2).在调制前先对基带信号m(n)做成形滤波,滤除主瓣外的频率成分。成形滤波通常都选择升余弦滚降滤波器,本质上也是一种FIR滤波器。 matlab设计在FPGA设计前通常都会使用MATLAB对系统进行建模与仿真。设计ASK调制系统时,选定系统参数:基带信号的符号速率Rb、载波频率Fc、采样频率Fs、升余弦滤波器的滚降因子α。 可以使用randi函数生成随机的二进制序列作为基带信号;rectpulse函数实现对基带信号的采样;rcosflt(老版本)或rcosdesign(新版本)函数实现成形滤波。主要代码如下: code_2ask = randi(2, 1, Len) - 1; %产生随机分布的二进制数据code_2ask_upsamp = rectpulse(code_2ask, Fs/Rb); %对基带数据以Fs速率采样code_2ask_filter = rcosflt(code_2ask, 1, Fs/Rb); %对基带数据进行成形滤波,同时进行Fs/Rb倍采样ASK2 = carrier .* code_2ask_upsamp; %产生未进行成形滤波的2ASK信号ASK2_filter = carrier .* code_2ask_filter(1:LenData)'; %产生成形滤波后的2ASK信号本系列主要是讲述FPGA设计,不详细讨论上述函数的使用,具体情况可以的MATLAB的help中查询。 FPGA设计在Vivado开发环境下完成4ASK调制技术的设计并进行仿真(为了能更直观地观察调制效果,这里省略了成形滤波器及带通滤波器)。模块接口如下: `timescale 1ns / 1ps
//-----------------------------------------------------------
// 4ASK制
//-----------------------------------------------------------
module ASKmodulation_liuqi
( input rst,
input clk, //系统时钟8*Rb(采样频率)
input [1:0] din, //基带数据输入(速率为Rb)
output signed [13:0] dout //ASK调制信号输出
);采样时钟设置为基带信号的码元速率的8倍,输出的ASK调制信号位宽由载波信号的位宽决定。
载波信号频率设置为2MHz,由Vivado提供的DDS Compiler IP核产生DDS的参数设置将决定载波信号的位宽,进一步会决定ASK调制信号的位宽。本设计将DDS的无杂散动态范围设置为80dB,对应的位宽为14bit。实例化代码如下: //-----------------------------------------------------------
// DDS Compiler IP核生成本地载波信号(2Mhz)
//-----------------------------------------------------------
wire out_valid;
wire [15:0] dds_data;
wire [13:0] sin_data = dds_data[13:0];
dds U0
(
.aclk(clk),
.m_axis_data_tvalid(out_valid),
.m_axis_data_tdata(dds_data)
);
设计中使用载波信号最大幅值的0、1/3、2/3、1倍来分别表示四进制基带信号的00、01、10、11。调制部分的代码如下: //-----------------------------------------------------------
// 调制,0、1/3、2/3、1代表四种数字信息
//-----------------------------------------------------------
reg [13:0] ask_data;
always @ (posedge clk or posedge rst)
if (rst) ask_data <= 'd0;
else
case (din)
//"00"--0
2'd0 : ask_data <= 'd0;
//"01"--1/4+1/16+1/32≈1/3
2'd1 : ask_data <= {{2{sin_data[13]}},sin_data[13:2]}
+ {{4{sin_data[13]}},sin_data[13:4]}+{{5{sin_data[13]}},sin_data[13:5]}; //"10"--1/2+1/8+1/16≈2/3
2'd2 : ask_data <= {{2{sin_data[13]}},sin_data[13:2]}
+ {{2{sin_data[13]}},sin_data[13:2]}+{{2{sin_data[13]}},sin_data[13:2]}; //"11"--1
2'd3 : ask_data <= sin_data;
default : ask_data <= 'd0;
endcase
assign dout = ask_data;
endmodule 在采样时钟的控制下,使用Verilog HDL的case语法对基带信号数据din做判断,从而决定ASK调制信号的输出幅度。由于FPGA实现1/3、2/3这种除法运算很消耗资源,这里使用“移位相加”的组合方式代替除法,实现相同的效果。注意整个系统采用的都是带符号数二进制补码,因此移位时高位应该补符号位。 当然,调制毫无疑问也可以用乘法器实现,尤其是如果使用成形滤波器对基带信号滤波后(位宽会扩展),只能使用乘法器调制,不能像上面一样用case语句判断。使用乘法器调制的代码如下: //-----------------------------------------------------------//
调制,0、1/3、2/3、1代表四种数字信息
//-----------------------------------------------------------
wire signed [15:0] ask_data;
mult_gen_0 U1
(
.A (din),
.B (sin_data),
.P (ask_data)
);
assign dout = ask_data[15:2];
endmodule
乘法器的A端口(对应基带信号输入)设置为无符号数,B端口(对应载波信号输入)设置为带符号数,输出截位后作为ASK调制信号的输出。整个工程的RTL视图如下:
从图中可以看出DDS输出的载波信号和基带信号送入乘法器,截尾后得到ASK调制信号输出。 仿真与工程下载编写testbench,主要是基带信号的产生。当然可以像前面仿真FIR、FFT时一样,使用MATLAB生成一组随机二进制数据存入txt中,在testbench中读取txt文件作为基带信号。 本设计采用一种简单的基带信号产生方式,设置一个5位计数器cnt,截取高两位cnt[4:3]作为基带信号。仿真效果如下图所示(上文两种调制方式的仿真结果一样):
很明显看到输出的ASK调制信号dout有4种电平状态,且与基带信号的值之间一一对应。
|