204B實戰(zhàn)應(yīng)用-LMK04821代碼詳解(二)
一、SPI協(xié)議
通過閱讀LMK04821數(shù)據(jù)手冊,我們可以從中知道,可以通過SPI協(xié)議對LMK04821進行寄存器的配置工作,進而實現(xiàn)我們設(shè)計所需要的功能。
SPI協(xié)議部分,咱們可以用3線,或者4線,在本次設(shè)計中,使用3線。關(guān)于SPI的時序部分,這兒就不再贅述,手冊里面都有詳細的描述。
圖1
二、SPI寄存器配置模塊設(shè)計
圖2
如圖2所示,就是配置LMK04821存器的單元,信號定義如下:
1、cfg_clk:系統(tǒng)時鐘;
2、cfg_rst:系統(tǒng)復位;
3、通過VIO控制的信號,這組信號存在的目的在于方便檢測自己配置寄存器的正確性。
vio_cfg_en:配置寄存器使能信號;
vio_cfg_wr:配置寄存器讀寫使能,0寫1讀;
vio_cfg_addr:配置的寄存器地址;
vio_cfg_wdata:寄存器中配置的值;
addr_118_data:預留信號,模塊中沒有用;
我們在配置LMK04821寄存器時,要驗證配置寄存器操作是否正確,就要有寫有讀,在對應(yīng)的寄存器內(nèi)寫入對應(yīng)的數(shù)值,然后進行讀操作,觀察正確性。本次設(shè)計是在vivado環(huán)境下進行設(shè)計,通過添加VIO的IP核,來控制讀寫操作。同時,添加ILA配合VIO來進行讀寫數(shù)據(jù)操作的觀測。別的開發(fā)環(huán)境下思路一樣。
該組信號僅在回讀寄存器時使用,目的是為了驗證寄存器讀寫正確性。
圖3
4、lmk_rst:LMK04821復位信號,用于復位LMK04821,直接和LMK04821芯片相連;
5、3線制SPI信號:
lmk_spi_csn:片選;
lmk_spi_sdio:數(shù)據(jù);
lmk_spi_clk:時鐘;
6、可編程管教:主要和LMK04821內(nèi)部的PLL相關(guān),本次設(shè)計中默認為0;
lmk_clk_sel0 :sel0;
lmk_clk_sel1 :sel1;
三、SPI數(shù)據(jù)buffer定義
在本次設(shè)計中,SPI配置數(shù)據(jù)buffer,data_reg為24bit,r_w占1bit,箭頭1所指包含W1、W2以及地址位占13bit,具體見SPI時序圖;箭頭2所指數(shù)據(jù)位8bit。
圖4
根據(jù)圖5我們可以知道,要配置LMK04821我們需要配置126個寄存器,這126個寄存器來源參見第一章實戰(zhàn)記錄。
其中,126個寄存器包含必須要配的寄存器、一些無關(guān)緊要的寄存器、以及功能實現(xiàn)所需要的寄存器等,有些寄存器需要配置多次。
圖5
四、SPI時序?qū)崿F(xiàn)
設(shè)計中,我們需要按照順序配置126個寄存器,也就是說SPI要執(zhí)行126次。因此,在代碼實現(xiàn)過程中,注意寄存器配置的順序,并且保證每個寄存器都準確無誤的配置完成,才能進行下一個寄存器的配置。如果在設(shè)計中,要求LMK004821實現(xiàn)不同的功能,當配置的寄存器個數(shù)不一致時,在v文件中更改圖6所示的參數(shù)即可。
圖6
如下:是LMK04821配置的模塊,讀者可以作為參考。
代碼區(qū)(參考代碼):
//###########################################################################// // Copyright (C) 2017, JSZX, Co. Ltd. All Rights Reserved. //###########################################################################// //-- Project Name : //-- File Name : lmk04821_spi //-- Description : //###########################################################################// //---------------------------Modification History----------------------------// //-- Date By Ver Comment //-- 12/04/2017 hhh 1.0 Create new //=================================================================== //-- End Revision //=================================================================== `timescale 1ns / 1ps module lmk04821_spi( input cfg_clk , //<=10MHz input cfg_rst , input vio_cfg_en , input vio_cfg_wr ,//0,write;1,read; input [12:0] vio_cfg_addr , input [07:0] vio_cfg_wdata , input [07:0] addr_118_data , input r_w , input lmk_cfgen , output lmk_rst , output lmk_spi_csn , inout tri lmk_spi_sdio , output lmk_spi_clk , output lmk_clk_sel0 , output lmk_clk_sel1 , output reg regdatareadvalid , output reg [7:0] regdataread , output reg lmk_cfgdone = 1'b0 ); //parameter defination parameter NUM_REG = 8'd126 ;//需要配置的寄存器個數(shù) parameter CFG_DONE_DLY = 32'hF4240 ;//100ms@10Mhz; //====================================================================// //----------------------internal signals------------------------------// //====================================================================// reg [00:0] lmk_cfgen_d0 ; reg [00:0] lmk_cfgen_d1 ; reg [00:0] lmk_cfgen_d2 ; reg [00:0] vio_cfg_en_d0 ; reg [00:0] vio_cfg_en_d1 ; reg [00:0] vio_cfg_en_d2 ; reg [07:0] cnt_clk ;// 每個寄存器需要的時鐘數(shù)計數(shù)器 reg [07:0] cnt_reg ;// 需要配置的寄存器計數(shù)器,最多255個! reg [23:0] data_reg ; reg [00:0] load_p ; reg [00:0] load_p_d0 ; reg [35:0] mid_data_o ; reg [35:0] mid_csn_o ; reg [00:0] spi_sdo ; reg [00:0] spi_cs_n ; wire[00:0] spi_sdi ; reg [05:0] sdo_cnt ; // //====================================================================// // //-----------------------------ila debug------------------------------// // //====================================================================// // //ila_spi // ila_spi ila_spi( // .clk ( cfg_clk ), // // .probe0 ( cnt_clk ),//8 // .probe1 ( cnt_reg ),//8 // .probe2 ( data_reg ),//24 // .probe3 ( load_p ),//1 // .probe4 ( sdo_cnt ),//6 // .probe5 ( spi_cs_n ),//1 // .probe6 ( spi_sdi ),//1 // .probe7 ( spi_sdo ),//1 // .probe8 ( lmk_cfgen_d1 ) //1 // ); //====================================================================// //--------------------------main process------------------------------// //====================================================================// //lmk_clk_sel assign lmk_clk_sel0= 1'b0 ; assign lmk_clk_sel1= 1'b0 ; //spi signals; assign lmk_rst = cfg_rst ; assign lmk_spi_clk = (spi_cs_n) ? 1'b0 : ~cfg_clk ; assign lmk_spi_csn = spi_cs_n ; assign spi_sdi = lmk_spi_sdio; assign lmk_spi_sdio= (data_reg[23]==1'b1 && sdo_cnt>6'h18)? 1'bz : spi_sdo ; //lmk_cfgen_d0/lmk_cfgen_d1/lmk_cfgen_d2/load_p_d0 always @(posedge cfg_clk or posedge cfg_rst) begin if(cfg_rst==1'b1) begin lmk_cfgen_d0 <= 1'b0 ; lmk_cfgen_d1 <= 1'b0 ; lmk_cfgen_d2 <= 1'b0 ; load_p_d0 <= 1'b0 ; vio_cfg_en_d0 <= 1'b0 ; vio_cfg_en_d1 <= 1'b0 ; vio_cfg_en_d2 <= 1'b0 ; end else begin lmk_cfgen_d0 <= lmk_cfgen ; lmk_cfgen_d1 <= lmk_cfgen_d0 ; lmk_cfgen_d2 <= lmk_cfgen_d1 ; load_p_d0 <= load_p ; vio_cfg_en_d0 <= vio_cfg_en ; vio_cfg_en_d1 <= vio_cfg_en_d0 ; vio_cfg_en_d2 <= vio_cfg_en_d1 ; end end //load_p/cnt_reg/cnt_clk always @(posedge cfg_clk or posedge cfg_rst) begin if(cfg_rst==1'b1) begin cnt_reg <= 8'd0 ; cnt_clk <= 8'd36 ; load_p <= 1'b0 ; end else begin if(lmk_cfgen_d1==1'b1 && lmk_cfgen_d2==1'b0) begin cnt_clk <= 8'd0 ; cnt_reg <= 8'd0 ; load_p <= 1'b0 ; end else if((cnt_clk==8'd36)&&(cnt_reg6'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 //====================================================================// //------------------------------- end ------------------------------// //====================================================================// endmodule
審核編輯:湯梓紅
-
FPGA
+關(guān)注
關(guān)注
1629文章
21729瀏覽量
602977 -
芯片
+關(guān)注
關(guān)注
455文章
50714瀏覽量
423132 -
SPI
+關(guān)注
關(guān)注
17文章
1706瀏覽量
91501 -
JESD204B
+關(guān)注
關(guān)注
5文章
76瀏覽量
19125
原文標題:往期精選:204B實戰(zhàn)應(yīng)用-LMK04821代碼詳解
文章出處:【微信號:HXSLH1010101010,微信公眾號:FPGA技術(shù)江湖】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
評論