(1)设计定义:设计呼吸灯LED,一个循环周期总时间控制在2.5s内,LED显示从熄灭到慢慢亮起耗时1s,然后保持全亮0.5s,最后在1s内从点亮慢慢熄灭。
(2)设计思路:可以使用状态机实现功能,三个状态:从熄灭到点亮、保持点亮、从点亮到熄灭。
(3)代码设计:
1.首先需要定义4个计数器,分别计数1us,1ms,0.5s,1s
//1us计时器设计
always@(posedge clk or negedge reset_n)
if(!reset_n)
cnt_us <= 6'd0;
else if(!en_cnt)
cnt_us <= 6'd0;
else if(cnt_us == MCNT_US)
cnt_us <= 6'd0;
else
cnt_us <= cnt_us + 6'd1;
//1ms计数器
always@(posedge clk or negedge reset_n)
if(!reset_n)
cnt_ms <= 10'd0;
else if(!en_cnt)
cnt_ms <= 10'd0;
else if((cnt_ms == MCNT_MS) && (cnt_us == MCNT_US))
cnt_ms <= 10'd0;
else if(cnt_us == MCNT_US)
cnt_ms <= cnt_ms + 10'd1;
else
cnt_ms <= cnt_ms;
//0.5s计数器
always@(posedge clk or negedge reset_n)
if(!reset_n)
cnt_s_half <= 9'd0;
else if(!en_cnt)
cnt_s_half <= 9'd0;
else if((cnt_ms == MCNT_MS) && (cnt_us == MCNT_US) && (cnt_s_half == MCNT_S_HALF))
cnt_s_half <= 9'd0;
else if((cnt_ms == MCNT_MS) && (cnt_us == MCNT_US))
cnt_s_half <= cnt_s_half + 9'd1;
else
cnt_s_half <= cnt_s_half;
//1s计数器
always@(posedge clk or negedge reset_n)
if(!reset_n)
cnt_s <= 10'd0;
else if(!en_cnt)
cnt_s <= 10'd0;
else if(s_done)
cnt_s <= 10'd0;
else if((cnt_ms == MCNT_MS) && (cnt_us == MCNT_US))
cnt_s <= cnt_s + 10'd1;
else
cnt_s <= cnt_s;
assign s_done =((cnt_ms == MCNT_MS) && (cnt_us == MCNT_US) && (cnt_s == MCNT_S));
2.设计状态机,实现三种状态的切换,需要注意的是,我们可以通过设计一个en_cnt使能信号,让每次状态切换,计数器都清零。
always@(posedge clk or negedge reset_n)
if(!reset_n)begin
en_cnt <= 1'd0;
state <= STATE_1;
LED <= 1'd1;
end
else begin
case(state)
STATE_1: begin
en_cnt <= 1'd1;
if(s_done)begin
state <= STATE_2;
en_cnt <= 1'd0;
end
else if(cnt_ms < cnt_s)
LED <= 1'd0;
else
LED <= 1'd1;
end
STATE_2: begin
en_cnt <= 1'd1;
LED <= 1'd0;
if((cnt_ms == MCNT_MS) && (cnt_us == MCNT_US) && (cnt_s_half == MCNT_S_HALF))begin
state <= STATE_3;
en_cnt <= 1'd0;
end
end
STATE_3: begin
en_cnt <= 1'd1;
if(s_done)begin
state <= STATE_1;
en_cnt <= 1'd0;
end
else if(cnt_ms < cnt_s)
LED <= 1'd1;
else
LED <= 1'd0;
end
default: begin
LED <= 1'd1;
state <= STATE_1;
en_cnt <= 1'd0;
end
endcase
end