RTL代码
module key(outdata,clk,rst_n,key_in); reg key_flag; reg key_state; input clk,rst_n; input key_in; output reg outdata; parameter S0=4'b0001,S1=4'b0010,S2=4'b0100,S3=4'b1000; reg [3:0] state,next_state; reg [19:0] cnt; reg cnt_en,cnt_full; reg key_in_a,key_in_b; reg key_in_c,key_in_d; wire pos,neg; always@(posedge clk) if(!rst_n) state<=S0; else state<=next_state; always@(posedge clk) begin if(!rst_n)begin cnt<=20'd0;end else begin if(cnt_en) begin if(cnt<20'd999999)begin cnt<=cnt+1;end else begin cnt_full<=1'b1;cnt<=20'd0;end end else begin cnt<=20'd0;end end end always@(posedge clk) begin if(!rst_n)begin key_in_a<=1'b0;key_in_b<=1'b0;end else begin key_in_a<=key_in;key_in_b<=key_in_a;end end always@(posedge clk) begin if(!rst_n)begin key_in_c<=1'b0;key_in_d<=1'b0;end else begin key_in_c<=key_in_b;key_in_d<=key_in_c;end end assign pos=key_in_c&(!key_in_d), neg=(!key_in_c)&(key_in_d); always@(posedge clk) begin if(!rst_n)begin cnt_en<=1'b0;key_flag<=1'b0;key_state<=1'b1;end else case(state) S0:begin key_flag<=1'b0; if(neg) begin next_state<=S1;cnt_en<=1'b1;end else begin next_state<=S0;end end S1:begin if(pos) begin next_state<=S0;cnt_en<=1'b0;end else if(cnt_full) begin next_state<=S2;cnt_en=1'b0;key_flag<=1'b1;key_state<=1'b0;end else begin next_state<=S1;end end S2:begin key_flag<=1'b0; if(pos) begin next_state<=S1;cnt_en=1'b1;end else next_state<=S1; end S3:begin if(cnt_full) begin key_flag<=1'b1; key_state<=1'b1; next_state<=S0; cnt_en<=1'b0; end else if(neg) begin next_state<=S2; cnt_en<=1'b0; end else begin next_state<=S3;end end endcase end always@(posedge clk) if(!rst_n) outdata<=1'b0; else if(!key_state&&key_flag) outdata<=~outdata; else outdata<=outdata; endmodule