打包IP核,PWM发生器
PWM发生器
- 所谓PWM即为脉冲宽度调制技术,通过改变PWM波的周期可以实现调频,通过改变PWM波的占空比可以实现调压,大量应用于控制电路中中,如常用的PWM调光技术,电机调速技术等。
PWM设计文件
模块的端口设计如下:
端口名 | 功能 |
---|---|
clk | 输入时钟 |
rst_n | 复位信号(低电平有效) |
set_enable | 配置端口使能信号 |
period | 周期 = period * clk |
void_value | 占空比 = void_value / period |
pwm_out | PWM波输出 |
- 设计文件代码:
module PWM_Top
#(
parameter PWM_BIT_WIDTH = 16//预定义参数,位宽
)
(
input clk, //输入时钟
input rst_n, //复位信号
input set_enable, //参数配置使能信号
input [PWM_BIT_WIDTH - 1 : 0] period,//周期=period*时钟频率
input [PWM_BIT_WIDTH - 1 : 0] void_value, //占空比=void_value/period
output pwm_out
);
reg[PWM_BIT_WIDTH - 1 : 0] period_r; //周期寄存器
reg[PWM_BIT_WIDTH - 1 : 0] void_value_r; //占空比*周期寄存器
reg[PWM_BIT_WIDTH - 1 : 0] period_cnt; //周期计数器
reg pwm_out_r; //pwm输出寄存器
assign pwm_out = pwm_out_r;//将pwm实时输出
always@(posedge clk or negedge rst_n) begin //缓存输入周期与占空比参数
if(!rst_n) begin //复位清零
period_r <= {PWM_BIT_WIDTH {1'b0}};
void_value_r <= {PWM_BIT_WIDTH {1'b0}};
end
else begin
if (set_enable) begin //使能置数
period_r <= period;
void_value_r <= void_value;
end
else begin //未使能也未复位,保持
period_r <= period_r;
void_value_r <= void_value_r;
end
end
end
always@(posedge clk or negedge rst_n) begin //周期计数器
if(!rst_n) begin //复位清零
period_cnt <= {PWM_BIT_WIDTH {1'b0}};
end
else begin
if (period_cnt <= period_r)begin //未溢出时计数器自增1
period_cnt <= period_cnt + 1'b1;
end
else begin //当溢出时,清零计数器
period_cnt <= {PWM_BIT_WIDTH {1'b0}};
end
end
end
always@(posedge clk or negedge rst_n) begin //PWM波输出
if (!rst_n) begin //复位清零
pwm_out_r <= 1'b0;
end
else begin
if (period_cnt > void_value_r)begin //输出高电平
pwm_out_r <= 1'b1;
end
else begin //输出低电平
pwm_out_r <= 1'b0;
end
end
end
endmodule
- RTL结构图如下:
仿真文件
- 使用testbench插件生成测试文件模板,稍作修改得到我们的测试文件
`timescale 1ns / 1ps
module tb_PWM_Top;
// PWM_Top Parameters
parameter PERIOD = 2;
parameter PWM_BIT_WIDTH = 16;
// PWM_Top Inputs
reg clk = 0 ;
reg rst_n = 0 ;
reg set_enable = 0 ;
reg [PWM_BIT_WIDTH - 1 : 0] period = 0 ;
reg [PWM_BIT_WIDTH - 1 : 0] void_value = 0 ;
// PWM_Top Outputs
wire pwm_out ;
initial
begin
forever #(PERIOD/2) clk=~clk;
end
initial
begin
#(PERIOD*2) rst_n = 0;
end
PWM_Top #(
.PWM_BIT_WIDTH ( PWM_BIT_WIDTH ))
u_PWM_Top (
.clk ( clk ),
.rst_n ( rst_n ),
.set_enable ( set_enable ),
.period ( period [PWM_BIT_WIDTH - 1 : 0] ),
.void_value ( void_value [PWM_BIT_WIDTH - 1 : 0] ),
.pwm_out ( pwm_out )
);
initial begin
rst_n = 1'b0;
set_enable =1'b1;
period = 16;
void_value = 8;
#70
set_enable = 0;
#200
rst_n = 1;
#200
set_enable = 1;
#1000
void_value = 2;
#1000
period = 128;
void_value =16;
#2000
$finish;
end
endmodule
- 仿真波形如下:
打包IP核
- 点击"Tools -> Create and Package New IP",打开向导
- 在"Identification"设置IP核的名字,功能以及其他信息
- 在"Compatibility"设置适配的芯片型号
- 在"Customization Parameters"界面设置预定义的常量参数,参数类型,时候可修改,默认值等设置,当需要一些选择性端口时,还可添加配置常量,供后续端口处使用,此处添加"PWM_Bit_Width"常量用于设置输入数据位宽,添加"Need Set Enabler Signal Or Not"常量用于后续配置是否需要使能Enable信号。
- 在"Ports and Interfaces"界面,设置需要配置的端口,此处将"set_enabler"信号进行定义。将该端口设置为可选项,并在下方填入表达式"Need Set Enabler Signal Or Not ==1",并将端口默认值设置为1。对于其他无特殊要求的端口,可不进行设置。
- 在"Customization GUI"界面,能够看到即将生成的IP核外观和设置参数,看IP设计是否符合预期。
- 最后点击"Review and Package"界面。对IP核进行打包。
- 打开"IP Catalog"界面,在"User Repository -> UserIP"文件夹下,看到我们刚刚生成的IP
使用打包好的IP
- 在一个新建的工程中,点击"PROJECT MANAGER -> Settings",在"Project Settings -> IP -> Repository"界面中,点击"IP Repository"下的+号,选择用户打包好的IP核所对应的工程文件,点击确定。
- 然后点击"PROJECT MANAGER -> IP Catalog",在"User Repository -> UserIP"文件夹下,即可看到我们添加的自定义IP核。当然也可以在"Block Design"界面下,直接点击+号添加使用。