Digital IC design study notes
Key debounce module 2
1 原理图
2 Verilog 代码
3 Modelsim仿真
1. Schematic
Experimental phenomenon:
Each time the button 0 is pressed, the display status of the 4 LEDs is increased by 1 in the binary addition format; each time the button 1 is pressed, the display status of the 4 LEDs is subtracted by 1 in the binary addition format.
2 Verilog code
//----top module---------------------------------
module fsm_key_filter_top(
input clk,
input rst_n,
input key0,
input key1,
output [3:0] led
);
wire key_flag0;
wire key_flag1;
wire key_state0;
wire key_state1;
led_ctrl uut_ctrl(
.clk(clk),
.rst_n(rst_n),
.key_flag0(key_flag0),
.key_state0(key_state0),
.key_flag1(key_flag1),
.key_state1(key_state1),
.led(led)
);
fsm_key_filter uut_filter0(
.clk(clk),
.rst_n(rst_n),
.key(key0),
.key_state(key_state0),
.key_flag(key_flag0)
);
fsm_key_filter uut_filter1(
.clk(clk),
.rst_n(rst_n),
.key(key1),
.key_state(key_state1),
.key_flag(key_flag1)
);
endmodule
//---------------------------------
//----抖动滤除模块------------------
module fsm_key_filter#(
parameter IDLE = 4'b0001,
parameter FILTER1 = 4'b0010,
parameter DOWN = 4'b0100,
parameter FILTER2 = 4'b1000
)
(
input clk, //50MHz 20us
input rst_n,
input key,
output key_flag,
output reg key_state
);
reg cnt_en;
reg cnt_full;
reg [19:0] cnt1;
//reg [19:0] cnt2;
reg [3:0] state;
reg key_syn1;
reg key_syn2;
reg key_reg1;
reg key_reg2;
wire pos_edge;
wire neg_edge;
always@(posedge clk or negedge rst_n)
if(!rst_n)begin
state <= IDLE;
cnt_en <= 1'b0;
end else
begin
case(state)
IDLE:
begin
if(neg_edge)begin
state <= FILTER1;
cnt_en <= 1'b1;
end else
begin
state <= IDLE;
cnt_en <= 1'b0;
end
end
FILTER1:
begin
if(cnt_full)//20ms
begin
state <= DOWN;
cnt_en <= 1'b0;
end
else if(pos_edge)
begin
state <= IDLE;
cnt_en <= 1'b0;
end else
begin
state <= FILTER1;
cnt_en <= cnt_en;
end
end
DOWN:
begin
if(pos_edge)begin
cnt_en <= 1'b1;
state <= FILTER2;
end else
begin
cnt_en <= 1'b0;
state <= DOWN;
end
end
FILTER2:
begin
if(cnt_full)
state <= IDLE;
else if(neg_edge)begin
cnt_en <= 1'b0;
state <= DOWN;
end
else
state <= FILTER2;
end
default: begin
state <= IDLE;
cnt_en <= 1'b0;
end
endcase
end
//----cnt--------------------------------------
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
cnt1 <= 20'd0;
else if(cnt_en)
cnt1 <= cnt1 + 20'd1;
else
cnt1 <= 20'd0;
end
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
cnt_full <= 1'b0;
else if(cnt1 == 20'd999_999)
cnt_full <= 1'b1;
else
cnt_full <= 1'b0;
end
//----异步信号key同步处理---------------------------------
always@(posedge clk or negedge rst_n)begin
if(!rst_n)begin
key_syn1 <= 1'b0;
key_syn2 <= 1'b0;
end else
begin
key_syn1 <= key;
key_syn2 <= key_syn1;
end
end
//----key edge detect--------------------------------
always@(posedge clk or negedge rst_n)begin
if(!rst_n)begin
key_reg1 <= 1'b0;
key_reg2 <= 1'b0;
end else
begin
key_reg1 <= key_syn2;
key_reg2 <= key_reg1;
end
end
assign neg_edge = (!key_reg1) & key_reg2;
assign pos_edge = key_reg1 & (!key_reg2);
//----key_flag---------------------------------------
assign key_flag = (cnt1 == 20'd999_999)? 1'b1:1'b0;
//----key_state--------------------------------------
always@(posedge clk or negedge rst_n)
if(!rst_n)
key_state <= 1;
else if(cnt_full)
key_state <= ~key_state;
else
key_state <= key_state;
endmodule
//-------------------------------------------------
//----LED灯控制模块--------------------------------
`timescale 1ns/1ns
module fsm_filter_model(
input press,
output reg key
);
reg [15:0] myrand;
initial begin
key = 1;//before press
end
always@(posedge press)
press_key;
task press_key;
begin
repeat(50)begin
myrand = {
$random}%65536;//{$random}%6553(0~65535);{random}%65536:(-65535~65535)
#myrand; key = ~key;
end
key = 0;
#50000000;
repeat(50)begin
myrand = {
$random}%65536;//0~65535;
#myrand; key = ~key;
end
key = 1;
#25_000_000;
end
endtask
endmodule
//----------------------------------------------------
//----按键信号发生模型--------------------------------
`timescale 1ns/1ns
module fsm_filter_model(
input press,
output reg key
);
reg [15:0] myrand;
initial begin
key = 1;//before press
end
always@(posedge press)
press_key;
task press_key;
begin
repeat(50)begin
myrand = {
$random}%65536;//{$random}%6553(0~65535);{random}%65536:(-65535~65535)
#myrand; key = ~key;
end
key = 0;
#50000000;
repeat(50)begin
myrand = {
$random}%65536;//0~65535;
#myrand; key = ~key;
end
key = 1;
#25_000_000;
end
endtask
endmodule
//----testbench-------------------------------
`timescale 1ns/1ns
`define clock_period 20
module tb_fsm_key_filter_top;
reg clk;
reg rst_n;
reg press0;
reg press1;
wire [3:0] led;
wire key0;
wire key1;
fsm_filter_model uut_model0(
.press(press0),
.key(key0)
);
fsm_filter_model uut_model1(
.press(press1),
.key(key1)
);
fsm_key_filter_top uut_top(
.clk(clk),
.rst_n(rst_n),
.key0(key0),
.key1(key1),
.led(led)
);
initial clk = 1;
always #(`clock_period/2) clk = ~clk;
initial begin
rst_n = 0;
press0 = 0;
press1 = 0;
#(`clock_period*10);
rst_n = 1;
#(`clock_period*10+1);
//----press0------------------------------
#80_000_000;
press0 = 1;//press
#(`clock_period*3);
press0 = 0;//release
#80_000_000;
press0 = 1;//press
#(`clock_period*3);
press0 = 0;//release
#80_000_000;
press0 = 1;//press
#(`clock_period*3);
press0 = 0;//release
#80_000_000;
press0 = 1;//press
#(`clock_period*3);
press0 = 0;//release
//----press1-------------------------------
#120_000_000;
press1 = 1;//press
#(`clock_period*3);
press1 = 0;//release
#80_000_000;
press1 = 1;//press
#(`clock_period*3);
press1 = 0; //release
#80000100;
$stop;
end
endmodule
endmodule
How to load the simulation model to the testbench?
(Quartus) Since the internal logic statements of the simulation model cannot be synthesized, the simulation model needs to be added to the testbench before the simulation, and press the operation to execute:
Assignment–> setting–>simulation–>1–>2–>3–>4 ,
And then perform RTL simulation.
3. Modelsim simulation
button model
The anode end of the led is connected to the power supply through a pull-up resistor. If the cathode end is connected to a low level (LED[3:0] is a low level), the led light is on; if the cathode end is connected to a high level LED[3:0], it is High level), the led light is off;
The original content of learning comes from Xiaomei Ge FPGA self-study notes
[Note]: Personal study notes, if there are any mistakes, please feel free to enlighten me. This is polite~~~