老师给了我一个任务。这个是其中的一个模块——长短按键识别。就是说,我按着按键短点,可以实现功能1;按着久点,可以实现功能2。初学Verilog,有很多不懂,编写过程稍微吃力。以前用C很好写,但是用Verilog感觉就不同了。所以我第一个想法就是直接用状态机,但是新学,编起来有点乱,思维绞死。然后果断放弃,改用另个——直接计数,按键按下开始计数,再识别按键释放时的计数。想法不错,嘿嘿,然后感觉可行。可编到一半,又有点晕了。不习惯并行思维。于是在这个基础上,加了状态机。果断,行。嘿嘿。。。。终于搞掂。
虽然已经出来了,但是感觉还是有点问题的,希望前辈能稍微指点迷津。嘿嘿。
module key(clk,reset,key_in,STOP_RUN,RST,CONFIG); input clk; input reset; input key_in; output reg RST; //复位信号RST ,高电平有效 output reg STOP_RUN; //停车态或行车态 output reg CONFIG; //CONFIG=1,表示进入设置状态 reg [2:0] CURRENT_STATE,NEXT_STATE; //当前状态,下一个状态 parameter S0=3'b000,S1=3'b001,S2=3'b010,S3=3'b011,S4=3'b100; //状态机编码 //********************************************** always@(posedge clk or negedge reset) if(!reset) CURRENT_STATE <= S0; else CURRENT_STATE <= NEXT_STATE; //********************************************** reg[19:0] cnt; //分频计数器 always@(posedge clk or negedge reset) begin if(!reset) cnt<=20'd0; else if(cnt==20'd50_000) cnt<=20'd0; //计数50_000个时钟 else cnt<=cnt+20'd1; end //********************************************** reg [9:0] count; // always@(posedge clk or negedge reset) begin if(!reset) begin NEXT_STATE<=S0; STOP_RUN <= 1'b0; //停车态 RST <= 1'b0; CONFIG <= 1'b0; end else if(cnt==20'd49_999) //10ms扫描一次 begin case(NEXT_STATE) S0: begin if(key_in==0) NEXT_STATE<=S1; else begin count <= 10'd0; //NEXT_STATE<=S0; //STOP_RUN <= 1'b0; //RST <= 1'b0; end end S1: begin if(key_in==0) begin if(count>=10'd200) //按键按下的时间超过2s,跳转下个状态 NEXT_STATE<=S2; else // count <= count + 10'd1; end else begin if(count>=10'd3) //30ms begin STOP_RUN <= ~STOP_RUN; //行车态 count <= 10'd0; NEXT_STATE<=S0; end else //按键有按下,但时间太短,不允响应,跳转S0 NEXT_STATE<=S0; end end S2: begin if(key_in==0) begin if(count>=10'd400) NEXT_STATE<=S3;//按键按下的时间超过4s,跳转下个状态 else count <= count + 10'd1; end else begin if(count>=10'd300) begin RST <= ~RST; count <= 10'd0; NEXT_STATE<=S0; end else //按键有按下,但时间不足3s,不允响应,跳转S0 NEXT_STATE<=S0; end end S3: begin if(key_in==0) begin if(count>=10'd800) NEXT_STATE<=S4; //按键按下的时间超过8s,跳转下个状态 else count <= count + 10'd1; end else begin if(count>=10'd500) begin CONFIG <= ~CONFIG; count <= 10'd0; NEXT_STATE<=S0; end else //按键有按下,但时间不足5s,不允响应,跳转S0 NEXT_STATE<=S0; end end S4: begin if(key_in==0) //按键一直没有释放,一直处于S4 NEXT_STATE <= S4; else //按键释放,跳转S0 NEXT_STATE <= S0; end /**/ default: NEXT_STATE <= S0; endcase end else ; end endmodule