FPGA低级建模---按键去抖动

FPGA低级建模,原则上一个模块一个功能,如按键去抖动建模中,有两个模块。

1、detect_module 这个是按键检测模块,主要检测按键的高低电平变化,现在按键是按下还是释放。

2、delay_module 这个是滤波去抖模块,主要是防止按键或外界的抖动干扰。

综合后如下RTL图:

3、以下是建模的Verilog代码:

顶层模块:debounce_module

    


module debounce_module(
input iCLK,
input iRST_n,

input iPIN_In,
output oPIN_Out

);

wire H2L_Sig_W;
wire L2H_Sig_W;

delay_module u_delay_module(
.iCLK( iCLK ),
.iRST_n( iRST_n ),
.iH2L_Sig( H2L_Sig_W ),
.iL2H_Sig( L2H_Sig_W ),
.oPIN_Out( oPIN_Out )
);

detect_module u_detect_module(
.iCLK( iCLK ),
.iRST_n( iRST_n ),
.iKEY_In( iPIN_In ),
.oH2L_Sig( H2L_Sig_W ),
.oL2H_Sig( L2H_Sig_W )
);

endmodule

  

延时模块:delay_module


module delay_module(
input iCLK,
input iRST_n,

input iH2L_Sig,
input iL2H_Sig,

output oPIN_Out

);

/************************************************************************/
//50M系统晶振 50M*0.001 -1 = 49_999
parameter T1MS = 16'd49999;
/************************************************************************/

reg [15:0] Count1;
reg isEn;
reg isCount; //是否计数
reg [3:0] Count_MS;
reg rPin_Out;
reg [1:0] i;
//1ms 计数
always @(posedge iCLK or negedge iRST_n)
begin
if( !iRST_n )
Count1 <= 16'd0;
else if( isCount && (Count1 == T1MS ))
Count1 <= 16'd0;
else if( isCount )
Count1 <= Count1 + 1'b1;
else if( !isCount )
Count1 <= 16'd0;
end

//16ms 计数
always @( posedge iCLK or negedge iRST_n)
begin
if( !iRST_n )
Count_MS <= 4'd0;
else if( isCount && ( Count1 == T1MS ))
Count_MS <= Count_MS + 1'b1;
else if( !isCount )
Count_MS <= 4'd0;
end

//
always @( posedge iCLK or negedge iRST_n)
begin
if( !iRST_n ) begin
isCount <= 1'b0;
rPin_Out <= 1'b0;
i <= 2'd0;
end
else
case( i )
2'd0:
begin
if( iH2L_Sig ) i <= 2'd1;
else if( iL2H_Sig ) i <= 2'd2;
end
2'd1:
begin
if( Count1 == T1MS ) begin
isCount <=1'b0;
rPin_Out <= 1'b1;
i <= 2'd0;
end
else
isCount <= 1'b1;
end
2'd2:
begin
if( Count1 == T1MS ) begin
isCount <= 1'b0;
rPin_Out <= 1'b0;
i <= 2'd0;
end
else
isCount <= 1'b1;
end
endcase
end


assign oPIN_Out = rPin_Out;

endmodule

  

按键检测模块: detect_module


module detect_module(
input iCLK,
input iRST_n,

input iKEY_In,
output oH2L_Sig,
output oL2H_Sig

);

/************************************************************************/
//50M系统晶振 50M*0.0001 -1 = 4_999
parameter T100US = 11'd4999;
/************************************************************************/

reg [10:0] Count1;
reg iSEn;

//100us 计数
always @(posedge iCLK or negedge iRST_n)
begin
if( !iRST_n ) begin
Count1 <= 11'h0;
iSEn <= 1'b0;
end
else begin
if( Count1 == T100US )
iSEn <= 1'b1;
else
Count1 <= Count1 + 1'b1;
end
end


reg H2L_F1;
reg H2L_F2;
reg L2H_F1;
reg L2H_F2;

//判断是否有按键按下或释放
always @( posedge iCLK or negedge iRST_n)
begin
if( !iRST_n ) begin
H2L_F1 <= 1'b1;
H2L_F2 <= 1'b1;
L2H_F1 <= 1'b0;
L2H_F2 <= 1'b0;
end
else begin
H2L_F1 <= iKEY_In;
H2L_F2 <= H2L_F1;
L2H_F1 <= iKEY_In;
L2H_F2 <= L2H_F1;
end

end

assign oH2L_Sig = iSEn? ( H2L_F2 & !H2L_F1 ):1'b0;
assign oL2H_Sig = iSEn? ( !L2H_F2 & L2H_F1 ):1'b0;


endmodule

原文地址:https://www.cnblogs.com/mouou/p/5390898.html