1 //源代码,因为在返回到空闲状态时没有清零
2 module key_filter(
3 clk,
4 reset_n,
5 key,
6 // key_p_flag,
7 // key_r_flag,
8 key_flag,
9 key_state
10 );
11 input clk;
12 input reset_n;
13 input key;
14 // output reg key_p_flag;
15 // output reg key_r_flag;
16 output key_flag;
17 output reg key_state;
18
19 reg key_p_flag;
20 reg key_r_flag;
21 assign key_flag = (key_p_flag | key_r_flag);
22
23 //定义两个寄存器来产生上升沿和下降沿。
24
25 reg [1:0] r_key;
26 always@(posedge clk)//利用位拼接来完成。
27 r_key <= {r_key[0],key};
28 // always@(posedge clk)begin
29 // r_key[0] <= key;
30 // r_key[1] <= r_key[0];
31 // end
32
33 //上升沿
34 wire pedge_key;
35 assign pedge_key = (r_key == 2'b01);
36
37 //下降沿
38 wire nedge_key;
39 assign nedge_key = (r_key == 2'b10);
40
41 //定义计数器
42 reg [19:0] cnt;
43
44
45 reg [1:0] state;
46 always@(posedge clk or negedge reset_n)
47 if(!reset_n)begin
48 state <= 0;
49 key_r_flag <= 0;
50 key_p_flag <= 0;
51 cnt <= 0;
52 key_state <= 1;
53 end
54 else begin
55 case(state)
56 0:
57 begin
58 key_r_flag <= 0;
59 if(nedge_key)
60 state <= 1;
61 else
62 state <= 0;
63 end
64 1:
65 if((pedge_key) &&(cnt < 1000000-1))begin
66 cnt <= 0;
67 state <= 0;
68 end
69 else if(cnt >= 1000000-1)begin
70 state <= 2;
71 cnt<=0;
72 key_p_flag <= 1;
73 key_state <= 0;
74 end
75 else begin
76 cnt <= cnt +1'b1;
77 state <= 1;
78 end
79 2:
80 begin
81 key_p_flag <= 0;
82
83 if(pedge_key)
84 state <= 3;
85 else
86 state <= 2;
87 end
88 3:
89 if((nedge_key) &&(cnt < 1000000-1))begin
90 state <= 2;
91 cnt <= 0;
92 end
93 else if(cnt >= 1000000-1)begin
94 state <= 0;
95 cnt <= 0;
96 key_r_flag <= 1;
97 key_state <= 1;
98 end
99 else begin
100 cnt <= cnt +1'b1;
101 state <= 3;
102 end
103 default:;
104 endcase
105 end
106
107 endmodule
108
109 //仿真代码tb2引入了随机数种子
110 `timescale 1ns / 1ps
111 module key_filter_tb2();
112 reg clk;
113 reg reset_n;
114 reg key;
115 // wire key_p_flag;
116 // wire key_r_flag;
117 wire key_flag;
118 wire key_state;
119 key_filter key_filter_inst0(
120 clk,
121 reset_n,
122 key,
123 // key_p_flag,
124 // key_r_flag,
125 key_flag,
126 key_state
127 );
128
129 initial clk = 1;
130 always #10 clk =! clk;
131 //按键抖动优化
132 initial begin
133 reset_n = 0;
134 key = 1;
135 #201;
136 reset_n =1;
137 #3000;
138 press_key(2);
139 $stop;
140 //模拟抖动
141 // key = 0;
142 // #20000;
143 // key = 1;
144 // #30000;
145 // key = 0;
146 // #20000;
147 // key = 1;
148 // #30000;
149 // key = 0;
150 // #50000000;
151
152 // key = 1;
153 // #30000;
154 // key = 0;
155 // #20000;
156 // key = 1;
157 // #30000;
158 // key = 0;
159 // #20000;
160 // key = 1;
161 // #50000000;
162 end
163
164 reg [31:0] rand;
165 // initial begin
166 // rand = {$random} %10000000;
167 // #rand key = ~key;
168
169 // end
170
171 task press_key;
172 input [3:0] seed;
173 begin
174 key = 1;
175 #20000000;
176 //按下按键
177 repeat(5)begin
178 rand = {$random(seed)} %10000000;
179 #rand key = ~key;
180 end
181 key = 0;
182 #40000000;
183 //释放按键
184 repeat(5)begin
185 rand = {$random(seed)} %10000000;
186 #rand key = ~key;
187 end
188 key = 1;
189 #40000000;
190
191 end
192 endtask
193 endmodule
2023-03-28 11:34:55