zedboard--用戶自定義IP核(pwm發生器)設計(二十)

1:實驗說明:

對於Zedboard的用戶自定義的IP核有兩種可行的方案:

一:通過EMIO交換數據(GPIO,SPI),這個其實就是將PL的IP核看作系統的外設,在數據交互性能和效率上都有很大的缺陷。(不常用)

二:利用嚮導來製作滿足AXI協議的IP核,嚮導自動生成總線相關的代碼,做好地址譯碼邏輯,讀寫控制邏輯,並在用戶工作區生成一些寄存器。我們寫的PL邏輯通過讀寫這些寄存器和PS交互。這也是常用的方法。

Zedboard也有一些自己做好了的IP core,實驗八就是用的自帶的IP core。

本實驗就是採用第二種方法,製作一個簡單的PWM發生器。在PL端開發了這個IP核以後,先在裸跑的程序裏面調用這個IP core,測試我們的邏輯有沒有實現,這個和之前做的實驗沒有什麼區別(zedboard--zynq使用自帶外設IP讓ARM PS訪問FPGA(八),只不過這裏是我們自己寫的IP core)

PWM發生器內部只有兩個寄存器,一個是調節週期的週期寄存器,另一個是調節佔空比的佔空比寄存器,其中週期寄存器的最高位是狀態位,控制PWM波最後是否產生。


2:具體步驟

啓動PlanAhead,創建工程,Next,圖1

 

輸入工程名project_10,Next,圖2

 

Next,RTL工程  圖3

 

一路Next,不添加任何文件 圖4

 

選擇board  圖5

 

完成工程  圖6

 

PlanAhead進入工作視圖,在Project Manager中單擊那個有+的圖標(addsources),出現下圖,選擇Embedded Sources  圖7,圖8

 


Next 選着Create Sub-Design。  圖9

 

輸入名稱,這裏爲system 圖10

 

點擊finish  圖11

 

進入了XPS,提示所建立的一個zynq工程,提示是否建立bsb Wizard,選擇yes  圖12

 

 

出現下圖   圖13

 

點擊ok  出現   圖14

 

選擇next 這裏不要大意,一定要把右側的兩個東西來remove掉,我當時就是卡在這裏。,remove後出現這樣的圖   圖15

 

Finish,點擊finish就可以了,然後進入zynq的配置界面,Diligent公司做好了一個配置方案,可以到網上下載到配置文件。

 如圖16 17 18

 



Hardware- Createor Import  Periphera  來到歡迎界面   圖19

 

Next,創建新的模板(默認選擇)  圖20

 

Next  默認   圖21

 

Next命名工程  圖22

 

採用AXI4-Lite 圖23

 

Next,這裏只要 User logic master support   圖24

 

Next,我們要兩個寄存器,分別是佔空比寄存器和週期寄存器,圖25

 

Next,不做任何修改  圖26

 

Next,不需要仿真平臺  圖27

 

Next,  全選圖28

第一個選項表示生成的User Logic使用VerilogHDL

第二個選項表示同時生成一個ISE的工程,便於調試和測試Ipcore

第三個選項表示生成軟件驅動庫文件,方便在SDK裏使用Ipcore

 

Next,點擊finish就可以了 圖29

  

我們自己配置的IP核就建立好了,接下來添加剛完成的IP核,在IP Catalog裏面的USER選項中找到它  圖30

 

雙擊PWM_IP,出現  圖31

 

選擇YES,  圖32

 

點擊兩次ok,出現 圖33

 

注意一下不要粘貼外面的(如word文檔裏面的),容易出錯,輸入法選擇在英文輸入法下。

右擊pwm_ip_0,View MPD,添加PORT pwm_out=””,DIR=O,如圖34(添加在60行),保存並關閉

 

右擊pwm_ip_0,Brouse HDLsources,打開pwm_ip.vhd.添加代碼

1添加(138行) 將pwm_out接口設置爲模塊的輸出接口

pwm_out                        :out std_logic;    圖35


2添加(253行)將pwm_out接口到user_logic設備

pwm_out                                          :out std_logic;      圖36


3添加(342)將設備的pwm_out接口和IP核的pwm_out接口連接

       pwm_out                        =>pwm_out,    圖37

 

 

保存,退出,右擊pwm_ip_0,Brouse HDLsources,打開user_logic.v.添加代碼

1添加(58行),聲明pwm_out接口,添加pwm_out,   圖38


2添加(88行)定義pwm_out爲輸出,而且位寬爲1,添加

output              pwm_out;  圖39


3接下來就是用戶實現段了,令slv_reg0爲週期寄存器,slv_reg1爲佔空比寄存器。此外我們還需要一個計數器(pwm_counter),下一個週期的開始信號(Over Period)和預輸出信號(pre_pwm_out)。

在110添加邏輯

wire  ovprd;

reg   [C_SLV_DWIDTH-1 :0] pwm_counter;

wire                                           pre_pwm_out;

圖40


pwm產生器的邏輯

在124行添加邏輯  圖41

  // USER logic implementation added here

always @(posedgeBus2IP_Clk)

begin

       if(!Bus2IP_Resetn || ovprd ||~slv_reg1[31])

              pwm_counter=32'h8000_0000;

       else if(slv_reg1[31])

                            pwm_counter=pwm_counter+1'b1;

                     else pwm_counter=pwm_counter;

end

 

assignovprd=(pwm_counter[30:0]==slv_reg0[30:0])?1'b1:1'b0;

assignpre_pwm_out=(slv_reg1<pwm_counter)?1'b0:1'b1;

assignpwm_out=pre_pwm_out & slv_reg1[31];

 

保存,退出,在project菜單中選擇RescanUser Repositories,從port中可以看到我們新添加的引腳pwm_out.選擇External Ports把引腳引出去,如圖42

 

打開Address標籤頁,單擊右上角的GeneratedAddresses按鈕,如圖43

 

單擊project –>Design Rule Check,沒有報錯,關閉xps,回到PlanAhead圖44


在system.xmp文件上右擊,選擇CreateTop HDL   圖45,46

 


單擊Add source按鈕,選擇Add orCreate Constrains 單擊Next 圖47

 

單擊 Create File…選項  圖48

 

改文件名 圖49,finish就可以了

 

單擊左邊的Run Synthesis ,這裏就出錯了,如圖50,

 

在tcl console 按下ctrl +f 輸入error,如圖51一看是user_logic.v出錯了,<slv_reg> is not d eclared這個時候啓動xps,改正錯誤,可以看到圖41,確實是錯的,應該在128和134行爲slv_reg1,而我漏掉了1,改正,保存,退出xps,重新Run Synthesis,這裏也是尋找解決錯誤的方法。


過程結束後會彈出對話框,圖52

 

選擇Open Synthesized Design,會有一些警告,忽略,打開I/O Port標籤,由於以前一直用Altera,這個標籤找了一會兒(window->I/O Port),設置pwm_out的引腳,保存。圖53

選擇Select an existing file

 

看不到system.ucf,重啓PlanAhead,這時候就可以看到system.ucf文件的內容如下 圖54

 

單擊左邊的Generate Bitstream.單擊yes,完成implementation,至此硬件工程就做完了。(這個過程又點長)

在PlanAhead中,單擊File->Export->ExportHardware  圖55

 

建立c工程 圖56

 

選擇Xilinx Tools->Repositories,單擊new,找到工程路徑,圖57


在hello_bsp_0上右擊,選擇BoardSupport Package Setting ,找到drivers中得pwm_ip_0,修改Driver,圖58,如果你沒有出現估計就悲劇了。

 

然後我們將自設的IP核的Driver添加進來後就可以添加c代碼了。圖59

 

修改bug在hello_bsp_0上面有一個紅色的叉,是有一個宏沒有設置,需要手動設置這個宏,找到pwm_ip_selftest,c這個文件,C:\zedboard\project_11\project_11.srcs\sources_1\edk\system/drivers/pwm_ip_v1_00_a/src/pwm_ip_selftest.c(我的目錄在這裏)

註釋 #include "xio.h"

添加#define PWM_IP_USER_NUM_REG 2   圖60


保存,等待工程編譯結束。

出現圖61的錯誤,解決辦法。重新建立一個c工程。然後和上面的是一樣的,至於原因就不知道了。


測試

選擇Xilinx Tools->Program FPGA

在hello_world_0工程上右擊,選擇RunAs->Launch on Hardware,用示波器看波形結果是正確的,修改helloworld.c 中的佔空比可以看到不同的波形。


易出錯的地方:

第一個:在添加vhdl和verilog代碼的時候以及找錯誤的方法。

        第二個是出現類似於以下的錯誤: "Building target: hello_world_0.elf Invoking: ARM gcc linker arm-xilinx-eabi-gcc -Wl,-T -Wl,../src/lscript.ld -L../../standalone_bsp_0/ps7_cortexa9_0/lib -o"hello_world_0.elf" ./src/helloworld.o ./src/platform.o -l-Wl,--start-group,-lxil,-lgcc,-lc,--end-group ../lib/gcc/arm-xilinx-eabi/4.6.1/../../../../arm-xilinx-eabi/bin/ld.exe: cannot find -l-Wl,--start-group,-lxil,-lgcc,-lc,--end-group collect2: ld returned 1 exit status make: *** [hello_world_0.elf] Error 1"解決方法就是重新新建一個c工程,(衝PlanAhead重新導入一次),原因不祥。

       以上都在上面有提到過。這次是用裸跑的程序來調用IPcore,下次實驗是要爲這個IPcore開發Linux系統上的設備驅動,使得運行在Linux上的應用程序可以使用這個驅動程序與PL端進行通信,從而控制PWM的輸出。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章