自定义IP核
自定义LED IP核,控制PL LED呈现呼吸灯的效果,且PS可以通过AXI接口来控制呼吸灯的开关和呼吸的频率。

IP核设计
下边是第三方设计好的呼吸灯Verilog代码,大概原理为调整占空比控制LED灯的呼吸效果。
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 
 | 
 
 module breath_led(
 input          sys_clk        ,
 input          sys_rst_n      ,
 input          sw_ctrl        ,
 input          set_en         ,
 input   [9:0]  set_freq_step  ,
 
 output         led
 );
 
 
 
 parameter  START_FREQ_STEP = 10'd100;
 
 reg  [15:0]  period_cnt  ;
 reg  [9:0]   freq_step   ;
 reg  [15:0]  duty_cycle  ;
 reg          inc_dec_flag;
 
 
 wire         led_t       ;
 
 assign led_t = ( period_cnt <= duty_cycle ) ? 1'b1 : 1'b0 ;
 assign led = led_t & sw_ctrl;
 
 
 always @ (posedge sys_clk) begin
 if (!sys_rst_n)
 period_cnt <= 16'd0;
 else if(!sw_ctrl)
 period_cnt <= 16'd0;
 else if( period_cnt == 16'd50_000 )
 period_cnt <= 16'd0;
 else
 period_cnt <= period_cnt + 16'd1;
 end
 
 
 always @(posedge sys_clk) begin
 if(!sys_rst_n)
 freq_step <= START_FREQ_STEP;
 else if(set_en) begin
 if(set_freq_step == 0)
 freq_step <= 10'd1;
 else if(set_freq_step >= 10'd1_000)
 freq_step <= 10'd1_000;
 else
 freq_step <= set_freq_step;
 end
 end
 
 
 always @(posedge sys_clk) begin
 if (sys_rst_n == 1'b0) begin
 duty_cycle <= 16'd0;
 inc_dec_flag <= 1'b0;
 end
 else if(!sw_ctrl) begin
 duty_cycle <= 16'd0;
 inc_dec_flag <= 1'b0;
 end
 
 else if( period_cnt == 16'd50_000 ) begin
 if( inc_dec_flag ) begin
 if( duty_cycle == 16'd0 )
 inc_dec_flag <= 1'b0;
 else if(duty_cycle < freq_step)
 duty_cycle <= 16'd0;
 else
 duty_cycle <= duty_cycle - freq_step;
 end
 else begin
 if( duty_cycle >= 16'd50_000 )
 inc_dec_flag <= 1'b1;
 else
 duty_cycle <= duty_cycle + freq_step;
 end
 end
 else
 duty_cycle <= duty_cycle ;
 end
 endmodule
 
 | 
==上述verilog代码实现的呼吸灯涉及的输入输出和参数如下:==
Input:
    sys_clk          , //时钟信号
    sys_rst_n      , //复位信号
    sw_ctrl          , //呼吸灯开关控制信号 1:亮 0:灭
    set_en           , //设置呼吸灯频率设置使能信号
    set_freq_step  , //设置呼吸灯频率变化步长
Output:
    led              //LED
Parameters:
    parameter  START_FREQ_STEP = 10’d100; //设置频率步长初始值
1 新建IP
打开Vivado 选择manage IP,选择保存IP的路径
tools—create and package new IP 
配置IP名称,接口等信息


IP Catalog— user Reposity—AXI Peripheral —自定义IP—右击—edit in IP packager 

2 修改代码
vivado自动创建.v实例化了AXI4,里边可以找到定义的寄存器

右键breath_led_IP_v1_0,add Sources,新建一个.v文件准备实现自定义IP核逻辑。
添加呼吸灯模块代码后,需要在breath_led_IP_v1_0_S01_AXI_inst中例化呼吸灯IP核,并添加参数。


完成后在breath_led_IP_v1_0中例化breath_led_IP_v1_0_S01_AXI,添加参数。
定义led 和 申明START_FREQ_STEP,以及后续例化中补充接口和参数

点击Run Sythesized对模块综合,检查代码是否错误
3 打包IP核
回到Package IP界面
compatibility 添加支持的开发板、修改Customization Parameters定制参数

Re-Package IP,自此,之前创建的IP核打包完成
vivado硬件设计
创建一个工程
在Setting—IP—Repository中添加之前创建的IP项目,添加完成后在Ip Catalog中也可以右键修改


添加Zynq处理器以及自定义IP核,验证连接没有出错后
在Design Sources中右键system,Generate output product,然后点击Create HDL Wrapper

验证无误后,生成bitstream文件
导出包含bitstream的xsa文件
vitis软件设计
三个不同的文件路径都可以看到IP核对应代码:
export/CustomIP_led/hw/drivers/breath_led_ip_v1_0
hw/drivers/breath_led_ip_v1_0
psu_cortexa53_0/standalone_domain/bsp/psu_cortexa53_0/libsrc/breath_led_ip_v1_0
1 利用导出的xsa新建平台
2 新建空项目,创建main.c文件
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 
 | #include "xparameters.h" #include "breath_led_IP.h"
 #include "xil_io.h"
 #include "stdio.h"
 
 
 #define LED_IP_BASEADDR XPAR_BREATH_LED_IP_0_S01_AXI_BASEADDR
 #define LED_IP_REG0 	BREATH_LED_IP_S01_AXI_SLV_REG0_OFFSET
 #define LED_IP_REG1 	BREATH_LED_IP_S01_AXI_SLV_REG1_OFFSET
 
 int main(){
 
 printf("led user ip test!\n");
 BREATH_LED_IP_mWriteReg(LED_IP_BASEADDR,LED_IP_REG1,0x800003e8);
 BREATH_LED_IP_mWriteReg(LED_IP_BASEADDR,LED_IP_REG0,0x00000001);
 
 
 return 0;
 }
 
 | 
修改IP核:
修改.v文件
File Group、Review and Package、Run Sythesized检查错误、Re-Package重新封装IP
Show IP Status、Upgrade Selected、在对话框中选择Generate output Products
由于这里只是测试一下修改IP核从LED寄存器中读取数据,所以就不需要修改顶层设计了
直接生成bitstream文件
导出硬件xsa,包含bitstream文件,覆盖老版本xsa文件
回到vitis,platform,右键,update Hardware Specification