【ZYNQ Ultrascale+ MPSOC FPGA教程】第三十章 自定義IP實驗

原創聲明:

本原創教程由芯驛電子科技(上海)有限公司(ALINX)創做,版權歸本公司全部,如需轉載,需受權並註明出處。ide

適用於板卡型號:

AXU2CGA/AXU2CGB/AXU3EG/AXU4EV-E/AXU4EV-P/AXU5EV-E/AXU5EV-P /AXU9EG/AXU15EG測試

 

實驗Vivado工程目錄爲「custom_pwm_ip /vivado」。this

實驗vitis工程目錄爲「custom_pwm_ip /vitis」。spa

Xilinx官方爲你們提供了不少IP核,在Vivado的IP Catalog中能夠查看這些IP核,用戶在構建本身的系統中,不可能只使用Xilinx官方的免費IP核,不少時候須要建立屬於本身的用戶IP核,建立本身的IP核有不少好處,例如系統設計定製化;設計複用,能夠在在IP核中加入license, 有償提供給別人使用;簡化系統設計和縮短設計時間。用ZYNQ系統設計IP核,最經常使用的就是使用AXI總線將PS同PL部分的IP核鏈接起來。本實驗將爲你們介紹如何在Vivado中構建AXI總線類型的IP核,此IP核用來產生一個PWM,用這個控制開發板上的LED,作一個呼吸燈的效果。debug

FPGA工程師工做內容

如下爲FPGA工程師負責內容。設計

1. PWM介紹

咱們常常使用PWM來控制LED,蜂鳴器等,經過調節脈衝的佔空比來調節LED的亮度。3d

在其餘開發板中咱們使用過的一個pwm模塊以下:調試

////////////////////////////////////////////////////////////////////////////////// // // ////////////////////////////////////////////////////////////////////////////////// // // // Copyright (c) 2017,ALINX(shanghai) Technology Co.,Ltd // // All rights reserved // // // // This source file may be used and distributed without restriction provided // // that this copyright statement is not removed from the file and that any // // derivative work contains the original copyright notice and the associated // // disclaimer. // // // //////////////////////////////////////////////////////////////////////////////////  //================================================================================ // Description: pwm model // pwm out period = frequency(pwm_out) * (2 ** N) / frequency(clk); // //================================================================================ // Revision History: // Date By Revision Change Description //-------------------------------------------------------------------------------- // 2017/5/3 meisq 1.0 Original //********************************************************************************/ `timescale1ns/1ps module ax_pwm #( parameter N =32//pwm bit width ) ( input clk, input rst, input[N -1:0]period, input[N -1:0]duty, output pwm_out ); reg[N -1:0] period_r; reg[N -1:0] duty_r; reg[N -1:0] period_cnt; reg pwm_r; assign pwm_out = pwm_r; always@(posedge clk orposedge rst) begin if(rst==1) begin period_r <={ N {1'b0}}; duty_r <={ N {1'b0}}; end else begin period_r <= period; duty_r <= duty; end end always@(posedge clk orposedge rst) begin if(rst==1) period_cnt <={ N {1'b0}}; else period_cnt <= period_cnt + period_r; end always@(posedge clk orposedge rst) begin if(rst==1) begin pwm_r <=1'b0; end else begin if(period_cnt >= duty_r) pwm_r <=1'b1; else pwm_r <=1'b0; end end endmodule 

能夠看到這個PWM模塊須要2個參數「period」、「duty」來控制頻率和佔空比,」period」爲步進值,也就是計數器每一個週期要加的值。Duty爲佔空比的值。咱們須要設計一些寄存器來控制這些參數,這裏須要使用AXI總線,PS經過AXI總線來讀寫寄存器。rest

2. Vivado工程創建

用」ps_hello」工程另存爲一個名爲「custom_pwm_ip」工程code

2.1 建立自定義IP

1)點擊菜單「Tools->Create and Package IP...」

2)選擇「Next」

3)選擇建立一個新的AXI4設備

4)名稱填寫「ax_pwm」,描述填寫「alinx pwm」,而後選擇一個合適的位置用來放IP

5)下面參數能夠指定接口類型、寄存器數量等,這裏不須要修改,使用AXI Lite Slave接口,4個寄存器。

6)點擊「Finish」完成IP的建立

7)在「IP Catalog」中能夠看到剛纔建立的IP

8)這個時候的IP只有簡單的寄存器讀寫功能,咱們須要修改IP,選擇IP,右鍵「Edit in IP Packager」

9)這是彈出一個對話框,能夠填寫工程名稱和路徑,這裏默認,點擊「OK」

10)Vivado打開了一個新的工程

11)添加PWM功能的核心代碼

12)添加代碼時選擇複製代碼到IP目錄

13)修改「ax_pwm_v1_0.v」,添加一個pwm輸出端口

14)修改「ax_pwm_v1_0.v」,在例化「ax_pwm_V1_0_S00_AXI」,中添加pwm端口的例化

15)修改「ax_pwm_v1_0_s00_AXI.v」文件,添加pwm端口,這個文件是實現AXI4 Lite Slave的核心代碼

16)修改「ax_pwm_v1_0_s00_AXI.v」文件,例化pwm核心功能代碼,將寄存器slv_reg0和slv_reg1用於pwm模塊的參數控制。

17)雙擊「component.xml」文件

18)在「File Groups」選項中點擊「Merge changers from File Groups Wizard」

19)在「Customization Parameters」選項中點擊「Merge changes form Customization Parameters Wizard」

20)點擊「Re-Package IP」完成IP的修改

2.2 添加自定義IP到工程

1)搜索「pwm」,添加「ax_pwm_v1.0」

2)點擊「Run Connection Automation」

3)導出pwm端口

4)保存設計,並Generate Output Products

5)添加xdc文件分配管腳,把pwm_0輸出端口分配給LED1,作一個呼吸燈,編譯生成bit文件,導出硬件

軟件工程師工做內容

如下爲軟件工程師負責內容。

3. Vitis軟件編寫調試

1)啓動Vitis,新建APP,模板選擇「Hello World」

2)在bsp裏找到「xparameters.h」文件,這個很是重要的文件,裏面找到了自定IP的寄存器基地址,能夠找到自定義IP的基地址。

3)有個寄存器讀寫宏和自定義IP的基地址,咱們開始編寫代碼,測試自定義IP,咱們先經過寫寄存器AX_PWM_S00_AXI_SLV_REG0_OFFSET,控制PWM輸出頻率,而後經過寫寄存器AX_PWM_S00_AXI_SLV_REG1_OFFSET控制PWM輸出的佔空比。

#include <stdio.h> #include "platform.h" #include "xil_printf.h" #include "ax_pwm.h" #include "xil_io.h" #include "xparameters.h" #include "sleep.h" unsignedint duty; int main() { init_platform(); print("Hello World\n\r"); //pwm out period = frequency(pwm_out) * (2^N) / frequency(clk);  AX_PWM_mWriteReg(XPAR_AX_PWM_0_S00_AXI_BASEADDR, AX_PWM_S00_AXI_SLV_REG0_OFFSET,17179);//200hz  //duty = (2^N) * (1 - (duty cycle)) - 1  while(1){ for(duty =0x8fffffff; duty <0xffffffff; duty = duty +100000){ AX_PWM_mWriteReg(XPAR_AX_PWM_0_S00_AXI_BASEADDR, AX_PWM_S00_AXI_SLV_REG1_OFFSET, duty); usleep(100); } } cleanup_platform(); return0; } 

4)經過運行代碼,咱們能夠看到PLLED1呈現出一個呼吸燈的效果。

5)經過debug,咱們來查看一下寄存器

6)進入debug狀態,按「F6」能夠單步運行。

7)經過菜單能夠查看「Memory」窗口

8)添加一個監視地址「0x80000000」

9)單步運行,觀察變化

4. 實驗總結

經過本實驗咱們掌握了更多的Vitis調試技巧,掌握了ARM + FPGA開發的核心內容,就是ARM和FPGA數據交互。

相關文章
相關標籤/搜索