首先我们先编写一个pwm模块,用于封装成IP核。
`timescale 1ns/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 or posedge 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 or posedge rst)
begin
if(rst == 1)
period_cnt <= { N {1'b0}};
else
period_cnt <= period_cnt + period_r;
end
always @(posedge clk or posedge 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
1.我们在Vivado开发环境里新建了一个“custom_pwm_ip”的工程,并生成了一个名为system的Block Diagram文件,再添加ZYNQ7 Processing System内核系统到这个原理图中,创建好后的Vivado工程及Block Diagram如下:
2. 接下来需要配置ZYNQ的DDR为 MT41J256M16 RE-125, 再配置MIO48,MIO49为UART1。
下面开始创建自定义的RTC控制IP核:
1.点击菜单Tools->Create and Package IP…
2. 选择Create a new AXI4 peripheral项,这里我们是要产生一个AXI4总线接口的外设IP, 前面的那几项是把当前的工程打成包。
3. 显示IP的名字,版本和描述等信息。我们这里可以修改了IP的名字和存放位置。
4. 显示AXI总线接口名字,接口是Slave, 数据宽度是32位,IP内部的寄存器数量为4个。 我们这里不需要修改,点击Next。
5. 点击Finish完成。
6. 打开IP Catalog界面,我们可以看到ax_pwm_v1.0了,但现在返个IP还不具有任何功能。
7. 右键选中ax_pwm_v1.0, 然后选择Edit in IP Packager项。
8. 点击OK, 软件自动会打开另外一个Vivado窗口来对返个用户IP核进行编辑。
新的IP的Vivado工程显示如下:
9. 双击顶层文件ax_pwm_v1_0.v打开,在下图的位置添加PWM的管脚端口定义。
在顶层文件ax_pwm_v1_0.v的下面所示位置对pwm管脚的例化。
10. 在双击打开ax_pwm_v1_0_S00_AXI.v文件,在以下的位置添加pwm的管脚端口定义
11.将pwm核心功能文件“ax_pwm.v”放在hdl目录,同样可以在返个目录下找到这个文件。
11. 将“ax_pwm.v”添加到工程中。
12. 例化pwm核心模块,将slv_reg0用于控制pwm的频率,slv_reg1用于控制pwm的占空比。
13. 可以编译一下看看有没有语法错误
14. 双击IP-XACT下的component.xml文件,返回到Package IP-rtc_ip窗口,点击Port and Interfaces项,点击Merge changes from Ports and Interface Wizard。
再对前面没有打钩的File Groups点击Merge changes from File Groups Wizard来更新文件和驱动
选择Review and Package项,然后点击Re-Package IP按键结束IP核的设置。
到此为止一个用户自定义的IP核就算设计完成了,接下来我们关闭IP核的Vivado工程,回到custom_pwm_ip的系统工程界面,在block中搜索pwm就可以完成导入了。