呼吸灯设计
4秒1次循环,每2ms秒变化1次,(前2秒亮度增大,后2秒亮度减小)这里暂时不会实现
module breathing_led(clk,rst_n,led,cnt_2ms,cnt_2ms_num,cnt_2s,cnt_2s_num,flag_2ms,flag_2s);
input clk,rst_n;
output reg [19:0]cnt_2ms; //2ms的计数位宽
output reg [19:0]cnt_2s;
output reg [1:0] cnt_2s_num;
output reg [11:0]cnt_2ms_num; //计数多少个2ms的位宽
output led;
output reg flag_2ms; //2ms中电平的高低
output reg flag_2s; //2s电平高低
//实现2ms计数器
always @(posedge clk or negedge rst_n)begin
if(!rst_n)begin
cnt_2ms <= 8'b0;
flag_2ms <= 1'b0;
end
else if (cnt_2ms == 99)begin
cnt_2ms <= 8'b0;
flag_2ms <= 1'b0;
end
else begin
cnt_2ms<= cnt_2ms + 8'b1;
flag_2ms <= 1'b1;
end
end
//实现需要计数多少个2ms
always @(posedge clk or negedge rst_n)begin
if(!rst_n)
cnt_2ms_num <= 12'b0;
else if ( cnt_2ms_num == 999)
cnt_2ms_num <= 12'b0;
else
cnt_2ms_num <= cnt_2ms_num + 12'b1;
end
//实现2秒计数器
always @(posedge clk or negedge rst_n)begin
if(!rst_n)begin
cnt_2s <= 20'b0;
flag_2s <= 0;
end
else if ( cnt_2s== 100000)begin
cnt_2s <= 20'b0;
flag_2s <= 0;
end
else begin
cnt_2s <= cnt_2s+ 20'b1;
flag_2s <= 1;
end
end
//实现每两秒计一次
always @(posedge clk or negedge rst_n)begin
if(!rst_n)
cnt_2s_num <= 0;
else if ( cnt_2s_num == 2)
cnt_2s_num <= 0;
else
cnt_2s_num<= 1;
end
assign led = flag_2ms;
endmodule
tb仿真:
`timescale 1ns/1ps //时间精度
`define Clock 20 //时间周期
module breathing_led_tb;
reg rst_n;
reg clk;
wire led;
wire[11:0]cnt_2ms_num;
wire [19:0]cnt_2s;
wire[1:0]cnt_2s_num;
wire[7:0] cnt_2ms;
wire flag_2s;
wire flag_2ms;
breathing_led counter
(
.clk(clk),
.rst_n(rst_n),
.led (led),
.cnt_2s_num(cnt_2s_num),
.cnt_2s(cnt_2s),
.cnt_2ms_num(cnt_2ms_num),
.flag_2s(flag_2s),
.flag_2ms(flag_2ms),
.cnt_2ms(cnt_2ms)
);
initial
clk = 0;
always #(`Clock/2) clk= ~clk;
initial begin
rst_n=0 ;#(`Clock*20+1);
rst_n=1;
end
initial begin
#(`Clock*1000000);
$stop;
end
endmodule
其中flag_2s,能看出每2s(2000000ns)计数一次,同时2s内还包含有2ms的计数变化。
flag_2ms的话是每2ms变化一次。