基于FPGA的CDR时钟恢复设计

这篇具有很好参考价值的文章主要介绍了基于FPGA的CDR时钟恢复设计。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


[参考文献]

[1] https://blog.csdn.net/yijingjijng/article/details/48024059

前言

  CDR全称为Clock and Data Recovery,即时钟数据恢复。顾名思义,CDR就是接收端根据接收到的数据信号恢复出时钟,以便于接收端对数据信号进行恢复和处理。
那为什么需要CDR呢?CDR一般应用于串行数据的恢复,那为什么不像SPI一样多传输一条数据线呢?我们知道SPI的最大传输速度也就几Mbps,这对图像等实时传输是不可能的。而如果速度传输加快,信道对传输信号的影响变大,会导致时钟和数据信号产生不同程度的影响,导致误码。因此后面演变出了SerDes这类高速传输方式,其采用LVDS差分信号进行数据传输,同时省去了时钟线,接收端再根据接收到的差分数据信号进行CDR处理,恢复出时钟和数据。

  本文是基于FPGA全数字电路实现的,重在实现的逻辑,没有物理层的优化,也就意味着无法对太高速的数据进行恢复,仅供参考。

一、CDR原理

  目前基于FPGA的全数字CDR设计基本上都是采取了过采样的方式实现,具体可以使用同频多相时钟采样和数据延迟链采样两种方式实现。核心都是采用Nxf的高速时钟,对信号进行N倍的过采样,通过对采样后数据进行判断分析,得到数据跳变沿的位置,再用最佳的采样点进行恢复数据。但是对于A7系列FPGA来说,PLL最大只能生成600MHz左右的时钟,因此对于高速信号直接使用Nxf的高频时钟采样是很困难的。

  本文采用同频多相时钟采样的方式实现CDR,利用PLL产生0°和90°相位差的采样时钟,两时钟利用双沿采样,如此起到了4倍上采样的效果。最后通过一个判决器对四个采样点进行判决,得到信号跳变沿的位置,再选取最佳的采样点恢复出数据。

  如下图所示,数据信号发生跳变时存在四种情况,跳变沿前后两个采样点采样得到的值不一样,如此便能通过四个采样数值得到跳变沿所在的位置,再选取合适的采样点进行数据的恢复,比如说情况1,信号的上升沿在第一个和第二个采样点之间,可选择相对稳定的第三个采样点作为数据恢复点,以此类推。

cdr fpga 工程,# FPGA设计,fpga开发

二、CDR实现电路

cdr fpga 工程,# FPGA设计,fpga开发

代码实现

 module CDR(
    input clk_0,
    input clk_90,
    input rst_n,
    input ser_in,
    
    output ser_clk,
    output ser_out,
    output [3:0] debug
    );
    reg data00,data01,data02,data03;
    reg data10,data11,data12,data13;
    reg data20,data21,data22,data23;
    reg data30,data31,data32,data33;
    reg data04,data14,data24,data34;
    wire cdr_en ;
    reg [3:0] pos_neg;

    assign debug = {data34,data24,data14,data04};

    assign ser_out = (pos_neg[0])?data23:
                     (pos_neg[1])?data33:
                     (pos_neg[2])?data03:
                     (pos_neg[3])?data13:0 ;
                                  
    assign ser_clk = (pos_neg[0])?~clk_0 :
                     (pos_neg[1])?~clk_90:
                     (pos_neg[2])? clk_0 :
                     (pos_neg[3])? clk_90:0 ;
    //Determine which position is the edge
    always @(posedge clk_0  or negedge rst_n)begin
        if(!rst_n) pos_neg <= 4'd0;
        else if(!cdr_en)begin
            pos_neg[0] <= !data04 &  data14 &  data24 &  data34;        //the edge of data is in the first position
            pos_neg[1] <= !data04 & !data14 &  data24 &  data34;        //
            pos_neg[2] <= !data04 & !data14 & !data24 &  data34;        //
            pos_neg[3] <=  data04 &  data14 &  data24 &  data34;        //
        end
        else
            pos_neg <= pos_neg;
    end
    assign cdr_en = (|pos_neg)?1'b1:1'b0;

    always @(posedge clk_0 or negedge rst_n)begin
        if(!rst_n)begin
        data04 <= 1'b0;
        data14 <= 1'b0;
        data24 <= 1'b0;
        data34 <= 1'b0;
        end
        else begin
        data04 <= data03;
        data14 <= data13;
        data24 <= data23;
        data34 <= data33;
        end
    end
    always @(posedge clk_0 or negedge rst_n)begin
        if(!rst_n) begin
            data00 <= 1'b0;       data01 <= 1'b0;
            data02 <= 1'b0;       data03 <= 1'b0;
        end
        else begin
           data00 <= ser_in;      data01 <= data00; 
           data02 <= data01;      data03 <= data02; 
        end
    end
    always @(posedge clk_90 or negedge rst_n)begin
        if(!rst_n) begin
            data10 <= 1'b0;       data11 <= 1'b0;
            data12 <= 1'b0;       data13 <= 1'b0;
        end
        else begin
           data10 <= ser_in;      data11 <= data10; 
           data12 <= data11;      data13 <= data12; 
        end
    end
    always @(negedge clk_0 or negedge rst_n)begin
        if(!rst_n) begin
            data20 <= 1'b0;       data21 <= 1'b0;
            data22 <= 1'b0;       data23 <= 1'b0;
        end
        else begin
           data20 <= ser_in;      data21 <= data20; 
           data22 <= data21;      data23 <= data22; 
        end
    end
    always @(negedge clk_90 or negedge rst_n)begin
        if(!rst_n) begin
            data30 <= 1'b0;       data31 <= 1'b0;
            data32 <= 1'b0;       data33 <= 1'b0;
        end
        else begin
           data30 <= ser_in;      data31 <= data30; 
           data32 <= data31;      data33 <= data32; 
        end
    end

endmodule

测试文件

module tb_cdr( );
reg clk;
reg rst_n;
reg ser_in;
wire ser_out;
wire clk_90;
wire ser_clk;
initial begin
clk = 0;ser_in = 0; rst_n = 1;
#100 rst_n = 0;
#10 rst_n = 1;
#1000
#11
repeat(100)begin
    #10 ser_in = $random%2;
end
end

always #5 clk = ~clk;
assign #2.5 clk_90 = clk;

CDR CDR(
    .clk_0      (clk    ),
    .clk_90     (clk_90 ),
    .rst_n      (rst_n  ),
    .ser_in     (ser_in ),
    .ser_clk    (ser_clk),
    .ser_out    (ser_out)
    );


endmodule

三、仿真波形

cdr fpga 工程,# FPGA设计,fpga开发

总结

  本文基于FPGA全数字实现了CDR,实现结果有所局限,CDR的频率不能太高且不能自适应更正识别数据信号的相位,主要目的是实现时钟恢复的功能,仅供参考。后续将该CDR模块会应用于低速的serdes实现。文章来源地址https://www.toymoban.com/news/detail-767549.html

到了这里,关于基于FPGA的CDR时钟恢复设计的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 基于FPGA的多功能数字时钟设计报告

    作品基于intel Cyclone IV E EP4CE10F17C8 FPGA板卡,主要开发环境为Quartus Ⅱ,编程并实现了多功能温湿度电子钟。本作品在实现显示实时时间的基础上,设计并完成了设置闹钟、改变闹钟铃声、显示实时温度和实时湿度、基于以太网通信协议的实时视频传输等功能。在未设置闹钟时

    2024年02月05日
    浏览(34)
  • 基于FPGA的数字时钟设计与实现(含源码)

    随着数字电子技术的不断发展,基于FPGA(现场可编程门阵列)的数字时钟设计方案逐渐成为了一种流行的选择。本篇博客将详细介绍如何利用FPGA实现一个简单的数字时钟,涉及到分频器、数码管驱动、时分秒计数、三八译码器和扫描数码管等模块。 1. 系统设计概述 在本设计

    2024年02月05日
    浏览(36)
  • 记一次基于FPGA的VGA显示四操作数计算器工程的开发流程——(1)从顶层设计说起

    首先值得说明的是,在这个项目几乎完成之际,笔者才愈发体会到了硬件思维和软件思维的云泥之别。不幸的是,在此项目的实现过程中,绝大部分代码的思维仍然是软件思维,因此该项目主要模块的设计部分可能并不能体现硬件操作的独到之处,不符合硬件工程师的基本设

    2024年02月04日
    浏览(31)
  • 基于高云FPGA开发板的多功能数字时钟

    目录 一、数字时钟作品的功能 二、数字时钟作品的主体设计原理和功能说明 三、数字时钟的各设计模块说明及模块程序代码 1) 时钟分频模块time_div、freq_div 2)按键消抖模块key_db 3)控制模块control 4)时间正常计数模块time_count 5)时间设置模块time_set 6)时间动态扫描位选模块time_d

    2024年01月22日
    浏览(49)
  • 基于FPGA的LVDS过采样数据恢复设计

    一言蔽之,就是利用PLL产生多个不同相位的同频时钟,对数据进行多倍采样后判决最佳采样位,将接收数据恢复输出。 如图所示,过采样恢复数据基本流程如下: 8倍过采样:生成相位分别为0,45°,90°,135°的四个时钟通过双边沿对数据进行采样,以获得8倍过采样的效果。

    2024年02月15日
    浏览(34)
  • FPGA课程设计——数字电子时钟VERILOG(基于正点原子新起点开发板,支持8位或6位共阳极数码管显示时分秒毫秒,可校时,可设闹钟,闹钟开关,led指示)

    2019   级    电子科学与技术   专业FPGA课程设计 报   告 2022  年 5 月 20 日 多功能数字电子钟的设计 摘要 电子设计自动化(EDA)是一种实现电子系统或电子产品自动化设计的技术,使用EDA技术设计的结果既可以用FPGA / CPLD来实施验证,也可以直接做成专用集成电路(ASIC)。

    2024年02月03日
    浏览(36)
  • CDR插件开发之Addon插件005 - Corel.Interop.VGCore.dll库文件简介

    本文讲解了 Corel.Interop.VGCore.dll 库文件的基本概念,演示了如何在CDR软件的安装目录中查找到VGCore库文件所在的位置,最后演示了如何在C#项目中,添加 Corel.Interop.VGCore.dll 库文件的引用并通过对象浏览器进行查看,简单演示了 VGCore 在C#源文件中的引用方式。  如果你更喜欢观

    2024年02月08日
    浏览(56)
  • 基于FPGA的数字秒表设计(完整工程)

    目录 概述 设计功能 数字秒表设计的目的 模块仿真 设计代码 概述 该设计是用于体育比赛的数字秒表,基于FPGA在Quartus II 9.0sp2软件下应用VHDL语言编写程序,采用ALTRA公司CycloneII系列的EP2C8Q208芯片进行了计算机仿真,并给出了相应的仿真结果。本设计有效的克服了传统的数字秒表

    2024年02月05日
    浏览(25)
  • FPGA多功能数字时钟 基于Quartus实现设计与仿真 华南师范大学数电综设

    专业: 通信工程 学号:__ 姓名: 龚易乾___指导老师: 电子与信息工程学院 2023年2月 有任何疑问可以联系邮箱:codealan@qq.com 项目仓库地址:https://github.com/CodeAlanqian/e-clock github仓库地址 熟练掌握Quartus等EDA设计与仿真工具,掌握多路选择器、N进制计数器、显示译码电路、开关

    2024年02月12日
    浏览(32)
  • cdr文件怎么转化成ai文件 CDR文件转AI文件大小会变化吗

    cdr与AI软件都可以用于制作矢量图形。基于不同的打印与使用需求,可能需要将cdr文件保存为ai文件使用。那么,cdr文件怎么转化成ai文件,CDR文件转AI文件大小会变化吗?下面让我们来详细解读一下吧。 一、cdr文件怎么转化成ai文件 cdr文件是CorelDRAW系列软件编辑的文件格式,

    2024年02月11日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包