FPGA数字信号处理(十三)锁相环位同步技术的实现_fpga位同步-程序员宅基地

技术标签: PLL  FPGA  ASK  Sync  数字信号处理  

前面介绍了数字通信系统中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与原始基带数据一一对应。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/FPGADesigner/article/details/81156055

智能推荐

c# 调用c++ lib静态库_c#调用lib-程序员宅基地

文章浏览阅读2w次,点赞7次,收藏51次。四个步骤1.创建C++ Win32项目动态库dll 2.在Win32项目动态库中添加 外部依赖项 lib头文件和lib库3.导出C接口4.c#调用c++动态库开始你的表演...①创建一个空白的解决方案,在解决方案中添加 Visual C++ , Win32 项目空白解决方案的创建:添加Visual C++ , Win32 项目这......_c#调用lib

deepin/ubuntu安装苹方字体-程序员宅基地

文章浏览阅读4.6k次。苹方字体是苹果系统上的黑体,挺好看的。注重颜值的网站都会使用,例如知乎:font-family: -apple-system, BlinkMacSystemFont, Helvetica Neue, PingFang SC, Microsoft YaHei, Source Han Sans SC, Noto Sans CJK SC, W..._ubuntu pingfang

html表单常见操作汇总_html表单的处理程序有那些-程序员宅基地

文章浏览阅读159次。表单表单概述表单标签表单域按钮控件demo表单标签表单标签基本语法结构<form action="处理数据程序的url地址“ method=”get|post“ name="表单名称”></form><!--action,当提交表单时,向何处发送表单中的数据,地址可以是相对地址也可以是绝对地址--><!--method将表单中的数据传送给服务器处理,get方式直接显示在url地址中,数据可以被缓存,且长度有限制;而post方式数据隐藏传输,_html表单的处理程序有那些

PHP设置谷歌验证器(Google Authenticator)实现操作二步验证_php otp 验证器-程序员宅基地

文章浏览阅读1.2k次。使用说明:开启Google的登陆二步验证(即Google Authenticator服务)后用户登陆时需要输入额外由手机客户端生成的一次性密码。实现Google Authenticator功能需要服务器端和客户端的支持。服务器端负责密钥的生成、验证一次性密码是否正确。客户端记录密钥后生成一次性密码。下载谷歌验证类库文件放到项目合适位置(我这边放在项目Vender下面)https://github.com/PHPGangsta/GoogleAuthenticatorPHP代码示例://引入谷_php otp 验证器

【Python】matplotlib.plot画图横坐标混乱及间隔处理_matplotlib更改横轴间距-程序员宅基地

文章浏览阅读4.3k次,点赞5次,收藏11次。matplotlib.plot画图横坐标混乱及间隔处理_matplotlib更改横轴间距

docker — 容器存储_docker 保存容器-程序员宅基地

文章浏览阅读2.2k次。①Storage driver 处理各镜像层及容器层的处理细节,实现了多层数据的堆叠,为用户 提供了多层数据合并后的统一视图②所有 Storage driver 都使用可堆叠图像层和写时复制(CoW)策略③docker info 命令可查看当系统上的 storage driver主要用于测试目的,不建议用于生成环境。_docker 保存容器

随便推点

网络拓扑结构_网络拓扑csdn-程序员宅基地

文章浏览阅读834次,点赞27次,收藏13次。网络拓扑结构是指计算机网络中各组件(如计算机、服务器、打印机、路由器、交换机等设备)及其连接线路在物理布局或逻辑构型上的排列形式。这种布局不仅描述了设备间的实际物理连接方式,也决定了数据在网络中流动的路径和方式。不同的网络拓扑结构影响着网络的性能、可靠性、可扩展性及管理维护的难易程度。_网络拓扑csdn

JS重写Date函数,兼容IOS系统_date.prototype 将所有 ios-程序员宅基地

文章浏览阅读1.8k次,点赞5次,收藏8次。IOS系统Date的坑要创建一个指定时间的new Date对象时,通常的做法是:new Date("2020-09-21 11:11:00")这行代码在 PC 端和安卓端都是正常的,而在 iOS 端则会提示 Invalid Date 无效日期。在IOS年月日中间的横岗许换成斜杠,也就是new Date("2020/09/21 11:11:00")通常为了兼容IOS的这个坑,需要做一些额外的特殊处理,笔者在开发的时候经常会忘了兼容IOS系统。所以就想试着重写Date函数,一劳永逸,避免每次ne_date.prototype 将所有 ios

如何将EXCEL表导入plsql数据库中-程序员宅基地

文章浏览阅读5.3k次。方法一:用PLSQL Developer工具。 1 在PLSQL Developer的sql window里输入select * from test for update; 2 按F8执行 3 打开锁, 再按一下加号. 鼠标点到第一列的列头,使全列成选中状态,然后粘贴,最后commit提交即可。(前提..._excel导入pl/sql

Git常用命令速查手册-程序员宅基地

文章浏览阅读83次。Git常用命令速查手册1、初始化仓库git init2、将文件添加到仓库git add 文件名 # 将工作区的某个文件添加到暂存区 git add -u # 添加所有被tracked文件中被修改或删除的文件信息到暂存区,不处理untracked的文件git add -A # 添加所有被tracked文件中被修改或删除的文件信息到暂存区,包括untracked的文件...

分享119个ASP.NET源码总有一个是你想要的_千博二手车源码v2023 build 1120-程序员宅基地

文章浏览阅读202次。分享119个ASP.NET源码总有一个是你想要的_千博二手车源码v2023 build 1120

【C++缺省函数】 空类默认产生的6个类成员函数_空类默认产生哪些类成员函数-程序员宅基地

文章浏览阅读1.8k次。版权声明:转载请注明出处 http://blog.csdn.net/irean_lau。目录(?)[+]1、缺省构造函数。2、缺省拷贝构造函数。3、 缺省析构函数。4、缺省赋值运算符。5、缺省取址运算符。6、 缺省取址运算符 const。[cpp] view plain copy_空类默认产生哪些类成员函数

推荐文章

热门文章

相关标签