按键实验

参照《VerilogHDL那些事儿-建模篇》的消抖实验,完成了按键按下灯亮放开灯灭的效果。

源码基本是参照书上敲的:

//=======================================================
//  This code is generated by Terasic System Builder
//=======================================================

module myButton(

    //////////// CLOCK //////////
    CLOCK_50,
    RSTn,

    //////////// LED //////////
    LEDG,
    LEDR,

    //////////// KEY //////////
    KEY 
);
//=======================================================
//  PORT declarations
//=======================================================

//////////// CLOCK //////////
input                          CLOCK_50;
input                          RSTn;

//////////// LED //////////
output             [8:0]        LEDG;
output            [17:0]        LEDR;

//////////// KEY //////////
input             [3:0]        KEY;
//=======================================================
//  Structural coding
//=======================================================


//===========电平检测模块============
parameter    T100US = 11'd4999;
reg    [10:0]    Count1;
reg isEn;
//电平检测不稳定需延时100US
always @ (posedge CLOCK_50 or negedge RSTn)
    if(!RSTn)
        begin    
            Count1 <= 11'd0;
            isEn <=1'b0;
        end
    else if(Count1==T100US)
        isEn <= 1'b1;
    else
    Count1 <= Count1 + 1'b1;

//检测按键状态    
reg    H2L_F1;
reg    H2L_F2;
reg    L2H_F1;
reg    L2H_F2;

always @ (posedge CLOCK_50 or negedge RSTn)
    if(!RSTn)
        begin    
            H2L_F1 <= 1'b1;
            H2L_F2 <= 1'b1;
            L2H_F1 <= 1'b0;
            L2H_F2 <= 1'b0;
        end
    else 
        begin
            H2L_F1 <= KEY[3];
            H2L_F2 <= H2L_F1;
            L2H_F1 <= KEY[3];
            L2H_F2 <= L2H_F1;
        end

wire H2L_Sig;        
wire L2H_Sig;    
assign    H2L_Sig = isEn ? (H2L_F2 & !H2L_F1) : 1'b0;
assign    L2H_Sig = isEn ? (!L2H_F2 & L2H_F1) : 1'b0;


//=============消抖模块===============

parameter    T1MS = 16'd49_999;
reg    [15:0]    Count2;
reg    [3:0]    Count_MS;
//延时1MS
always @ (posedge CLOCK_50 or negedge RSTn)
    if(!RSTn)
        Count2 <= 16'd0;
    else if(isCount && Count2==T1MS)
        Count2 <= 16'd0;
    else if(isCount)
        Count2 <= Count2 + 1'b1;
    else if(!isCount)
        Count2 <= 16'd0;
        
always @ (posedge CLOCK_50 or negedge RSTn)
    if(!RSTn)
        Count_MS <= 4'd0;
    else if(isCount && Count2==T1MS)
        Count_MS <= Count_MS + 1'b1;
    else if(!isCount)
        Count_MS <= 4'd0;

reg    isCount;        
reg    Pin_Out;        
reg    [1:0]    i;

always @ (posedge CLOCK_50 or negedge RSTn)
    if(!RSTn)
        begin    
            isCount <= 1'b0;
            Pin_Out <= 1'b0;
            i <= 2'd0;
        end
    else
        case(i)
            2'd0:
            if(H2L_Sig)    i <= 2'd1;
            else if(L2H_Sig)    i<= 2'd2;
            
            2'd1:
            if(Count_MS == 4'd10) begin
                isCount <= 1'b0;
                Pin_Out <= 1'b1;
                i <= 2'd0;
                end
            else    isCount <= 1'b1;

            2'd2:
            if(Count_MS == 4'd10) begin
                isCount <= 1'b0;
                Pin_Out <= 1'b0;
                i <= 2'd0;
                end    
            else    isCount <= 1'b1;
        endcase
        
assign    LEDR[17] = Pin_Out;


endmodule
原文地址:https://www.cnblogs.com/fengyanlover/p/5035879.html