module Button(Clk,Rst,Sw1,Sw2,Led);// 模块接口
input Clk; // 时钟信号
input Rst; // 复位信号
input Sw1; // 按钮SW1输入,0表示按下,1表示抬起
input Sw2; // 按钮SW2输入
output [1 : 0] Led; // led 输出
/*
教程中的开发板是4 个LED,本开发板2 个LED 稍作修改
*/
reg [20 : 0]C1; //去抖动延时计时器C1
reg [20 : 0]C2; //去抖动延时计时器C2
reg [0 :0 ]Ledn; // 指示那个LED 输出
reg [1 :0 ]Led; //Led 输出
reg Sw1D,Sw1D1,Sw2D,Sw2D1; //同步延时中间信号
wire Sw1_IsDwon,Sw2_IsDwon;//标示按钮按下的信号
// 通过同步电路,实现判断按钮按下一次
// 当按钮按下前一个时钟Sw1D1=0,Sw1D=0,Sw1_IsDwon=0
// 挡按钮按下第一个时钟Sw1D1=0,Sw1D=1,Sw1_IsDwon=1
// 挡按钮按下第二个时钟Sw1D1=1,Sw1D=1,Sw1_IsDwon=0
assign Sw1_IsDwon = !Sw1D1 && Sw1D;
//按钮SW2 的同步信号和SW1 一样
assign Sw2_IsDwon = !Sw2D1 && Sw2D;
// 此模块把按钮按下的判断信号延时1个时钟
always @(posedge Clk ) begin
if( !Rst )begin //
Sw1D1 <= 1'b0;
Sw2D1 <= 1'b0;
end
else begin
Sw1D1 <= Sw1D;
Sw2D1 <= Sw2D;
end
end
always @(posedge Clk )
if( !Rst )begin
Sw1D <= 1'b0;
Sw2D <= 1'b0;
end
else begin
//如果C1[20] 为1 则Sw1D 置1 表示按钮按下
// 如果按钮按下,则必须等到C1=0 才置Sw1D 为0 表示按钮抬起
if( C1[ 20 ] ) Sw1D <= 1'b1;
else if( Sw1D && C1==0 ) Sw1D <=1'b0;
//按钮SW2 和SW1 一样
if( C2[ 20 ] ) Sw2D <= 1'b1;
else if( Sw2D && C2==0 ) Sw2D <=1'b0;
end
always @(posedge Clk )
if( !Rst )begin
C1 <= 21'd0;
C2 <= 21'd0;
end
else begin
// 如果按钮SW1 按下,则C1 开始计数,否则减计数,实现去抖动
if( !Sw1 ) begin
if( !C1[ 20 ] ) C1 <= C1 + 1'b1;
end
else if( C1 > 0 ) C1 <= C1 - 1'b1;
// 如果按钮SW2 按下,则C2 开始计数,否则减计数,实现去抖动
if( !Sw2 ) begin
if( !C2[ 20 ] ) C2 <= C2 + 1'b1;
end
else if( C2 > 0 ) C2 <= C2 - 1'b1;
end
//控制LED 的输出模块
//每次按下LED 后,LED 移动移位
//移动方向由按钮控制
always @( posedge Clk )
if(!Rst)begin
Ledn <= 1'd0;
Led <= 2'h0;
end
else begin
if( Sw1_IsDwon ) Ledn <= Ledn + 1'b1;
else if( Sw2_IsDwon ) Ledn <= Ledn - 1'b1;
Led <= 2'h0; //LED 0 灭掉
Led[Ledn] <= 1'b1; //LED 1 点亮
//有些开发板是0 点亮,1 灭掉
end
endmodule
上面是教程里的按键去抖程序,有点不理解,求大神帮忙介绍下这个去抖原理。
另外,
always @(posedge Clk )
if( !Rst )begin
C1 <= 21'd0;
C2 <= 21'd0;
end
else begin
// 如果按钮SW1 按下,则C1 开始计数,否则减计数,实现去抖动
if( !Sw1 ) begin
if( !C1[ 20 ] ) C1 <= C1 + 1'b1;
end
else if( C1 > 0 ) C1 <= C1 - 1'b1;
// 如果按钮SW2 按下,则C2 开始计数,否则减计数,实现去抖动
if( !Sw2 ) begin
if( !C2[ 20 ] ) C2 <= C2 + 1'b1;
end
else if( C2 > 0 ) C2 <= C2 - 1'b1;
end
这个always块里面,减计数,去抖是怎么实现的,为什么减计数就可以去抖,还有就是C1 >0,和上面!c2[20]有重合的部分,不理解。
|