verilog基础-状态机之FPGA独立按键消抖设计与验证(熟练testbench的写法)

独立按键消抖设计与验证

本实验主要是为了锻炼状态机的思维模式以及熟练掌握TB的写法
本节主要收获了:define的用法,另外就是,顶层的input在TB中是reg的真正含义,其实就是把激励当做寄存器来使了。

开发板:小梅哥AC620
软件:quartus 13.1

verilog基础-状态机之FPGA独立按键消抖设计与验证(熟练testbench的写法)_第1张图片
一般情况下抖动的总时间会持续20ms以内。

状态机的基本结构,下面是一个状态机的样例,我们只需要在以后模仿着写即可,下面程序不是我们的独立按键消抖程序,是我以前写的一个程序,基本上,我写状态机都是按照这种三段式的方法来写。
    /* 有限状态机,三过程块建模风格 ***************************************** */
    // 状态编码
    localparam IDLE  = 3'b001,
               DELAY = 3'b010,
               GENE  = 3'b100;
    
    reg [2:0] now_state = IDLE, next_state = IDLE;
    
    // 1.实现状态转换
    always @ (posedge clk) begin//: trans_state
        if (rst)
            now_state <= IDLE;
        else
            now_state <= next_state;
    end//: trans_state
    
    // 2.产生下一个状态
    always @ (*) begin//: set_next_state
        //next_state = now_state; // 下面分支的缺省状态
        case (now_state)
        IDLE  : if (valid )
							begin
                    if (delay=='b0)
                        next_state = GENE;
                    else
                        next_state = DELAY;
						  end
                else
                    next_state = IDLE;
        DELAY : if (delay_cnt >= delay)
                    next_state = GENE;
                else
                    next_state = DELAY;
        GENE  : if (nop_cnt >= nop)
                    next_state = IDLE;
                else
                    next_state = GENE;
		 default:
						next_state=IDLE;
        endcase
    end//: set_next_state
    
    // 3.产生状态机的输出值
    always @ (posedge clk) begin//: set_out_proc
        case (next_state)
        IDLE  : begin
                nop_cnt     <= 'b0;
                delay_cnt   <= 'b0;

                end
        DELAY : begin
                delay_cnt   <= delay_cnt + 1'b1;
                end
        GENE  : begin
                if (pulse_dec)
                    nop_cnt <= nop_cnt + 1'b1;
                else
                    nop_cnt <= nop_cnt;
                end
        default: ;
        endcase
    end//: set_out_proc

独立按键消抖程序

module key_detect
(
input clk,
input rst_n,
input key,
output led
);

reg key_n;
reg key_n_n;

reg [23:0]cnt_fall=0;//
reg [23:0]cnt_rise=0;

/*--------边沿检测部分---------*/
wire dectect_fall,dectect_rise;
always @ (posedge clk)
begin
key_n<=key;
key_n_n<=key_n;
end
assign dectect_fall=key_n_n&!key;//下降沿检测
assign dectect_rise=!key_n_n&key;//上升沿检测




localparam idle=0;//不按时候的空闲状态
localparam fall_shake=1;//按下时候的抖动状态
localparam fall_stable=2;//按下时候的稳定状态
localparam rise_shake=3;//释放时候的抖动状态

/*--------状态机部分---------*/
reg[2:0] state_next=idle;
reg [2:0] state_now=idle;

//参数化设计
localparam fall_shake_time=24'd10;//20ms的下降延抖动延时  10*20=200ns
localparam rise_shake_time=24'd10;//20ms的上升延抖动延时

//状态转移
always @ (posedge clk or negedge rst_n)
begin
		if(!rst_n)
		state_now<=idle;
		else
		state_now<=state_next;
end


//转移条件
always@ (*)
begin
		case(state_now)
			idle:
			begin
				if(dectect_fall)//如果检测到下降沿,那么就跳转到下降沿抖动状态
				state_next=fall_shake;
				else if(key)
				state_next=idle;
				else
				state_next=fall_stable;
			end
			
			fall_shake:
			begin
			
				if(cnt_fall

测试文件:
注意:测试由于我们的抖动20ms,太长了,对于仿真不方便,我们就把顶层的20ms,改成了200ns的抖动时间

`define clock_period 0.02
`timescale 1 us/ 1 ns
module key_detect_vlg_tst();
reg clk;
reg key;
reg rst_n;
                                               
wire led;

// assign statements (if any)                          
key_detect i1 (
// port map - connection between master ports and signals/registers   
	.clk(clk),
	.key(key),
	.led(led),
	.rst_n(rst_n)
);

initial
begin
clk=0;
rst_n=0;
key=1;
end

//定义时钟
always #(`clock_period/2) clk=~clk;

initial                                                
begin  
    #(`clock_period*10); 
	 rst_n=1;
    #(`clock_period*10); 
	 key=0;
    #(`clock_period*500); 
	 key=1;
	 #(`clock_period*10); 
	 key=0;
    #(`clock_period*5); 
	 key=1;
    #(`clock_period*500); 
	 $stop;
end  
                                                  
                                               
                                                  
endmodule

verilog基础-状态机之FPGA独立按键消抖设计与验证(熟练testbench的写法)_第2张图片

实际测试:
verilog基础-状态机之FPGA独立按键消抖设计与验证(熟练testbench的写法)_第3张图片

你可能感兴趣的:(verilog基础篇)