Digital IC design study notes _ button debounce moduleOne

Digital IC design study notes

Key debounce module 1

1 原理图
2 Verilog 代码
3 Modelsim仿真

1. Schematic

Insert picture description here
(1). Key waveform diagram The
Insert picture description here
ideal key signal is between 0 and 1, which can be completed instantaneously; when the key is pressed, a jitter signal of a certain time range will be generated, and the duration of the jitter signal is set as 20ms.
(2). key_flag, key_state waveform diagram The
Insert picture description here
first waveform is the key signal key; the
second waveform is the key_flag signal, when the jitter waveform is filtered out, a single-cycle high pulse is generated; the
third waveform is the key_state signal, when filtering After removing the jitter waveform, it transforms into a waveform consistent with the key signal;
(3). State transition diagram
Insert picture description here

2 Verilog code

//----top module---------------------------------
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
//----asyn_key-->syn---------------------------------
	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---------------------------------------
//		always@(posedge clk or negedge rst_n)
//			if(!rst_n)
//				key_flag <= 0;
//			else if(cnt_full)
//				key_flag <= 1;
//			else
//				key_flag <= 0;
	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
//----------------------------------------------------
//----testbench--------------------------------------
`timescale 1ns/1ns
`define clock_period 20
module tb_fsm_key_filter;
	reg clk;
	reg rst_n;
	reg key;
	wire key_flag;
	wire key_state;
	
	fsm_key_filter uut(
		.clk(clk),
		.rst_n(rst_n),
		.key(key),
		.key_flag(key_flag),
		.key_state(key_state)
	);
	initial clk = 1;
	always #(`clock_period/2) clk = ~clk;
	
	initial begin
		rst_n = 0;
		key = 1;//before press
		#(`clock_period*10);
		rst_n = 1;
		#(`clock_period*1000000+1);
//-----------第一种testbench------------------
//-------------------------------------
//----first time-----------------------	
//----press--------------------
//  //---jitter------------
//		key = 0;
//		#1000;key = 1;
//		#2000;key = 0;
//		#1400;key = 1;
//		#2600;key = 0;
//		#1300;key = 1;
//		#20;  key = 0;
//  //---non jitter--------
//		#20000100;
//		#50000100;
-----------------------------
//
----release------------------
//  //---jitter------------
//		#1000;key = 1;
//		#2000;key = 0;
//		#1400;key = 1;
//		#2600;key = 0;
//		#1300;key = 1;
//	//---non jitter-------------
//		#20000100;
-------------------------------------
----second time----------------------	
----press--------------------
//  //---jitter------------
//		key = 0;
//		#1000;key = 1;
//		#2000;key = 0;
//		#1400;key = 1;
//		#2600;key = 0;
//		#1300;key = 1;
//		#20;  key = 0;
//  //---non jitter--------
//		#20000100;
//		#50000100;
-----------------------------
//
----release------------------
//  //---jitter------------
//		#1000;key = 1;
//		#2000;key = 0;
//		#1400;key = 1;
//		#2600;key = 0;
//		#1300;key = 1;
//	//---non jitter-------------
//		#20000100;		
//		
//-----------第二种testbench------------------
      press_key;
		#10000;
      press_key;
		#10000;
      press_key;
		#10000;		
		//#50000100;
		$stop;
	end
	reg [15:0] myrand;
	
	task press_key;
	begin
		repeat(50)begin
		myrand = {
    
    $random}%65536;//0~65535;
		#myrand; key = ~key;			
	   end
	   key = 0;
		#50000000;
		
		repeat(50)begin
		myrand = {
    
    $random}%65536;//0~65535;
		#myrand; key = ~key;			
	   end
	   key = 1;
		#50000000;
	   	
	end
	endtask
	
endmodule

Testbench: The
first type lists the excitation signals in detail, which is simple but the code is verbose; the
second type uses task, which generates the function $random randomly, and the code is simple; the
third type uses a simulation model, and a single module generates the excitation signal, which is mostly used for authentic memory. Models, etc.; (simulation models are generally provided by the government)

Insert picture description here

//----------------------------------------------------
//----第三种test bench--------------------------------------
`timescale 1ns/1ns
`define clock_period 20
module tb2_fsm_key_filter;
	reg clk;
	reg rst_n;
	wire key;
	wire key_flag;
	wire key_state;
	
	fsm_key_filter uut1(
		.clk(clk),
		.rst_n(rst_n),
		.key(key),
		.key_flag(key_flag),
		.key_state(key_state)
	);
	
	fsm_filter_model uut2(
		.key(key)
);
	
	initial clk = 1;
	always #(`clock_period/2) clk = ~clk;
	
	initial begin
		rst_n = 0;
		#(`clock_period*10);
		rst_n = 1;
		#(`clock_period*1000000+1);	
//		#50000100;
//		$stop;
	end
//----仿真模型-------------------------------
`timescale 1ns/1ns
module fsm_filter_model(
	output reg key
);
	reg [15:0] myrand;
	
	initial begin
		key = 1;//before press

      press_key;
		#10000;
      press_key;
		#10000;
      press_key;
		#10000;		
		//#50000100;
		$stop;
	end
		
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;
		#50000000;
	   	
	end
	endtask
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.
Insert picture description here

3 Modelsim simulation
Insert picture description here

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~~~

Guess you like

Origin blog.csdn.net/weixin_50722839/article/details/109626087