完成任务: 在流水灯基础上加入pwm呼吸灯设计,关于pwm呼吸灯设计可以看博主上一篇博客PWM呼吸灯设计 ,开发板上灯每两秒进行一次切换,每一个的亮灭间隔为一秒。
代码参考:
Verilog
module pwm_led_change(
input wire clk ,
input wire rst_n ,
output reg [3:0] led
);
parameter TIME_US = 6'd49;//50*20ns 1us
parameter TIME_MS = 10'd999;//1000ns*1000 1ms
parameter TIME_S = 10'd999;//1000ms*1000 1s
reg [5:0] cnt_us;
reg [9:0] cnt_ms;
reg [9:0] cnt_s;
reg [1:0] cnt_2s;
reg [1:0] state;//保存led灯状态
reg flag;//闪烁标志
wire add_cnt_us;//us计数器开始计数标志
wire end_cnt_us;//us计数器结束计数标志
wire add_cnt_ms;//ms计数器开始计数标志
wire end_cnt_ms;//ms计数器结束计数标志
wire add_cnt_s;
wire end_cnt_s;
wire end_cnt_2s;
//1us计时器
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
cnt_us <= 6'd0;
end
else if(add_cnt_us) begin
if(end_cnt_us) begin
cnt_us <= 6'd0;
end
else begin
cnt_us <= cnt_us +1'd1;
end
end
else begin
cnt_us <= cnt_us;
end
end
assign add_cnt_us = 1'b1;
assign end_cnt_us = add_cnt_us && (cnt_us == TIME_US);
//1ms计时器
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
cnt_ms <= 10'd0;
end
else if(add_cnt_ms) begin
if(end_cnt_ms) begin
cnt_ms <= 10'd0;
end
else begin
cnt_ms <= cnt_ms + 1'd1;
end
end
else begin
cnt_ms <= cnt_ms;
end
end
assign add_cnt_ms = end_cnt_us;
assign end_cnt_ms = add_cnt_ms && (cnt_ms == TIME_MS);
//1s计时器
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
cnt_s <= 10'd0;
end
else if(add_cnt_s) begin
if(end_cnt_s) begin
cnt_s <= 10'd0;
end
else begin
cnt_s <= cnt_s + 1'd1;
end
end
else begin
cnt_s <= cnt_s;
end
end
assign add_cnt_s = end_cnt_ms;
assign end_cnt_s = add_cnt_s && (cnt_s == TIME_S);
//2s计时
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
cnt_2s <= 2'd0;
end
else if(end_cnt_s)begin
cnt_2s <= cnt_2s + 1'd1;
end
else if(cnt_2s == 2'd2) begin
cnt_2s <= 2'd0;
end
else begin
cnt_2s <= cnt_2s;
end
end
assign end_cnt_2s = (cnt_2s == 2'd2);
//state状态
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
state <= 2'd0;
end
else if(end_cnt_2s) begin
state <= state + 1'd1;
end
else begin
state <= state;
end
end
//flag值判断
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
flag <= 1'b0;
end
else if(end_cnt_s) begin
flag <= ~flag ;
end
else begin
flag <= flag;
end
end
//led变化
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
led = 4'b0000;
end
else begin
case(state)
2'd0 : begin
if(flag == 1'b1) begin//电亮
if(cnt_s > cnt_ms) begin
led[0] <= 1'b1;
led[3:1] <= 3'b000;
end
else begin
led[0] <= 1'b0;
led[3:1] <= 3'b000;
end
end
else begin//熄灭
if(cnt_s > cnt_ms) begin
led[0] <= 1'b1;
led[3:1] <= 3'b000;
end
else begin
led[0] <= 1'b1;
led[3:1] <= 3'b000;
end
end
end
2'd1 : begin
if(flag == 1'b1) begin//电亮
if(cnt_s > cnt_ms) begin
led[1] <= 1'b1;
led[3:2] <= 2'b00;
led[0] <= 1'b0;
end
else begin
led[1] <= 1'b0;
led[3:2] <= 2'b00;
led[0] <= 1'b0;
end
end
else begin//熄灭
if(cnt_s > cnt_ms) begin
led[1] <= 1'b0;
led[3:2] <= 2'b00;
led[0] <= 1'b0;
end
else begin
led[1] <= 1'b1;
led[3:2] <= 2'b00;
led[0] <= 1'b0;
end
end
end
2'd2 : begin
if(flag == 1'b1) begin//电亮
if(cnt_s > cnt_ms) begin
led[2] <= 1'b1;
led[3] <= 1'b0;
led[1:0] <= 2'b0;
end
else begin
led[2] <= 1'b0;
led[3] <= 1'b0;
led[1:0] <= 2'b0;
end
end
else begin//熄灭
if(cnt_s > cnt_ms) begin
led[2] <= 1'b0;
led[3] <= 1'b0;
led[1:0] <= 2'b0;
end
else begin
led[2] <= 1'b1;
led[3] <= 1'b0;
led[1:0] <= 2'b0;
end
end
end
2'd3 : begin
if(flag == 1'b1) begin//电亮
if(cnt_s > cnt_ms) begin
led[3] <= 1'b1;
led[2:0] <= 3'b000;
end
else begin
led[3] <= 1'b0;
led[2:0] <= 3'b000;
end
end
else begin//熄灭
if(cnt_s > cnt_ms) begin
led[3] <= 1'b0;
led[2:0] <= 3'b000;
end
else begin
led[3] <= 1'b1;
led[2:0] <= 3'b000;
end
end
end
default :led <= 4'b0000;
endcase
end
end
endmodule
测试文件:
Verilog
`timescale 1ns/1ns
module pwm_led_change_tb();
reg clk;
reg rst_n;
wire [3:0] led;
parameter CYCLE = 20;
parameter TIME_US = 5;
parameter TIME_MS = 10;
parameter TIME_S = 10;
always #(CYCLE/2) clk = ~clk;
initial begin
clk = 1'b0;
rst_n = 1'b0;
#(CYCLE);
rst_n = 1'b1;
#((TIME_US + 1)*(TIME_MS + 1)*(TIME_S + 1)*CYCLE*2*4);
$stop;
end
pwm_led_change #(
.TIME_US (TIME_US),
.TIME_MS (TIME_MS),
.TIME_S (TIME_S)
)u_pwm_led_change(
.clk (clk),
.rst_n (rst_n),
.led (led)
);
endmodule
我们通过modelsim仿真结果如下:
结果展示: