文章目录
- 一、按键消抖概述
-
- 二、系统设计
-
- 三、代码实现
- 1、按键消抖模块(key_debounce)
- 2、呼吸灯模块(led_breath)
- 3、流水灯模块(led_waterfall)
- 4、按键控制模块
- 5、顶层文件
- 四、效果展示
- 五、仿真设计
-
一、按键消抖概述
1、为何要进行按键消抖
2、消抖的方式
二、系统设计
1、系统模块划分
按键和LED是不同的外设,这里划分模块时,可以将按键消抖设计为一个模块,LED控制设计为一个模块。当然,这个工程比较简单,可以将两者划分为一个模块。
2、系统时序图
三、代码实现
文件结构:
1、按键消抖模块(key_debounce)
module key_debounce(
input wire clk,
input wire rst_n,
input wire key_in,
output reg key_out
);
parameter TIME_DELAY = 1000_000;
reg [19:0] cnt_delay;
wire add_cnt;
wire end_cnt;
reg key_before;
reg key_now;
wire flag_fall;
reg flag_timing;
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
key_now <= 1'b1;
else
key_now <= key_in;
end
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
key_before <= 1'b1;
else
key_before <= key_now;
end
assign flag_fall = key_before & (~key_now);
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
flag_timing <= 1'b0;
else if (flag_fall)
flag_timing <= 1'b1;
else if (end_cnt)
flag_timing <= 1'b0;
end
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
cnt_delay <= 20'd0;
else if (add_cnt) begin
if (end_cnt)
cnt_delay <= 20'd0;
else
cnt_delay <= cnt_delay + 1'd1;
end
end
assign add_cnt = flag_timing;
assign end_cnt = ((cnt_delay==TIME_DELAY) && add_cnt);
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
key_out <= 1'b0;
else if (end_cnt)
key_out <= ~key_now;
else
key_out <= 1'b0;
end
endmodule
2、呼吸灯模块(led_breath)
module led_breath(
input wire clk,
input wire rst_n,
input wire flag_state_change,
output reg[3:0] led_b
);
parameter TIME_US = 50;
parameter TIME_MS = 1000;
parameter TIME_S = 1000;
reg [5:0] cnt_us;
reg [9:0] cnt_ms;
reg [9:0] cnt_s;
wire add_cnt_us;
wire end_cnt_us;
wire add_cnt_ms;
wire end_cnt_ms;
wire add_cnt_s;
wire end_cnt_s;
reg flag;
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
cnt_us <= 6'd0;
else if (flag_state_change)
cnt_us <= 6'd0;
else if (add_cnt_us) begin
if (end_cnt_us)
cnt_us <= 6'd0;
else
cnt_us <= cnt_us + 1'd1;
end
end
assign add_cnt_us = 1'b1;
assign end_cnt_us = ((cnt_us==TIME_US-1) && add_cnt_us);
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
cnt_ms <= 10'd0;
else if (flag_state_change)
cnt_ms <= 6'd0;
else if (add_cnt_ms) begin
if (end_cnt_ms)
cnt_ms <= 10'd0;
else if(end_cnt_us)
cnt_ms <= cnt_ms + 1'd1;
end
end
assign add_cnt_ms = 1'b1;
assign end_cnt_ms = ((cnt_ms==TIME_MS-1) && add_cnt_ms);
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
cnt_s <= 10'd0;
else if (flag_state_change)
cnt_s <= 6'd0;
else if (add_cnt_s) begin
if (end_cnt_s)
cnt_s <= 10'd0;
else if(end_cnt_ms)
cnt_s <= cnt_s + 1'd1;
end
end
assign add_cnt_s = 1'b1;
assign end_cnt_s = ((cnt_s==TIME_S-1) && add_cnt_s);
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
flag <= 1'b0;
else if (flag_state_change)
flag <= 1'b0;
else if(end_cnt_s)
flag <= ~flag;
end
integer i;
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
led_b <= 4'b0000;
else if (flag_state_change)
led_b <= 4'b0000;
else begin
led_b <= {4{(cnt_s > cnt_ms) ? ~flag : flag}};
end
end
endmodule
3、流水灯模块(led_waterfall)
module led_waterfall(
input wire clk,
input wire rst_n,
input wire flag_state_change,
output reg[3:0] led_w
);
parameter T_WATER = 25'd24_999_999;
reg [24:0] cnt_period;
wire add_cnt;
wire end_cnt;
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
cnt_period <= 25'd0;
else if (flag_state_change)
cnt_period <= 25'd0;
else if (add_cnt) begin
if (end_cnt)
cnt_period <= 25'd0;
else
cnt_period <= cnt_period + 1'd1;
end
end
assign add_cnt = 1'b1;
assign end_cnt = ((T_WATER==cnt_period) && add_cnt);
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
led_w <= 4'b0001;
else if (flag_state_change)
led_w <= 4'b0001;
else if (end_cnt)
led_w <= {led_w[2:0], led_w[3]};
else
led_w <= led_w;
end
endmodule
4、按键控制模块
module led_control(
input wire clk,
input wire rst_n,
input wire[1:0] key,
output reg[3:0] led
);
parameter WATERFALL_LIGHT = 0;
parameter BREATH_LIGHT = 1;
reg led_state = WATERFALL_LIGHT;
reg flag_state_change;
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
led_state <= WATERFALL_LIGHT;
else if (key[0]) begin
led_state <= WATERFALL_LIGHT;
flag_state_change = 1'b1;
end
else if (key[1]) begin
led_state <= BREATH_LIGHT;
flag_state_change = 1'b1;
end
else begin
led_state <= led_state;
flag_state_change <= 1'b0;
end
end
wire[3:0] led_w;
wire[3:0] led_b;
led_waterfall u_led_waterfall(
.clk (clk),
.rst_n (rst_n),
.flag_state_change (flag_state_change),
.led_w (led_w)
);
led_breath u_led_breath(
.clk (clk),
.rst_n (rst_n),
.flag_state_change (flag_state_change),
.led_b (led_b)
);
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
led <= 4'b1111;
else if (led_state == WATERFALL_LIGHT)
led <= led_w;
else if (led_state == BREATH_LIGHT)
led <= led_b;
else
led <= led;
end
5、顶层文件
module led_control_top(
input wire clk,
input wire rst_n,
input wire[1:0] key_in,
output wire[3:0] led
);
wire [1:0] key;
key_debounce k0(
.clk (clk),
.rst_n (rst_n),
.key_in (key_in[0]),
.key_out (key[0])
);
key_debounce k1(
.clk (clk),
.rst_n (rst_n),
.key_in (key_in[1]),
.key_out (key[1])
);
led_control u_led_control(
.clk (clk),
.rst_n (rst_n),
.key (key),
.led (led)
);
endmodule
四、效果展示
五、仿真设计
1、仿真文件
`timescale 1ns/1ps
module led_control_top_tb;
reg tb_clk;
reg tb_rst_n;
reg [1:0] tb_key_in;
wire [3:0] tb_led;
parameter CYCLE = 20;
defparam test_led_control_top.k0.TIME_DELAY = 10;
defparam test_led_control_top.k1.TIME_DELAY = 10;
defparam test_led_control_top.u_led_control.u_led_breath.TIME_US = 5;
defparam test_led_control_top.u_led_control.u_led_breath.TIME_MS = 5;
defparam test_led_control_top.u_led_control.u_led_breath.TIME_S = 5;
defparam test_led_control_top.u_led_control.u_led_waterfall.T_WATER = 5;
always #(CYCLE/2) tb_clk = ~tb_clk;
integer i,j;
initial begin
tb_clk = 1'b1;
tb_rst_n = 1'b0;
tb_key_in = 2'b11;
#(CYCLE * 10);
tb_rst_n = 1'b1;
#(CYCLE * 100);
for (i=0 ;i<5; i=i+1) begin
tb_key_in[1] = {$random};
j = {$random}%20;
#(CYCLE * j);
end
tb_key_in = 2'b11;
#(CYCLE *120);
for(i= 0; i<5; i=i+1) begin
tb_key_in[0] = {$random};
j = {$random}%20;
#(CYCLE * j);
end
tb_key_in = 2'b11;
#(CYCLE *120);
$stop;
end
led_control_top test_led_control_top(
.clk (tb_clk),
.rst_n (tb_rst_n),
.key_in (tb_key_in),
.led (tb_led)
);
endmodule
2、波形图
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)