软件版本:VIVADO2017.4
操作系统:WIN10 64bit
硬件平台:适用米联客 ZYNQ系列开发板
米联客(MSXBO)论坛:www.osrc.cn答疑解惑专栏开通,欢迎大家给我提问!!
17.1 概述
本课就以AXI-Lite总线实现PWM(Pulse Width Modulation,脉冲宽度调制)自定义IP作为验证AXI-Lite总线应用的方案,实现4路PWM,通过点亮LED观察效果,带领大家快速进入实战状态。
17.2 自定义IP的封装
设置总线形式为Lite总线,Lite总线是简化的AXI总线,消耗的资源少,当然性能比完整版的AXI总线差一点。因为频率要求不高,因此采用Lite总线就够了。设置寄存器数量为8,因为后面我们需要用到8个寄存器。
Step6:选择Edit IP,单击Finish完成
17.3 用户IP的修改
IP创建后,需要对其进行修改,建立我们能够实际使用的IP。
Step1:打开PWM_LITE_ML_v1_0.v文件。
修改如下:
修改如下:
说明:slv_reg0-slv_reg7为PS部分写入PL的寄存器。通过这8个寄存器的值,我们可以控制PWM的占空比。
下面这段代码就是PS写PL部分的寄存器,一共有8个寄存器。
always @( posedge S_AXI_ACLK ) begin if ( S_AXI_ARESETN == 1'b0 ) begin slv_reg0 <= 0; slv_reg1 <= 0; slv_reg2 <= 0; slv_reg3 <= 0; slv_reg4 <= 0; slv_reg5 <= 0; slv_reg6 <= 0; slv_reg7 <= 0; end else begin if (slv_reg_wren) begin case ( axi_awaddr[ADDR_LSB+OPT_MEM_ADDR_BITS:ADDR_LSB] ) 3'h0: for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 ) if ( S_AXI_WSTRB[byte_index] == 1 ) begin // Respective byte enables are asserted as per write strobes // Slave register 0 slv_reg0[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8]; end 3'h1: for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 ) if ( S_AXI_WSTRB[byte_index] == 1 ) begin // Respective byte enables are asserted as per write strobes // Slave register 1 slv_reg1[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8]; end 3'h2: for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 ) if ( S_AXI_WSTRB[byte_index] == 1 ) begin // Respective byte enables are asserted as per write strobes // Slave register 2 slv_reg2[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8]; end 3'h3: for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 ) if ( S_AXI_WSTRB[byte_index] == 1 ) begin // Respective byte enables are asserted as per write strobes // Slave register 3 slv_reg3[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8]; end 3'h4: for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 ) if ( S_AXI_WSTRB[byte_index] == 1 ) begin // Respective byte enables are asserted as per write strobes // Slave register 4 slv_reg4[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8]; end 3'h5: for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 ) if ( S_AXI_WSTRB[byte_index] == 1 ) begin // Respective byte enables are asserted as per write strobes // Slave register 5 slv_reg5[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8]; end 3'h6: for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 ) if ( S_AXI_WSTRB[byte_index] == 1 ) begin // Respective byte enables are asserted as per write strobes // Slave register 6 slv_reg6[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8]; end 3'h7: for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 ) if ( S_AXI_WSTRB[byte_index] == 1 ) begin // Respective byte enables are asserted as per write strobes // Slave register 7 slv_reg7[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8]; end default : begin slv_reg0 <= slv_reg0; slv_reg1 <= slv_reg1; slv_reg2 <= slv_reg2; slv_reg3 <= slv_reg3; slv_reg4 <= slv_reg4; slv_reg5 <= slv_reg5; slv_reg6 <= slv_reg6; slv_reg7 <= slv_reg7; end endcase end end end |
Step3:新建一个PWM.v 文件实现PWM输出。
module PWM( input clk, input rst_n, input [31:0]fre_set, input [31:0]wav_set, output PWM_o );
reg [31:0]fre_cnt; always @(posedge clk)begin if(rst_n==1'b0)begin fre_cnt <=32'd0; end else begin if(fre_cnt<fre_set) begin fre_cnt <= fre_cnt+1'b1; end else begin fre_cnt<=32'd0; end end end
assign PWM_o = (wav_set>fre_cnt);
endmodule |
Step5:修改后,保存。出现如下界面,选择Automatically pick new top module。
17.4 FPGA BD工程
Step1:新建一个VIVADO工程,根据自己的开发板正确配置芯片型号。
Step2:将封装好的自定义IP路径添加到工程。
Step3:新建一个BD文件。
Step4:向BD文件中添加一个ZYNQ Processing system IP,根据自身硬件完成IP的配置。
Step5:单击添加IP图标,将自定义PWM IP添加到BD文件中。
Step6:直接点击Run connection automation,然后单击OK。
Step7:选中PWM_o,按Ctrl+T组合键引出端口,修改端口名为PWM_o。
Step8:添加 ila CORE。右击PWM信号线,后选择Debug,之后会提示Run connection automation
设置IP参数
Step9:搭建完成FPGA BD工程
17.5 加载到SDK
Step1:创建一个新的空工程。
Step2:将提供例程中SDK工程的main.c源文件复制,并粘贴到新建SDK工程。
Step3:右击工程,选择Debug as ->Debug configurations。
Step4:选中system Debugger,双击创建一个系统调试,点击Apply,点击Debug。
Step5:sdk中单击运行程序按钮运行程序。
Step6:回到VIVADO,单击Open Target->Auto Connect
Step7:加载完成后的界面
17.6 程序分析
main函数中,根据之前章节的讲解我们可知,此处是分别向AXI总线的寄存器中写入数据。在12.3小节里,我们观察到,pwm_o[0]的频率设置和波形设置是通过slv_reg0和slv_reg1控制的。
由上图可知,我们写入的数据和实际的输出是完全一致的,验证了我们的想法。