用verilog实现去抖动电路(状态机实现)

题目:用Verilog实现按键抖动消除电路,抖动小于20ms,输入时钟10MHz。

按键在按下的时候会有抖动特点,如果不加以处理,可能会被识别为多次按下,所以要设计去抖动电路。

去抖动电路的核心思想就是通过计数器去计时,在按键按下的时候开始计数,当达到计数阈值时,再次判断当前的按键输入,如果开始和结束时一样,则判断为按键已按下,所以中间的时间段(本题为20ms)内不论按键发生了什么变化都无所谓

 本次程序是我第二次使用状态机实现,当然也可以不用状态机(上一次使用状态机是序列检测)

电路共四个状态:

state1:清零状态  ;state2:计数状态 ; state3:计数完成检测输入是否变化 ;state4 :成功状态

状态转移图:

 

verilog代码:

`define DELAY_TIME 20 //ms
`define CLK_FREQUENCY 10 // Mhz

module debounce(
input clk,rst_n,din,
output pdge,ndge,
output reg dout,
output reg [1:0]current_state,
output reg [1:0]next_state,
reg [17:0] cnt//用来计数
);

parameter n_cnt = 1000*`CLK_FREQUENCY *`DELAY_TIME;//需要查的时钟个数,本题中为200,000个

parameter STATE1 = 2'b00;//状态1
parameter STATE2 = 2'b01;//状态2
parameter STATE3 = 2'b10;//状态3
parameter STATE4 = 2'b11;//状态4



reg din0, din1;//输入同步缓冲

assign pdge = (~din1) & din0;
assign ndge = (~din0) & din1;

always@(posedge clk,negedge rst_n)//输入同步缓冲
begin
	if(!rst_n)
	begin
		din0 <= 0;
		din1 <= 0;
	end
	else
	begin
		din0 <= din;
		din1 <= din0;
	end	
end

always@(posedge clk,negedge rst_n)//状态机第一段
begin
	if(!rst_n)
	begin
		current_state <= 0;
		next_state <= 0;
	end
	else
	begin
		current_state <= next_state;
	end	
end

always@(posedge clk,negedge rst_n)//状态机第二段
begin
	if(!rst_n)
	begin
		cnt <= 0;
		next_state <= STATE1;
	end
	else
	begin
		case(next_state)
		STATE1:
			if(pdge == 1)next_state <= STATE2;
			else next_state <= next_state;
		STATE2:
			if(cnt == n_cnt)next_state <= STATE3;
			else cnt <= cnt + 1;
		STATE3:
			if(din1 == 1)next_state <= STATE4;
			else 
			begin
				next_state <= STATE1;
				cnt <= 0;
			end
		STATE4:
			if(din1 == 0)
			begin
				next_state <= STATE1;
				cnt <= 0;
			end
			else next_state <= next_state;
		default: next_state <= next_state;
		endcase
	end	
end


always@(posedge clk,negedge rst_n)//状态机第三段
begin
	if(!rst_n)
	begin
		dout <= 0;
	end
	else
	begin
		if(current_state == STATE4)dout <= 1;
		else dout <= 0;
	end	
end



endmodule

testbench:

`timescale 10ns/10ns
module debounce_tb;

reg DIN, CLK, RST_N;
wire  PDGE,NDGE,DOUT;
wire [1:0] CURRENT_STATE;
wire [1:0] NEXT_STATE;
wire [17:0] CNT;//用来计数

integer i,j;


debounce U_debounce(
.clk(CLK), 
.rst_n(RST_N), 
.din(DIN), 
.dout(DOUT),
.pdge(PDGE),
.ndge(NDGE),
.current_state(CURRENT_STATE),
.next_state(NEXT_STATE),
.cnt(CNT)
);


initial
	begin
		CLK = 0;
		RST_N = 1;
		#6 RST_N = 0;
		#6 RST_N = 1;
		for(j = 0; j<10000000; j = j+1)
			begin
			#5 CLK = ~CLK;
			end	
	end
	
	
initial
begin	
	DIN = 0;
	for(i = 0; i<4; i = i+1)
	begin
        DIN = 1;
		#4000000 DIN = 0;
		#800000 DIN = 1;
		#800000 DIN = 0;
		#8000000;
	end
end

endmodule

仿真结果:

 

 

 

 

 

  • 4
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
FPGA(Field Programmable Gate Array)是一种可编程的逻辑电路,能够根据用户的需求进行编程来实现特定的电路功能。按键编码电路是一种将按键输入转换为二进制编码输出的电路。 首先,在FPGA上设计按键编码电路需要确定按键的数量和排列方式。接下来,利用FPGA的开发工具,使用硬件描述语言(HDL)如Verilog或VHDL编写按键编码电路的逻辑代码。 按键编码电路主要包括三个部分:输入部分、编码部分和输出部分。在输入部分,FPGA的引脚被配置为输入模式,将按键连接到FPGA的引脚上。在编码部分,使用状态机或组合逻辑的方式来进行按键的编码,将按键输入转换为相应的二进制编码。在输出部分,FPGA的引脚被配置为输出模式,将编码结果通过引脚输出。 在按键编码电路的设计中,需要考虑去抖动问题。去抖动是指由于按键机械特性引起的电气信号抖动现象。可以通过加入延时电路或使用触发器等方法来解决去抖动问题。 设计按键编码电路时,还需要根据实际需求对编码方式进行选择。常见的编码方式包括二进制编码、格雷码编码和BCD编码等。可以根据具体情况选择最适合的编码方式。 最后,使用FPGA的开发工具进行综合、布局和生成比特流文件。然后将比特流文件下载到FPGA芯片中,实现按键编码电路的功能。 总而言之,通过使用FPGA的可编程性和强大的逻辑功能,我们可以实现按键编码电路,将按键输入转换为二进制编码输出。这种设计具有灵活性和可扩展性,并可以根据实际需求进行调整和修改。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值