社区导航

 
查看: 830|回复: 4

[原创] 基于actel fpga的周期反馈式纯数字锁相环

[复制链接]

46

TA的帖子

0

TA的资源

一粒金砂(中级)

Rank: 2

发表于 2018-10-8 22:09:57 | 显示全部楼层 |阅读模式
本帖最后由 teleagle 于 2018-10-8 22:19 编辑


基于actel fpga的周期反馈式纯数字锁相环:
    简单的说就是建立一个状态机,对输入周期参数在产生时钟的每个周期的第一时间更新值,然后进入下一个状态计数,计数到和输入周期一致的时候又回到初始状态。代码综合仿真正确, 过程比较简单, 就不班门弄斧了. 不妥之处, 共同学习交流 ,一起改进,  代码如下:

//顶层模块:
module TE_DPLL_B(
        sys_clk,
        sys_rst,
        clk_in,
        clk_out
);


        //---全局参数---
        parameter DATA_W = 16;                        // 周期计数器及数据位宽,根据系统时钟与输入时钟的差值调整
        parameter PN_EDGE = 2'b01;                // 沿检测参数(01=上升沿,10=下降沿)
        parameter DPLL_M = 2;                        // M 参数
        parameter DPLL_N = 10;                        // N 参数


        //---输入输出接口---
        input sys_clk;                        // 系统时钟
        input sys_rst;                        // 系统重置
        input clk_in;                        // 输入时钟
        output clk_out;                        // 输出时钟


        //---内部信号---
        wire [DATA_W-1:0] n_ti;        // 输入时钟周期值


        //---------------------------------------------------------
        // 输入时钟周期测量模块,对输入时钟采样,测量输出时钟周期Ti
        //---------------------------------------------------------
        TE_DPLL_Figure TE_DPLL_Figure_0(
                .sys_clk(sys_clk),        // 系统时钟
                .sys_rst(sys_rst),        // 系统重置
                .clk_i(clk_in),                // 输入时钟
                .t_o(n_ti)                // 输入时钟周期值
        );
        defparam TE_DPLL_Figure_0.CNT_W = DATA_W;        // 周期计数器位宽
        defparam TE_DPLL_Figure_0.PN_EDGE = PN_EDGE;        // 沿检测参数(01=上升沿,10=下降沿)


        //---------------------------------------------------------
        // 例化反馈模块
        //---------------------------------------------------------
        TE_DPLL_Feed TE_DPLL_Feed_0(
                .sys_clk(sys_clk),        // 系统时钟
                .sys_rst(sys_rst),        // 系统重置
                .ti_i(n_ti),                // 输入时期周期值
                .clk_o(clk_out)                // 输出时钟
        );
        defparam TE_DPLL_Feed_0.DATA_W = DATA_W;        // 数据位宽
        defparam TE_DPLL_Feed_0.PN_EDGE = PN_EDGE;        // 沿检测参数(01=上升沿,10=下降沿)
        defparam TE_DPLL_Feed_0.DPLL_M = DPLL_M;        // M 参数
        defparam TE_DPLL_Feed_0.DPLL_N = DPLL_N;        // N 参数




endmodule
此帖出自FPGA/CPLD论坛


回复

使用道具 举报

46

TA的帖子

0

TA的资源

一粒金砂(中级)

Rank: 2

 楼主| 发表于 2018-10-8 22:12:07 | 显示全部楼层
//周期采样模块
module TE_DPLL_Figure(
        sys_clk,
        sys_rst,
        clk_i,
        t_o
);

        //---全局参数---
        parameter CNT_W = 16;                                // 周期计数器位宽
        parameter PN_EDGE = 2'b01;        // 沿检测参数(01=上升沿,10=下降沿)

        //---输入输出接口---
        input sys_clk;                // 系统时钟
        input sys_rst;                // 系统重置
        input clk_i;                        // 输入待测时钟
        output t_o;                        // 输出时钟周期

        reg [CNT_W-1:0] t_o;

        //---内部寄存器---
        reg [1:0] n_edge;                                // 待测时钟缓冲,用于检测时钟沿
        reg [CNT_W-1:0] n_cnt;        // 周期计数器
        reg n_state;                                                // 状态

        //---------------------------------------------------------
        // 2D 左移位寄存器,用于检测上升沿或下降沿
        //---------------------------------------------------------
        always @(posedge sys_clk)
        begin
                if(sys_rst)
                        n_edge <= 0;
                else
                  n_edge <= {n_edge[0],clk_i};
        end
        //---------------------------------------------------------
        // 一段状态机
        //---------------------------------------------------------
        always @(posedge sys_clk)
        begin
                if(sys_rst)
                        begin
                                n_state <= 0;
                                n_cnt <= 0;
                                t_o <= 0;
                        end
                else
                        case(n_state)
                                0 : begin
                                                n_state <= (n_edge == PN_EDGE) ? 1 : 0;                // 检测正向沿(由PN_EDGE决定)
                                                n_cnt <= (n_edge == PN_EDGE) ? 1 : 0;
                                        end
                                1 : begin
                                                n_state <= (n_edge == PN_EDGE) ? 0 : 1;                // 非正向沿时(由PN_EDGE决定),跳回状态0
                                                n_cnt <= n_cnt + 1;
                                                t_o <= (n_edge == PN_EDGE) ? n_cnt : t_o;
                                        end
                                default : n_state <= 0;
                        endcase
        end

endmodule


回复

使用道具 举报

46

TA的帖子

0

TA的资源

一粒金砂(中级)

Rank: 2

 楼主| 发表于 2018-10-8 22:14:28 | 显示全部楼层
// 反馈模块

module TE_DPLL_Feed(
        sys_clk,
        sys_rst,
        ti_i,
        clk_o
);

        //---全局参数---
        parameter DATA_W = 16;                        // 数据位宽
        parameter PN_EDGE = 2'b01;        // 沿检测参数(01=上升沿,10=下降沿)
        parameter DPLL_M = 10;                                                // M 参数
        parameter DPLL_N = 10;                                                // N 参数

        //---输入输出接口---
        input sys_clk;                                                // 系统时钟
        input sys_rst;                                                // 系统重置
        input [DATA_W-1:0] ti_i;        // 输入时钟周期值
        output clk_o;                                                        // 输出时钟

        //---内部信号---
        wire [DATA_W-1:0] n_to;                // 输出时钟周期值

        //---内部寄存器---
        reg [DATA_W-1:0] n_terr;        // 开环误差,除 M 后的误差值
        reg [DATA_W-1:0] n_err;                // 反馈误差,输入输出时钟周期误差

        //---------------------------------------------------------
        // 反馈误差(To/N)
        // 反馈的时钟周期乘以反馈增益1/N
        //---------------------------------------------------------
        always @(posedge sys_clk)
        begin
                if(sys_rst)
                        n_err <= 0;
                else
            n_err <= ti_i - (n_to / DPLL_N);                // 输入时钟周期 - (输出时钟周期 / N)
        end

        //---------------------------------------------------------
        // 开环误差 (n_err/M)
        // 反馈误差乘以开环增益1/M
        //---------------------------------------------------------
        always @(posedge sys_clk)
        begin
                if(sys_rst)
                        n_terr <= 0;
                else
            n_terr <= n_err / DPLL_M;
        end

        //---------------------------------------------------------
        // 将 n_err/M 值反馈给控制对象
        //---------------------------------------------------------
        TE_DPLL_Gen TE_DPLL_Gen_0(
                .sys_clk(sys_clk),        // 系统时钟
                .sys_rst(sys_rst),        // 系统重置
                .terr_i(n_terr),                // 误差 n_err 除 M 后的值
                .clk_o(clk_o)                                // 输出时钟
        );
        defparam TE_DPLL_Gen_0.DATA_W = DATA_W;                // 数据位宽
        //---------------------------------------------------------
        // 输出时钟周期测量模块,对输出时钟采样,测量输出时钟周期 To
        //---------------------------------------------------------
        TE_DPLL_Figure TE_DPLL_Figure_1(
                .sys_clk(sys_clk),        // 系统时钟
                .sys_rst(sys_rst),        // 系统重置
                .clk_i(clk_o),                        // 输出时钟反馈回周期测量模块
                .t_o(n_to)                                        // 输出时钟周期
        );
        defparam TE_DPLL_Figure_1.CNT_W = DATA_W;                        // 周期计数器位宽
        defparam TE_DPLL_Figure_1.PN_EDGE = PN_EDGE;        // 沿检测参数(01=上升沿,10=下降沿)

endmodule


回复

使用道具 举报

46

TA的帖子

0

TA的资源

一粒金砂(中级)

Rank: 2

 楼主| 发表于 2018-10-8 22:38:29 | 显示全部楼层
上述代码参数时的时序仿真:

时序仿真.JPG


回复

使用道具 举报

831

TA的帖子

0

TA的资源

纯净的硅(高级)

Rank: 6Rank: 6

发表于 2018-10-12 22:12:46 | 显示全部楼层
这个品牌用的人不多。


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

  • 论坛活动 E手掌握

    扫码关注
    EEWORLD 官方微信

  • EE福利  唾手可得

    扫码关注
    EE福利 唾手可得

小黑屋|手机版|Archiver|电子工程世界 ( 京ICP证 060456 )

GMT+8, 2018-10-20 11:14 , Processed in 0.147776 second(s), 16 queries , Gzip On, MemCache On.

快速回复 返回顶部 返回列表