一开始我不太认同通过测试文件的输入值改变占空比的做法符合要求,总感觉这等同于多次不同的测试放到了一起。后来感觉手动调占空比也符合要求,可以对应开发板上一个按键,来改变占空比。
手动调的方案
module PWM(clk,rst_n,duty,PWM_wave);
input clk;
input [6:0] duty;
input rst_n;
output reg PWM_wave;
reg [7:0] count;
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
PWM_wave<=0;
count<=8'd0;
end
else
begin
if(count>=8'd100)
count<=8'd0;
if(count<8'd100)
count<=count+8'd1;
if(count<duty)
PWM_wave<=1;
if(count>=duty)
PWM_wave<=0;
end
end
endmodule
测试文件
`timescale 10ns/1ns
module test();
reg clk;
reg rst_n;
reg [6:0] duty;
wire PWM_wave;
PWM u1(.clk(clk),.rst_n(rst_n),.duty(duty),.PWM_wave(PWM_wave));
initial
begin
clk<=0;
rst_n=0;
duty=7'd10;
#10 rst_n=1;
#100 duty=7'd30;
#100 duty=7'd50;
#100 duty=7'd70;
end
always #10 clk<=~clk;
endmodule
自动改变占空比的程序可对应呼吸灯实例,代码如下
顶层文件
module top_pwm(CLK_50M,RST_N,pwm_out);
input CLK_50M;
input RST_N;
output pwm_out;
wire CLK_1M;
fenpin i1(.CLK_50M(CLK_50M),.RST_N(RST_N),.CLK_1M(CLK_1M));
PWM i2(.CLK_1M(CLK_1M),.RST_N(RST_N),.pwm_out(pwm_out));
endmodule
PWM程序
module PWM(CLK_1M,RST_N,pwm_out);
input CLK_1M;
input RST_N;
output pwm_out;
reg [6:0] time_cnt;
reg [6:0] turn_reg;//翻转寄存器
reg pwm_reg;//输出寄存器
reg flag;
//---------------------------------------------
parameter period=7'd50;//周期
parameter turn=7'd30;//最大占空比
//---------------------------------------------------
always @ (posedge CLK_1M or negedge RST_N)
begin
if(!RST_N)
begin
time_cnt <= 7'd0;
pwm_reg<= 1'b0;
turn_reg<=turn;
end
else
begin
time_cnt<=time_cnt+7'd1;
if(turn_reg==turn)
flag=1'b0;
if(turn_reg==7'd1)
flag=1'b1;
if ( time_cnt <= turn_reg-1)
pwm_reg <= 1'b0;
if (( time_cnt > turn_reg-1) && (time_cnt<period-1))
pwm_reg <= 1'b1;
if(time_cnt==period-1)
begin
time_cnt <= 7'd0;
if(flag==1'b1)//改变占空比
turn_reg<=turn_reg+7'd1;
if(flag==1'b0)
turn_reg<=turn_reg-7'd1;
end
end
end
assign pwm_out= pwm_reg;
endmodule
分频产生1MHz时钟
module fenpin(CLK_50M,RST_N,CLK_1M);
input CLK_50M ;
input RST_N;
output CLK_1M;
reg [6:0] time_cnt;
reg CLK_1M;
parameter period=7'd25;
always@(posedge CLK_50M or negedge RST_N)
begin
if(!RST_N)
begin
time_cnt<=7'd0;
CLK_1M<=1'b0;
end
else
begin
time_cnt<=time_cnt+7'd1;
if(time_cnt==period-1)
begin
CLK_1M<=~CLK_1M;
time_cnt<=7'd0;
end
end
end
endmodule
测试文件
`timescale 1ns/1ns
module pwm_test();
reg CLK_50M;
reg RST_N;
wire pwm_out;
top_pwm u1 (.CLK_50M(CLK_50M),.RST_N(RST_N),.pwm_out(pwm_out));
initial
begin
RST_N=0;
CLK_50M=0;
#10 RST_N=1;
#10 RST_N=0;
#10 RST_N=1;
end
always #10 CLK_50M=~CLK_50M;
endmodule