FPGA数字信号处理(十三)锁相环位同步技术的实现

前面介绍了数字通信系统中ASK解调技术的FPGA实现,以及判决门限选择的问题。本文将介绍解调系统中的位同步技术,只有在位同步模块的控制下,才能正确的提取出基带信号中携带的数据。本文设计参考自杜勇老师的《数字调制解调技术的MATLAB与FPGA实现》。


位同步

位同步模块的主要作用是产生一个与输入数据频率一致的时钟信号,保证每一位数据判决一次,且最好在信噪比最大的时刻进行判决。目前常用的位同步技术有插入导频法、非线性变换滤波法、锁相环法和Gardner定时恢复算法。本文将采用锁相环实现位同步技术,其它方法将在后续的文章中介绍。


锁相环位同步

锁相环位同步技术的实现条件是获取基带数据的初始相位(即相邻不同码元之间的跳变时刻),这也就决定了该方法不适合于多进制调制信号的解调(如4ASK,比如00-11之间存在着01和10两个过渡码元,从而无法获得00跳变到11时的初始相位)。对于2ASK而言,只有0和1两个状态,根据判决门限做简单判决即可得到基带数据码元的初始相位。但是该方法没有考虑最佳判决时刻,因此只适合于信号质量好(SNR大)的信号。

锁相环位同步有超前-滞后型触发器型两种实现方式,本文以第一种方式实现,原理框图如下:
这里写图片描述
本地产生相互正交的超前脉冲和滞后脉冲,鉴相器(DPD)比较本地脉冲与输入信号(由判决门限判决后的单比特信号)的相位差(超前或滞后),据此来调整位同步脉冲信号的相位(扣除或附加一个时钟周期)。


FPGA设计

根据功能划分各子模块,顶层模块原理图及各子模块代码如下:
这里写图片描述
●clk_gen:该模块用于产生两路相互正交、占空比为1:3的时钟信号clk_d1、clk_d2,为了达到位同步脉冲的“扣除”和“附加”一个时钟周期的目的。

`timescale 1ns/1ps
//-----------------------------------------------------
//   双相时钟信号生成模块
//-----------------------------------------------------
module clk_gen
(
    input clk,      //32MHz系统时钟
    input rst,      //高电平有效复位信号
    output clk_d1,  //时钟1
    output clk_d2   //时钟2
);

//-----------------------------------------------------
//  产生占空比为1:3,时钟为采样频率(8MHz)的双相时钟
//  两路时钟输出相位相差两个系统时钟周期 
//-----------------------------------------------------
reg [1:0] cnt;     //计数器
reg clkd1, clkd2;

//在计数器的控制下完成指定时钟输出
always @ (posedge clk or posedge rst)
    if (rst) begin
        cnt <= 'd0; clkd1 <= 1'b0; clkd2 <= 1'b0;
    end
    else 
        case (cnt)
            2'd0 : begin  
                clkd1 <= 1'b1;
                clkd2 <= 1'b0;
                cnt <= cnt + 1'b1;
            end
            2'd2 : begin
                clkd1 <= 1'b0;
                clkd2 <= 1'b1;
                cnt <= cnt + 1'b1;
            end
            default : begin
                clkd1 <= 1'b0;
                clkd2 <= 1'b0;
                cnt <= cnt + 1'b1;
            end
        endcase

assign clk_d1 = clkd1;
assign clk_d2 = clkd2;

endmodule

●phaseDetec:鉴相器,检测输入码元的跳变情况以及完成与分频器输出的clk_i和clk_q之间的鉴相。

`timescale 1ns/1ps
//-----------------------------------------------------
//   鉴相器模块
//-----------------------------------------------------
module phaseDetec
(
    input clk,      //32MHz系统时钟
    input rst,      //高电平有效复位信号
    input datain,   //输入单比特基带数据 
    input clk_i,    //同相同步脉冲信号,1:1占空比
    input clk_q,    //正交同步脉冲信号,1:1占空比
    output pd_before,  //输出超前脉冲信号
    output pd_after    //输出滞后脉冲信号
);

reg din_d, din_edge;
reg pdbef, pdaft;

always @ (posedge clk or posedge rst)
    if (rst) begin
        din_d <= 1'b0; din_edge <= 1'b0;
        pdbef <= 1'b0; pdaft <= 1'b0;
    end
    else begin 
        din_d <= datain;   //一级寄存器缓存
        din_edge <= datain ^ din_d;   //异或检测基带边沿
        pdbef <= din_edge & clk_i;    //与门鉴相
        pdaft <= din_edge & clk_q;    //与门鉴相
    end

assign pd_before = pdbef;
assign pd_after = pdaft;

endmodule

●moniflop:单稳态触发器,检测到高电平输入后持续输出4个时钟周期的高电平脉冲(保证只通过clk_d1或clk_2),从而选择扣除还是附加时钟周期。

`timescale 1ns/1ps
//-----------------------------------------------------
//   单稳态触发器模块
//-----------------------------------------------------
module moniflop
(
    input clk,      //32MHz系统时钟
    input rst,      //高电平有效复位信号
    input din,      
    output dout     
);
//-----------------------------------------------------
// 检测到din的高电平脉冲后,dout输出4个时钟长的高电平 
//-----------------------------------------------------
reg [1:0] cnt;      //计数器控制输出高电平的时间
reg start, dout_reg;

always @ (posedge clk or posedge rst)
    if (rst) begin
        cnt <= 0; start <= 0; dout_reg <= 0;
    end
    else begin
        /* 检测到din的高电平脉冲,则开始输出 */
        if (din) begin
            start <= 1'b1; dout_reg <= 1'b1;
        end
        /* 控制一次4个时钟长高电平脉冲的输出 */
        //输出有效
        if (start) begin
            dout_reg <= 1'b1;
            if (cnt < 2'd3)    //有效输出维持4个时钟
                cnt <= cnt + 1'b1;
            else start <= 1'b0;
        end
        //输出无效
        else begin
            cnt <= 'd0;
            dout_reg <= 1'b0;  //无效期间输出低电平
        end
    end

assign dout = dout_reg; 

endmodule 

●control:控制模块,分频产生超前脉冲和滞后脉冲clk_i、clk_q,并完成扣除或附加脉冲的工作。

`timescale 1ns/1ps
//-----------------------------------------------------
//    控制模块
//-----------------------------------------------------
module control
(
    input clk,      //32MHz系统时钟
    input rst,      //高电平有效复位信号
    input clk_d1,
    input clk_d2,
    input pd_before,
    input pd_after,
    output clk_i,
    output clk_q
);

wire gate_open = (~pd_before) & clk_d1;
wire gate_close = pd_after & clk_d2;
wire clk_in = gate_open | gate_close;   //分频器驱动时钟

reg clki, clkq;
reg [2:0] cnt;
always @ (posedge clk or posedge rst)
    if (rst) begin
        cnt <= 'd0; clki <= 0; clkq <= 0;
    end
    else begin
        if (clk_in) cnt <= cnt + 1'b1;
        clki <= ~cnt[2];
        clkq <= cnt[2];
    end

assign clk_i = clki;
assign clk_q = clkq;

endmodule

仿真与工程下载

编写testbench,产生一个矩形脉冲来模拟对ASK调制信号判决后的单比特信号。Vivado中仿真效果如下图所示:
这里写图片描述
可以看到位同步信号Sync是一个周期与码元数据相同、上升沿对应码元初始相位(超前或滞后来回摆动)的信号。即Sync与原始基带数据一一对应。

猜你喜欢

转载自blog.csdn.net/FPGADesigner/article/details/81156055