上一篇介绍了数字通信系统中ASK调制技术的FPGA实现。调制信号经过DAC、可选的带通滤波器、功率放大器、天线发送出去后,在接收端收到ASK信号后需要对其解调,提取出包含的信息(基带信号)。无论在哪种调制解调系统中,解调总比调制要复杂很多,本文开始将介绍ASK解调系统的实现。
ASK信号的解调有包络检波法(非相干解调)和同步检测法(相干解调)两种方法。同步检测法系统框图如下:
“相干”指的是接收端必须提取出一个与载波同频、同相的信号(窄带滤波器、锁相环),相干的程度将影响到解调性能。键控信号s(n)与相干载波c(n)做乘法后,由LPF滤除高频分量得到基带波形,再经过判决输出得到基带数据m(n)。
包络检波法的系统框图如下:
键控信号s(n)经过整流,将交流信号转换为直流信号,通过LPF得到基带信号的包络,再经过判决输出得到基带数据m(n)。包络检波法不需要提取相干载波,整体要比同步检测法简单很多。在大信噪比(≥15dB)的条件下,两种方法的误码率性能几乎差不多,而ASK调制方法大多也都应用在信噪比较大的情况下,因此工程中多使用包络检波法实现ASK信号解调。
在FPGA设计前通常都会使用MATLAB对系统进行建模与仿真。设计ASK解调系统时,选定系统参数:基带信号的符号速率Rb、采样频率Fs。可以使用abs函数对ASK信号整流,设计的低通滤波器截止频率Fc设置为Rb。主要代码如下:
ASK2 = abs(ASK2); %整流
b = fir1(32, Rb*2/Fs); %32阶LPF
d_ASK2 = filter(b, 1, ASK2);
本系列主要是讲述FPGA设计,不详细讨论上述函数的使用,具体情况可以的MATLAB的help中查询。滤波器系数经过量化后存储为txt(coe)文件,在FPGA设计中调用。
采用包络检波法,在Vivado开发环境下完成2ASK和4ASK解调技术的设计并进行仿真(符号判决模块与位定时脉冲模块具体设计见本系列第12、13篇)。模块接口如下:
`timescale 1ns / 1ps
//--------------------------------------------------------
// 包络检波法(非相干解调)实现ASK信号解调
//--------------------------------------------------------
module ASKdemod_liuqi
(
input rst,
input clk, //8MHz数据采样时钟
input clk32, //32MHz位同步时钟
input signed [7:0] din, //ASK键控信号输入
output reg [7:0] abs_din, //整流后ASK信号
output signed [13:0] dout, //解调输出基带信号包络
output signed [13:0] mean, //基带信号包络的直流分量(均值)
output bit_data, //判决输出的二进制数据流
output bit_sync //位同步信号
);
整流部分即为取绝对值,判断输入信号的符号位,为负数则取反,为正数则保持。代码如下:
//--------------------------------------------------------
// 整流(取绝对值)
//--------------------------------------------------------
always @ (posedge clk or posedge rst)
if (rst) abs_din <= 'd0;
else //负数取反;正数保持
if (din[7]) abs_din <= -din;
else abs_din <= din;
低通滤波器使用Vivado提供的FIR Compiler IP核,滤波器系数使用MATLAB生成的coe文件,具体使用方法可参考“FPGA数字信号处理(五)Vivado FIR IP核实现 https://blog.csdn.net/fpgadesigner/article/details/80621411 ”。代码如下:
wire s_tready, m_tvalid;
wire signed [23:0] m_tdata;
fir_compiler_0 U0
(
.aclk (clk),
.s_axis_data_tvalid (1'b1),
.s_axis_data_tready (s_tready),
.s_axis_data_tdata (abs_din),
.m_axis_data_tvalid (m_tvalid),
.m_axis_data_tdata (m_tdata)
);
assign dout = m_tdata[19:6];
滤波器的输出为全精度输出,对其截取14bit(保留1bit符号位)作为基带包络信号输出即可。接下来实例化符号判决模块和位定时脉冲模块:
//--------------------------------------------------------
// 实例化判决门限模块,求取基带信号包络的均值
//--------------------------------------------------------
gate U1
(
.rst (rst),
.clk (clk),
.din (dout), //LPF输出的基带信号包络
.mean (mean) //基带信号的直流分量
);
//--------------------------------------------------------
// 位同步模块
//--------------------------------------------------------
wire demod = (dout > mean) ? 1'b1 : 1'b0; //判决
wire sync;
bitSync_liuqi U2
(
.clk(clk32), //32MHz系统时钟
.rst(rst), //高电平有效复位信号
.din(demod), //单比特基带数据输入
.sync(sync) //位同步脉冲输出
);
使用判决门限对LPF输出信号判决,判决结果输入到位同步模块中得到位同步时钟。下面代码完成在位同步脉冲的上升沿驱动下,提取出基带数据流:
reg data_out;
always @ (posedge sync or posedge rst)
if (rst) data_out <= 1'b0;
else data_out <= demod;
assign bit_data = data_out;
assign bit_sync = sync;
endmodule
编写testbench,主要是ASK调制信号的产生。使用MATLAB生成ASK调制信号数据存入txt中,在testbench中读取txt文件。文件操作方法参考“Testbench编写指南(一)文件的读写操作” https://blog.csdn.net/fpgadesigner/article/details/80470972 。
对2ASK信号解调的仿真效果如下图所示:
很明显看到输出的基带包络信号有2种电平状态,与ASK调制信号状态一一对应(ASK有波形时,包络为1;ASK无波形时,包络为0),只不过由于运算的关系,导致输出有一定延时。对4ASK信号解调的仿真效果如下图所示:
也可以看到输出的基带包络信号有4种电平状态,与ASK调制信号状态一一对应。
上面还没有提取出基带信号的数据。2ASK解调系统中经过判决输出和位定时脉冲两个模块提取出的基带数据流如下图:
可以看到基带数据流bit_data与解调信号dout完全对应,且与位同步脉冲bit_sync同步,因此可以提取出原始基带信息。但需要注意的是,这里判决门限的获取(求连续256个点的均值,具体见第12篇)会导致在解调的开始阶段出现错误:
由于一开始没有足够的数据点数计算正确的判决门限,导致红框内的解调数据是错误的,在应用中要注意此问题。