JESD204B高速AD开发(二)LMK04821时钟芯片配置代码详解

一、驱动模块顶层

1.1 接口描述

如下图为LMK04821时钟芯片的配置模块输入输出信号,主要分为三部分,

JESD204B高速AD开发(二)LMK04821时钟芯片配置代码详解_第1张图片

图1

1、模块的系统时钟和复位信号,cfg_clk时钟频率<=10MHz,频率的设置是根据LMK04821的SPI总线的spi_sck来确定的,具体可见LMK04821数据手册,内部有详细的介绍。cfg_rst模块高电平复位;

2、第二部分信号主要用于测试,因为我们配置时钟芯片时,如果只是按照规定的配置寄存器顺序完成寄存器配置,仅仅完成写操作,不进行读操作,这样一来我们没办法知道LMK04821内部的寄存器到底有没有配置正确,芯片如果输出的时钟频率不正确的话,也不知道具体原因,所以我们加入了一组vio控制信号,这组信号的功能就是,完成对LMK04821的寄存器的读操作,通过读寄存器来验证我们写入寄存器值得正确性。

一般来说,许多芯片都有一个固定的IC version寄存器,这个寄存器是只读寄存器,我们可以最先通过访问IC version寄存器来确定,芯片的供电有没有问题。比如LMK04821的IC version为0X 006,IC 信息为0X36;如图2所示。 JESD204B高速AD开发(二)LMK04821时钟芯片配置代码详解_第2张图片

图2

 vio_cfg_en:进行寄存器读写操作时,通过vio拉高该信号;

vio_cfg_wr:0写,1读,通过vio控制读写操作;

vio_cfg_addr:寄存器地址,操作哪个寄存器就通过vio进行设置即可;

vio_cfg_wdata:寄存器配置数据,往指定的寄存器内写入的数据值;

addr_118_data:预留信号,暂无作用。

二、代码描述

2.1 LMK04821模式配置

sel0、sel1配置 模式0;

设置需要配置的寄存器个数。

 2.2 LMK04821寄存器配置部分

        在配置寄存器之前我们需要注意到配置寄存器的顺序到底是怎么样的?如果没有经验可以参考手册中的建议的寄存器配置顺序。JESD204B高速AD开发(二)LMK04821时钟芯片配置代码详解_第3张图片

根据以上的官方建议寄存器配置顺序,配置代码如下。举例说明:

data_reg<={r_w,23'h0000_80};r_w指读写标志,高16位表示地址,低8位表示配置数据。cnt_reg表示配置寄存器个数寄存器。

    //data_reg:VCO0,1930~2075;VCO1,2920~3080;
    always @(posedge cfg_clk or posedge cfg_rst)
    begin
        if(cfg_rst==1'b1)
        begin
            data_reg <= 24'h80_0000;
        end
        else
        begin
            case(cnt_reg)//VCO_2Ghz;
                // Serial Port Configuration
                8'd1     : data_reg <= {r_w,23'h0000_80} ;//soft reset
                8'd2     : data_reg <= {r_w,23'h0000_00} ;//

                8'd3     : data_reg <= {r_w,23'h0100_04} ;//500Mhz;DCLKout0: input and output drive level;device clock out divider values
                8'd4     : data_reg <= {r_w,23'h0101_55} ;//controls the digital delay high and low count values for the device clock outputs
                8'd5     : data_reg <= {r_w,23'h0103_00} ;//registers control the analog delay properties for the device clocks
                8'd6     : data_reg <= {r_w,23'h0104_22} ;//set the half step for the device clock, the SYSREF output MUX, the SYSREF clock digital delay,and half step
                8'd7     : data_reg <= {r_w,23'h0105_00} ;//set the analog delay parameters for the SYSREF outputs
                8'd8     : data_reg <= {r_w,23'h0106_70} ;//controls the power down functions for the digital delay, glitchless half step
                8'd9     : data_reg <= {r_w,23'h0107_15} ;//configure the output polarity, and format:11:LVDS;15:LVPECL16;
                8'd10    : data_reg <= {r_w,23'h0108_10} ;//125Mhz;DCLKout2;V7_IO_CLK2;
                8'd11    : data_reg <= {r_w,23'h0109_55} ;
                8'd12    : data_reg <= {r_w,23'h010B_00} ;
                8'd13    : data_reg <= {r_w,23'h010C_22} ;//bit[5]:SDCLKoutY_MUX;0, Device clock output;
                8'd14    : data_reg <= {r_w,23'h010D_00} ;
                8'd15    : data_reg <= {r_w,23'h010E_70} ;//bit[3]:0,enable;bit[4]:powerdown;
                8'd16    : data_reg <= {r_w,23'h010F_11} ;//11:LVDS;15:LVPECL16
                8'd17    : data_reg <= {r_w,23'h0110_10} ;//125Mhz;DCLKout4;
                8'd18    : data_reg <= {r_w,23'h0111_55} ;
                8'd19    : data_reg <= {r_w,23'h0113_00} ;
                8'd20    : data_reg <= {r_w,23'h0114_22} ;//bit[5]:SDCLKoutY_MUX;0, Device clock output;
                8'd21    : data_reg <= {r_w,23'h0115_00} ;
                8'd22    : data_reg <= {r_w,23'h0116_70} ;//bit[3]:0,enable;bit[4]:powerdown;
                8'd23    : data_reg <= {r_w,23'h0117_11} ;//11:LVDS;15:LVPECL16
                8'd24    : data_reg <= {r_w,23'h0118_04} ;//500Mhz;DCLKout6,FPGA;V7_IO_CLK0;
                8'd25    : data_reg <= {r_w,23'h0119_55} ;
                8'd26    : data_reg <= {r_w,23'h011B_00} ;
                8'd27    : data_reg <= {r_w,23'h011C_22} ;//bit[5]:SDCLKoutY_MUX;0, Device clock output;
                8'd28    : data_reg <= {r_w,23'h011D_00} ;
                8'd29    : data_reg <= {r_w,23'h011E_70} ;
                8'd30    : data_reg <= {r_w,23'h011F_11} ;//11:LVDS;15:LVPECL16
                8'd31    : data_reg <= {r_w,23'h0120_10} ;//125Mhz;DCLKout8,FPGA MGT114 CLOCK;
                8'd32    : data_reg <= {r_w,23'h0121_55} ;
                8'd33    : data_reg <= {r_w,23'h0123_00} ;
                8'd34    : data_reg <= {r_w,23'h0124_02} ;//bit[5]:SDCLKoutY_MUX;0, Device clock output;
                8'd35    : data_reg <= {r_w,23'h0125_00} ;
                8'd36    : data_reg <= {r_w,23'h0126_70} ;
                8'd37    : data_reg <= {r_w,23'h0127_11} ;//11:LVDS;15:LVPECL16
                8'd38    : data_reg <= {r_w,23'h0128_10} ;//125Mhz;DCLKout10,FPGA MGT116 CLOCK;
                8'd39    : data_reg <= {r_w,23'h0129_55} ;
                8'd40    : data_reg <= {r_w,23'h012B_00} ;
                8'd41    : data_reg <= {r_w,23'h012C_02} ;//bit[5]:SDCLKoutY_MUX;0, Device clock output;
                8'd42    : data_reg <= {r_w,23'h012D_00} ;
                8'd43    : data_reg <= {r_w,23'h012E_70} ;
                8'd44    : data_reg <= {r_w,23'h012F_11} ;//11:LVDS;15:LVPECL16
                8'd45    : data_reg <= {r_w,23'h0130_04} ;//500Mhz;DCLKout12;
                8'd46    : data_reg <= {r_w,23'h0131_55} ;
                8'd47    : data_reg <= {r_w,23'h0133_00} ;
                8'd48    : data_reg <= {r_w,23'h0134_22} ;
                8'd49    : data_reg <= {r_w,23'h0135_00} ;
                8'd50    : data_reg <= {r_w,23'h0136_70} ;
                8'd51    : data_reg <= {r_w,23'h0137_15} ;//11:LVDS;15:LVPECL16

                8'd52    : data_reg <= {r_w,23'h0138_00} ;//selects the clock distribution source, and OSCout parameters;VCO0;
                8'd53    : data_reg <= {r_w,23'h0139_03} ;//sets the source for the SYSREF outputs
                8'd54    : data_reg <= {r_w,23'h013A_00} ;//SYSREF_DIV[12:8] DIV register 1;sysref 2000M/160=12.5Mhz;
                8'd55    : data_reg <= {r_w,23'h013B_A0} ;//SYSREF_DIV[7:0] DIV register 0;
                8'd56    : data_reg <= {r_w,23'h013C_08} ;//set the delay of the SYSREF digital delay value[12:8]
                8'd57    : data_reg <= {r_w,23'h013D_00} ;//set the delay of the SYSREF digital delay value[7:0]
                8'd58    : data_reg <= {r_w,23'h013E_03} ;//sets the number of SYSREF pulses if SYSREF is not in continuous mode;

                8'd59    : data_reg <= {r_w,23'h013F_04} ;//controls the feedback feature
                8'd60    : data_reg <= {r_w,23'h0140_01} ;//13-OSCin PD; powerdown controls for OSCin and SYSREF functions;bit[0]:Powerdown SYSREF pulse generator;
                8'd61    : data_reg <= {r_w,23'h0141_FF} ;//enables dynamic digital delay for enabled device clocks
                8'd62    : data_reg <= {r_w,23'h0142_00} ;//sets the number of dynamic digital delay adjustments occur
                8'd63    : data_reg <= {r_w,23'h0143_91} ;//sets general SYNC parameters such as polarization, and mode
                8'd64    : data_reg <= {r_w,23'h0144_00} ;//prevent a clock output from being synchronized or interrupted by a SYNC event or when outputting SYSREF
                8'd65    : data_reg <= {r_w,23'h0145_7F} ;//Always program this register to value 127
                8'd66    : data_reg <= {r_w,23'h0171_AA} ;//
                8'd67    : data_reg <= {r_w,23'h0172_02} ;//
                8'd68    : data_reg <= {r_w,23'h0173_00} ;//bit[6]PLL2_PRE_PD; bit[5]PLL2_PD;
                8'd70    : data_reg <= {r_w,23'h017C_15} ;//OPT_REG_1:21;
                8'd71    : data_reg <= {r_w,23'h017D_33} ;//OPT_REG_2:51;
                8'd72    : data_reg <= {r_w,23'h0182_00} ;
                8'd73    : data_reg <= {r_w,23'h0183_00} ;
                8'd74    : data_reg <= {r_w,23'h0184_00} ;
                8'd75    : data_reg <= {r_w,23'h0185_00} ;
                8'd76    : data_reg <= {r_w,23'h0188_00} ;

                8'd77    : data_reg <= {r_w,23'h0146_38} ;//CLKin enable and type controls.
                8'd78    : data_reg <= {r_w,23'h0147_02} ;//CLKin_SEL_MODE. pin select mode;
                8'd79    : data_reg <= {r_w,23'h0148_02} ;//CLKin_SEL0 controls
                8'd80    : data_reg <= {r_w,23'h0149_42} ;//CLKin_SEL1 controls and register readback SDIO pin type
                8'd81    : data_reg <= {r_w,23'h014A_02} ;//contains control of the RESET pin
                8'd82    : data_reg <= {r_w,23'h014B_16} ;//contains the holdover functions:start;
                8'd83    : data_reg <= {r_w,23'h014C_00} ;//
                8'd84    : data_reg <= {r_w,23'h014D_00} ;//
                8'd85    : data_reg <= {r_w,23'h014E_C0} ;//
                8'd86    : data_reg <= {r_w,23'h014F_7F} ;//
                8'd87    : data_reg <= {r_w,23'h0150_03} ;//
                8'd88    : data_reg <= {r_w,23'h0151_02} ;//
                8'd89    : data_reg <= {r_w,23'h0152_00} ;//contains the holdover functions:end;
                8'd90    : data_reg <= {r_w,23'h0153_00} ;//CLKin0_R[13:8]
                8'd91    : data_reg <= {r_w,23'h0154_01} ;//CLKin0_R[7:0]
                8'd92    : data_reg <= {r_w,23'h0155_00} ;//CLKin1_R[13:8]
                8'd93    : data_reg <= {r_w,23'h0156_40} ;//CLKin1_R[7:0]
                8'd94    : data_reg <= {r_w,23'h0157_00} ;//CLKin2_R[13:8]
                8'd95    : data_reg <= {r_w,23'h0158_40} ;//CLKin2_R[7:0]
                8'd96    : data_reg <= {r_w,23'h0159_00} ;//PLL1_N[13:8]
                8'd97    : data_reg <= {r_w,23'h015A_01} ;//PLL1_N[7:0]
                8'd98    : data_reg <= {r_w,23'h015B_D4} ;//PLL1 phase detector
                8'd99    : data_reg <= {r_w,23'h015C_20} ;//PLL1_DLD_CNT[13:8]
                8'd100   : data_reg <= {r_w,23'h015D_00} ;//PLL1_DLD_CNT[7:0]
                8'd101   : data_reg <= {r_w,23'h015E_00} ;//contains the delay value for PLL1 N and R delays.
                8'd102   : data_reg <= {r_w,23'h015F_0B} ;//configures the PLL1 LD pin
                8'd103   : data_reg <= {r_w,23'h0160_00} ;//PLL2_R[11:8]
                8'd104   : data_reg <= {r_w,23'h0161_01} ;//PLL2_R[7:0]
                8'd105   : data_reg <= {r_w,23'h0162_44} ;//sets other PLL2 functions:[7:5]:PLL2_P;[4:2]:OSCin_FREQ;[1]:PLL2_XTAL_EN;[0]:PLL2_REF_2X_EN;
                8'd106   : data_reg <= {r_w,23'h0163_00} ;//PLL2_N_CAL[17:16]
                8'd107   : data_reg <= {r_w,23'h0164_00} ;//PLL2_N_CAL[15:8]
                8'd108   : data_reg <= {r_w,23'h0165_0C} ;//PLL2_N_CAL[7:0]
                8'd109   : data_reg <= {r_w,23'h0166_00} ;//PLL2_N[17:16],MSB;
                8'd110   : data_reg <= {r_w,23'h0167_00} ;//PLL2_N[15:8],---;
                8'd111   : data_reg <= {r_w,23'h0168_0A} ;//PLL2_N[7:0],LSB;
                8'd112   : data_reg <= {r_w,23'h0169_59} ;//controls the PLL2 phase detector
                8'd113   : data_reg <= {r_w,23'h016A_60} ;//
                8'd114   : data_reg <= {r_w,23'h016B_00} ;//
                8'd115   : data_reg <= {r_w,23'h016C_00} ;//
                8'd116   : data_reg <= {r_w,23'h016D_00} ;//
                8'd117   : data_reg <= {r_w,23'h016E_13} ;//
                8'd118   : data_reg <= {r_w,23'h0143_90} ;//
                8'd119   : data_reg <= {r_w,23'h0139_00} ;//
                8'd120   : data_reg <= {r_w,23'h0143_B0} ;//
                8'd121   : data_reg <= {r_w,23'h0143_90} ;//
                8'd122   : data_reg <= {r_w,23'h0144_FF} ;//
                8'd123   : data_reg <= {r_w,23'h0143_10} ;//
                8'd124   : data_reg <= {r_w,23'h0143_11} ;//
                8'd125   : data_reg <= {r_w,23'h0139_03} ;//
                8'd126   : data_reg <= {1'b1,23'h0002_00} ;//
                default  : data_reg <= 24'h80_0000  ;
            endcase
        end
    end

 2.3 SPI接口

以下代码属于SPI三线模式,

    //spi_sdo/spi_cs_n/mid_data_o/mid_csn_o/mid_data_o/vio_cfg_cnt
    always @(posedge cfg_clk or posedge cfg_rst)
    begin
        if(cfg_rst==1'b1)
        begin
            spi_sdo    <=  1'b0;
            spi_cs_n   <=  1'b1;
            mid_data_o <=  36'h0;
            mid_csn_o  <=  36'hFFFFFFFFF;
            sdo_cnt <= 6'b0 ;
        end
        else
        begin
            if(load_p_d0==1'b1)
            begin
                spi_sdo    <=  1'b0;
                mid_data_o <=  {data_reg[23:0],12'hfff};//r_w:0 write;1 read;
                spi_cs_n   <=  1'b1;
                mid_csn_o  <=  {24'h0,12'hFFF};
                sdo_cnt <= 6'h1 ;
            end
            else if(vio_cfg_en_d1==1'b1 && vio_cfg_en_d2==1'b0)
            begin
                spi_sdo    <=  1'b0;
                mid_data_o <=  {vio_cfg_wr,2'b00,vio_cfg_addr,vio_cfg_wdata,12'hfff};//r_w:0 write;1 read;
                spi_cs_n   <=  1'b1;
                mid_csn_o  <=  {24'h0,12'hFFF};
                sdo_cnt <= 6'h1 ;
            end
            else
            begin
                spi_sdo    <=  mid_data_o[35];
                mid_data_o <=  {mid_data_o[34:0],1'b0};
                spi_cs_n   <=  mid_csn_o[35];
                mid_csn_o  <=  {mid_csn_o[34:0],1'b1};
                if(sdo_cnt<6'h3f)
                begin
                    sdo_cnt <= sdo_cnt + 6'h1 ;
                end
                else
                begin
                    sdo_cnt <= sdo_cnt ;
                end
            end
        end
    end
    //regdatareadvalid/regdataread
    always @(posedge cfg_clk or posedge cfg_rst)
    begin
        if(cfg_rst==1'b1)
        begin
            regdatareadvalid <= 1'b0 ;
            regdataread <= 8'b0 ;
        end
        else
        begin
            if(spi_cs_n==1'b0)
            begin
                if(data_reg[23]==1'b1)
                begin
                    if(sdo_cnt>6'd18 && sdo_cnt<6'd25)//2-17;18-25;
                    begin
                        regdatareadvalid <= 1'b0 ;
                        regdataread <= {regdataread[6:0],spi_sdi};
                    end
                    else if(sdo_cnt==6'd25)
                    begin
                        regdatareadvalid <= 1'b1 ;
                        regdataread <= {regdataread[6:0],spi_sdi};
                    end
                    else
                    begin
                        regdatareadvalid <= 1'b0 ;
                        regdataread <= regdataread ;
                    end
                end
                else
                begin
                    regdatareadvalid <= 1'b0 ;
                    regdataread <= regdataread ;
                end
            end
            else
            begin
                regdatareadvalid <= 1'b0 ;
                regdataread <= regdataread ;
            end
        end
    end

 配置完成标志。

    //lmk_cfgdone
    always @(posedge cfg_clk or posedge cfg_rst)
    begin
        if(cfg_rst)
        begin
            lmk_cfgdone <= 1'b0 ;
        end
        else
        begin
            if(cnt_reg>=NUM_REG)
            begin
                lmk_cfgdone <= 1'b1 ;
            end
            else
            begin
                lmk_cfgdone <= 1'b0 ;
            end
        end
    end

三、总结

        本文主要对基于JESD204B开发的AD时钟芯片的配置代码做了一个解析,LMK04821的具体配置代码做了描述,参考者可根据自己的实际运用需求,修改配置的寄存器的数值,得到不同的时钟频率。寄存器具体的数据值,可参考下面的链接,里面讲述了辅助开发软件的使用,通过软件配置出自己所需的时钟频率,导出寄存器的具体参数,然后再修改对应寄存器配置数据即可。JESD204B高速AD开发(一)基于FPGA的LMK04821时钟芯片设计_芒果*爸爸的博客-CSDN博客_lmk04828中文手册icon-default.png?t=M4ADhttps://blog.csdn.net/FDL_AQ/article/details/122445918?spm=1001.2014.3001.5502下一章,咱们开始jesd204b IP核的基础知识讲解。

你可能感兴趣的:(fpga开发)