双非硕士 研一下学期视觉转FPGA(在b站跟小梅哥视频)
长路漫漫,但希望前途光明
按键抖动是按键在日常工作中,经常出现的现象,为了避免该现象,设计了一个按键抖动消除的实验。
代码内容如下
module key_filter(
Clk,
Reset_n,
Key,
// p_key_flag,
// n_key_flag,
key_flag,
key_state
);
input Clk;
input Reset_n;
input Key;
// output reg p_key_flag;
// output reg n_key_flag;
output key_flag;
output reg key_state;
//定义一个边沿检测寄存器
reg [1:0]r_key;
always@(posedge Clk)
begin
r_key[0] <= Key;
r_key[1] <= r_key[0];
end
//定义一个上升沿
wire p_edge;
assign p_edge = (r_key == 2'b01);
//定义一个下降沿
wire n_edge;
assign n_edge = (r_key == 2'b10);
reg p_key_flag;
reg n_key_flag;
assign key_flag = p_key_flag | n_key_flag;
//开始进行状态机的框架
reg [19:0]cnt;
reg [1:0]state;
always@(posedge Clk or negedge Reset_n)
if(!Reset_n)
begin
cnt <= 0;
state <= 0;
p_key_flag <= 0;
n_key_flag <= 0;
key_state <= 1'b1;
end
else
begin
case(state)
0:
begin
n_key_flag <= 1'b0;
if(n_edge == 1)
state <= 1;
else
state <= 0;
end
1:
begin
if(cnt >= 1000000 -1 )
begin
state <= 2;
p_key_flag <= 1;
key_state <= 0;
cnt <= 0;
end
else if (( (p_edge == 1) && (cnt < 1000000 - 1) ))
begin
state <= 0;
cnt <= 0;
end
else
begin
cnt <= cnt + 1'b1;
state <= 1;
end
end
2:
begin
p_key_flag <= 0;
if(p_edge == 1)
begin
state <= 3;
end
else
state <= 2;
end
3:
begin
if(cnt >= 1000000 - 1)
begin
n_key_flag <= 1;
state <= 0;
key_state <= 1;
cnt <= 0;
end
else if((cnt < 1000000 - 1 ) && (n_edge == 1) )
begin
state <= 2;
cnt <= 0;
end
else
begin
cnt <= cnt + 1'b1;
state <= 3;
end
end
endcase
end
endmodule
仿真代码内容如下:
`timescale 1ns / 1ps
module key_filter_tb();
reg Clk;
reg Reset_n;
reg Key;
// wire p_key_flag;
// wire n_key_flag;
wire key_flag;
wire key_state;
key_filter key_filter(
.Clk(Clk),
.Reset_n(Reset_n),
.Key(Key),
// .p_key_flag(p_key_flag),
// .n_key_flag(n_key_flag),
.key_flag(key_flag),
.key_state(key_state)
);
initial Clk = 1;
always#10 Clk = ~Clk;
initial begin
Reset_n = 0;
Key = 1;
#201;
Reset_n = 1;
#3000;
press_key(2);
$stop;
end
reg [31:0]rand;
task press_key;
input [3:0]seed;
begin
Key = 1;
#20000000;
repeat(5)begin
rand = {$random(seed)} % 10000000;//(0,9999999)
#rand Key = ~Key;
end
Key = 0;
#40000000;
repeat(5)begin
rand = {$random(seed)} % 10000000;//(0,9999999)
#rand Key = ~Key;
end
Key = 1;
#40000000;
end
endtask
endmodule
波形图如下: