赞
踩
- module fangdou#(parameter width=8,T100hz=249999)
- (input clk,
- input reset,
- input setd,
- input key,
- input[(width-1):0]data_in,
- output dout
- );
- integer cnt_100hz;
- reg clk_100hz;
- wire debkey;
- wire temp_out;
- always @(posedge clk or posedge reset)//对板子上面的时钟分频用于按键防抖
- if(reset)
- cnt_100hz<=32'b0;
- else
- begin
- cnt_100hz<=cnt_100hz+1'b1;
- if(cnt_100hz==T100hz)
- begin
- cnt_100hz<=32'b0;
- clk_100hz<=~clk_100hz;
- end
- end
- reg key_rrr,key_rr,key_r;
- always@(posedge clk_100hz or posedge reset)
- if(reset)
- begin
- key_rrr<=1'b1;
- key_rr<=1'b1;
- key_r<=1'b1;
- end
- else
- begin
- key_rrr<=key_rr;// key_rrr等于前两个时钟上升沿的 key值
- key_rr<=key_r;// key_rr等于前一个时钟上升沿的 key值
- key_r<=key;//key_r等于当前时钟上升沿的key,当按键抖动时
- end
- assign debkey=key_rrr & key_rr & key_r;//当且仅当key_rrr,key_rr,key_r都等于1的时候debkey才等与一
- //按键发生抖动难以满足三者同时为1的条件,所以可以有效进行防抖
- bing_to_chuan #(width) btc(.btn_clk(debkey),.reset(reset),.en(setd),.data_in(data_in),.dout(temp_out));
- /*调用bing_to_chuan模块,将输入的数据进行锁存。debkey为按动按键手动产生的时钟,每按一次按键产生一次上升沿。
- 每次按下按钮,bing_to_chuan模块就会截取一位锁存的数据传入zhuangtaiji模块,即完成对并行输入的数据,进行串行
- 检测的要求,按下按钮8次后才会将当前锁存的数据全部检测完*/
- zhuangtaiji ztj( .clk(debkey),.reset(reset),.din(temp_out),.dout(dout));
- //根据串行传入的数据进行检测1101序列的模块
- endmodule
- module bing_to_chuan#(parameter width=8)
- (input btn_clk,input reset,input en, input[(width-1):0]data_in, output reg dout);
- reg [(width-1):0] temp_d;
- always@(posedge en or posedge btn_clk or posedge reset)
- begin
- if(en)//en有效时传入数据,将数据锁存在temp_d中
- temp_d=data_in;
- else if(reset)//重置信号
- dout=1'b0;
- else
- begin
- dout=temp_d[0];
- temp_d={1'b0,temp_d[(width-1):1]};
- /*对信号进行移位,每当btn_clk到达上升沿,也即按下按钮,
- 取出temp_d的一位数据传入状态转换模块*/
- end
- end
- endmodule
- module zhuangtaiji(
- input clk, input reset, input din, output reg dout);
-
- parameter s0=3'b000;
- parameter s1=3'b001;
- parameter s2=3'b010;
- parameter s3=3'b011;
- parameter s4=3'b100;//状态声明
- reg [2:0] current_state,next_state;//现态与次态
- always@(posedge clk or posedge reset)
- begin
- if(reset)//重置
- begin
- current_state<=s0;
- end
- else
- current_state<=next_state;
- end
- always@(current_state or din or reset)//状态转换判断
- begin
- if(reset)//重置
- next_state=s0;
- else
- begin
- case(current_state)
- //对现态以及传入的数据进行判断后,确定次态
- //具体转换逻辑详见原理图
- s0:
- if(din==1'b1) next_state=s1; else next_state =s0;
- s1:
- if(din==1'b1) next_state=s2; else next_state =s0;
- s2:
- if(din==1'b0) next_state=s3; else next_state=s2;
- s3:
- if(din==1'b1) next_state=s4; else next_state=s0;
- s4:
- if(din==1'b1) next_state=s1; else next_state=s0;
- default: next_state=s0;
- endcase
- end
- end
- always@(reset or next_state)//判断输出
- begin
- if(reset)//重置
- dout=0;
- else
- begin
- if(next_state == s4)dout=1;
- //次态等于状态s4时,即检测到1101序列,输出信号赋值1
- else
- dout=0;
- //次态不等于状态s4说明未检测到序列1101,输出信号赋值0
- end
- end
- endmodule
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。