Xilinx 平台 drp 动态调节 mmcm

分享个人觉得有意思的知识:

  1. 什么样的时钟 会输入到 锁相环里

  2. 锁相环框图 VCO 控制电压控制频率 DS182 可以查看 VCO 范围

    a. 先生成高频 的 VCO

    b. 再通过 倍频和分频 产生具体各路时钟

    c.

  3. 怎么控制 输出频率?XAPP888

    a. high time 是VCO 高电平 持续周期

    b. low time 是 VCO 低电平持续周期

    c. no count 是 VCO时钟周期的计数

    d. edge 将high time 再扩展半个vco 周期 ,可以用来奇数分频 变成 50%占空比

    e. high time 和 low time的 和 是 分频值

  4. 控制相位

    b. 八个可变调节 以 45°为步长

    c. 如果需要 20°就需要使用delay time

    d. vco 频率越高,分频系数越高,相位越精细,如果是 10分频那么VCO输出一周期就是便宜360/10 = 36°

  5. 小数分频

  6. 时序图:

  1. 代码:
    此代码 配置 其中的一个时钟输出,首先读出对于寄存器,然后设置,再读出对比寄存器值,观察是否设置成功,可以使用 LED 观察现象。

代码分享

c 复制代码
`timescale 1ns / 1ps
module drp(
    input               i_clk           ,
    input               i_rst           ,

    output [6 :0]       o_daddr         ,   
    output              o_dclk          ,   
    output              o_den           ,     
    output [15:0]       o_din           ,
    output              o_dwe           ,     
    input  [15:0]       i_dout          ,  
    input               i_drdy          ,
    output              o_mmcm_rst      
          
);

localparam              P_CLKOUT0_REG1_ADDR = 16'h08    ;
localparam [5 :0]       P_HIGN_TIME         = 6'd10     ;
localparam [5 :0]       P_LOW_TIME          = 6'd10     ;

localparam              P_ST_IDLE     = 0   ,
                        P_ST_RST      = 1   ,
                        P_ST_RREG     = 2   ,
                        P_ST_WRDY     = 3   ,
                        P_ST_SET      = 4   ,
                        P_ST_WAIT_RDY = 5   ,
                        P_ST_2RREG    = 6   ,
                        P_ST_2WRDY    = 7   ,
                        P_ST_END      = 8   ;

reg  [7 :0]             r_st_current    ;
reg  [7 :0]             r_st_next       ;
reg  [15:0]             r_st_cnt        ;

reg  [6 :0]             ro_daddr        ;
reg                     ro_dclk         ;
reg                     ro_den          ;
reg  [15:0]             ro_din          ;
reg                     ro_dwe          ;
reg                     ro_mmcm_rst     ;
(* MARK_DEBUG = "TRUE" *)reg  [15:0]             r_clkout0_reg1  ;
(* MARK_DEBUG = "TRUE" *)reg  [15:0]             r_clkout0_2reg1 ;
reg  [1 :0]             r_rdy           ;

assign o_daddr      = ro_daddr          ;
assign o_dclk       = ro_dclk           ;
assign o_den        = ro_den            ;
assign o_din        = ro_din            ;
assign o_dwe        = ro_dwe            ;
assign o_mmcm_rst   = ro_mmcm_rst       ;


always@(posedge i_clk,posedge i_rst)
begin
    if(i_rst)
        r_st_current <= P_ST_IDLE;
    else 
        r_st_current <= r_st_next;
end

always@(*)
begin
    case(r_st_current)
        P_ST_IDLE       : r_st_next = r_st_cnt == 20000 ? P_ST_RST  : P_ST_IDLE ;
        P_ST_RST        : r_st_next = r_st_cnt == 20    ? P_ST_RREG : P_ST_RST  ;
        P_ST_RREG       : r_st_next = P_ST_WRDY;
        P_ST_WRDY       : r_st_next = r_rdy[1]          ? P_ST_SET  : P_ST_WRDY ;
        P_ST_SET        : r_st_next = P_ST_WAIT_RDY;
        P_ST_WAIT_RDY   : r_st_next = r_rdy[1]          ? P_ST_2RREG  : P_ST_WAIT_RDY;
        P_ST_2RREG      : r_st_next = P_ST_2WRDY;
        P_ST_2WRDY      : r_st_next = r_rdy[1]          ? P_ST_END    : P_ST_2WRDY;
        P_ST_END        : r_st_next = P_ST_END;
        default         : r_st_next = P_ST_IDLE;
    endcase
end

always@(posedge i_clk,posedge i_rst)
begin
    if(i_rst)
        r_st_cnt <= 'd0;
    else if(r_st_current != r_st_next)
        r_st_cnt <= 'd0;
    else 
        r_st_cnt <= r_st_cnt + 1;
end

always@(posedge i_clk,posedge i_rst)
begin
    if(i_rst)
        ro_mmcm_rst <= 'd0;
    else if(r_st_current == P_ST_END)
        ro_mmcm_rst <= 'd0;
    else if(r_st_current == P_ST_RST)
        ro_mmcm_rst <= 'd1;
    else 
        ro_mmcm_rst <= ro_mmcm_rst;
end

  
always@(posedge i_clk,posedge i_rst)
begin
    if(i_rst) begin
        ro_daddr <= 'd0;
        ro_den   <= 'd0;
        ro_din   <= 'd0;
        ro_dwe   <= 'd0;
    end else if(r_st_current == P_ST_RREG || r_st_current == P_ST_2RREG) begin 
        ro_daddr <= P_CLKOUT0_REG1_ADDR;
        ro_den   <= 'd1;
        ro_din   <= 'd0;
        ro_dwe   <= 'd0;
    end else if(r_st_current == P_ST_SET) begin 
        ro_daddr <= P_CLKOUT0_REG1_ADDR;
        ro_den   <= 'd1;
        ro_din   <= (r_clkout0_reg1 | 16'b0000_1111_1111_1111) & {4'b1111,P_HIGN_TIME,P_LOW_TIME};
        ro_dwe   <= 'd1;
    end else begin
        ro_daddr <= 'd0;
        ro_den   <= 'd0;
        ro_din   <= 'd0;
        ro_dwe   <= 'd0;
    end
end

always@(posedge i_clk,posedge i_rst)
begin
    if(i_rst)
        r_rdy <= 'd0;
    else 
        r_rdy <= {r_rdy[0],i_drdy};
end

always@(posedge i_clk,posedge i_rst)
begin
    if(i_rst)
        r_clkout0_reg1 <= 'd0;
    else if(r_st_current == P_ST_WRDY && i_drdy)
        r_clkout0_reg1 <= i_dout;
    else 
        r_clkout0_reg1 <= r_clkout0_reg1;
end

always@(posedge i_clk,posedge i_rst)
begin
    if(i_rst)
        r_clkout0_2reg1 <= 'd0;
    else if(r_st_current == P_ST_2WRDY && i_drdy)
        r_clkout0_2reg1 <= i_dout;
    else 
        r_clkout0_2reg1 <= r_clkout0_2reg1;
end
endmodule
相关推荐
周湘zx11 小时前
项目三:信号源的FPGA实现
fpga开发
9527华安13 小时前
FPGA多路MIPI转FPD-Link视频缩放拼接显示,基于IMX327+FPD953架构,提供2套工程源码和技术支持
fpga开发·架构·音视频
上理考研周导师13 小时前
【FPGA】ISE13.4操作手册,新建工程示例
fpga开发
北京太速科技股份有限公司18 小时前
太速科技-889-基于RFSOC XCZU49DR的 16T16R的软件无线电硬件
fpga开发
stm 学习ing19 小时前
HDLBits训练5
c语言·fpga开发·fpga·eda·hdlbits·pld·hdl语言
超能力MAX19 小时前
IIC驱动EEPROM
单片机·嵌入式硬件·fpga开发
吉大一菜鸡1 天前
FPGA学习(基于小梅哥Xilinx FPGA)学习笔记
笔记·学习·fpga开发
9527华安2 天前
FPGA实现MIPI转FPD-Link车载同轴视频传输方案,基于IMX327+FPD953架构,提供工程源码和技术支持
fpga开发·架构·mipi·imx327·fpd-link·fpd953