本人初学,看了教程后写的这个按键消抖程序,有个地方十分想不明白
module sw_debounce(
clk,rst_n,sw1_n,sw2_n,sw3_n,
led1_p,led2_p,led3_p
);
input clk;//时钟50M
input rst_n;//复位低有效
input sw1_n,sw2_n,sw3_n;//开关低有效
output led1_p,led2_p,led3_p;//LED灯高有效
reg [2:0] high1;
reg [2:0] high2;
always @(posedge clk or negedge rst_n)begin
if(!rst_n) high1<=3'b111;
else high1<={sw1_n,sw2_n,sw3_n};
end
always @(posedge clk or negedge rst_n)begin//前一个周期和后一个周期按键信息进行与操作
if(!rst_n) high2<=3'b111;
else high2<=high1;
end
wire [2:0]low_en=(~high1)&high2;//一旦检测到有震荡,low_en由0变为1
reg [19:0] cnt;
always @(posedge clk or negedge rst_n)begin
if(!rst_n) cnt<=20'h00000;
else if(low_en) cnt<=20'h00000;//一旦按键有震荡,计数器清0
else cnt<=cnt+1'b1;
end
reg [2:0] low1;
reg [2:0] low2;
always @(posedge clk or negedge rst_n)begin
if(!rst_n) low1<=3'b111;
else if(cnt==20'hfffff)low1<={sw1_n,sw2_n,sw3_n};//这里low1每当计数器数到20ms时保存下按键状态
end
always @(posedge clk or negedge rst_n)begin//这里low2每个周期保存下low1上个周期状态
if(!rst_n) low2<=3'b111;
else low2<=low1;
end
wire [2:0] led_en=(~low1[2:0])&low2[2:0];
reg led1_pn;
reg led2_pn;
reg led3_pn;
always @(posedge clk or negedge rst_n)begin
if(!rst_n)
begin
led1_pn<=0;
led2_pn<=0;
led3_pn<=0;
end
else
begin
if (led_en[2]) led1_pn<=~led1_pn;
if (led_en[1]) led2_pn<=~led2_pn;
if (led_en[0]) led3_pn<=~led3_pn;
end
end
assign led1_p=led1_pn?1:0;
assign led2_p=led2_pn?1:0;
assign led3_p=led3_pn?1:0;
endmodule
问题来了,就是红色字体部分,如果计数器cnt恰好数到20'hfffff的时候来了个低电平的杂波且少于20ms,那岂不是误触发了led_en导致LED翻转而点亮?
多谢了,分不多 |