安德鲁

[笔记].一种独立键盘消抖的Verilog写法.[Verilog]

0
阅读(9720)

图1 KEY原理图


图2 LED原理图

key_led.v


01 modulekey_led(
02 inputCLOCK_50,
03 inputQ_KEY,
04 input[4:1] KEY,
05 outputreg[4:1] LED
06 );
07
08 //++++++++++++++++++++++++++++++++++++++
09 // 获取键值 开始
10 //++++++++++++++++++++++++++++++++++++++
11 wire[4:1] key_val;// 键值
12
13 key_debounce u0(
14 .i_clk (CLOCK_50),
15 .i_rst_n (Q_KEY),
16 .i_key (KEY),
17 .o_key_val (key_val)// 按下为0,松开为1
18 );
19 //--------------------------------------
20 // 获取键值 结束
21 //--------------------------------------
22
23
24 //++++++++++++++++++++++++++++++++++++++
25 // 按下键后开关LED 开始
26 //++++++++++++++++++++++++++++++++++++++
27 always@ (posedgeCLOCK_50,negedgeQ_KEY)
28 if(!Q_KEY)
29 LED <=4'hF;// 0灭1亮
30 else
31 case(1'b0)
32 key_val[1] : LED[1] <= ~LED[1];
33 key_val[2] : LED[2] <= ~LED[2];
34 key_val[3] : LED[3] <= ~LED[3];
35 key_val[4] : LED[4] <= ~LED[4];
36 default: LED <= LED ;// 缺省亮灭情况不变
37 endcase
38 //--------------------------------------
39 // 按下键后开关LED 结束
40 //--------------------------------------
41
42 endmodule

key_debounce.v


01 module key_debounce(
02 input i_clk,
03 input i_rst_n,
04 input [4:1] i_key,// 按下为0,松开为1
05 output reg [4:1] o_key_val// 键值
06 );
07
08 //++++++++++++++++++++++++++++++++++++++
09 reg [4:1] key_samp1, key_samp1_locked;
10
11 // 将i_key采集至key_samp1
12 always @ (posedge i_clk, negedge i_rst_n)
13 if(!i_rst_n)
14 key_samp1 <= 4'hF;
15 else
16 key_samp1 <= i_key;
17
18 // 将key_samp1锁存至key_samp1_locked
19 always @ (posedge i_clk, negedge i_rst_n)
20 if(!i_rst_n)
21 key_samp1_locked <= 4'hF;
22 else
23 key_samp1_locked <= key_samp1;
24 //--------------------------------------
25
26 //++++++++++++++++++++++++++++++++++++++
27 wire [4:1] key_changed1;
28
29 // 当key_samp1由1变为0时
30 // key_changed1由0变为1,只维持一个时钟周期
31 assign key_changed1 = key_samp1_locked & (~key_samp1);
32 //--------------------------------------
33
34
35 //++++++++++++++++++++++++++++++++++++++
36 reg [19:0] cnt;
37
38 // 一旦有按键按下,cnt立即被清零
39 always @ (posedge i_clk, negedge i_rst_n)
40 if(!i_rst_n)
41 cnt <= 20'h0;
42 elseif(key_changed1)
43 cnt <= 20'h0;
44 else
45 cnt <= cnt + 1'b1;
46 //--------------------------------------
47
48
49 //++++++++++++++++++++++++++++++++++++++
50 reg [4:1] key_samp2, key_samp2_locked;
51
52 // 只有当按键不变化(不抖动),且维持20ms以上时
53 // 才将i_key采集至key_samp2
54 always @ (posedge i_clk, negedge i_rst_n)
55 if(!i_rst_n)
56 key_samp2 <= 4'hF;
57 elseif(cnt == 20'hF_FFFF)// 0xFFFFF/50M = 20.9715ms
58 key_samp2 <= i_key;
59
60 // 将key_samp2锁存至key_samp2_locked
61 always @ (posedge i_clk, negedge i_rst_n)
62 if(!i_rst_n)
63 key_samp2_locked <= 4'hF;
64 else
65 key_samp2_locked <= key_samp2;
66 //--------------------------------------
67
68 //++++++++++++++++++++++++++++++++++++++
69 wire [4:1] key_changed2;
70
71 // 当key_samp2由1变为0时
72 // key_changed2由0变为1,只维持一个时钟周期
73 assign key_changed2 = key_samp2_locked & (~key_samp2);
74 //--------------------------------------
75
76
77 //++++++++++++++++++++++++++++++++++++++
78 // 每次按键稳定后,输出键值
79 // 按下为0,松开为1
80 always @ (posedge i_clk, negedge i_rst_n)
81 if(!i_rst_n)
82 o_key_val <= 4'hF;
83 else
84 o_key_val <= ~key_changed2;
85 //--------------------------------------
86
87 endmodule
Baidu
map