fpga verilog的按键消抖问题 5

书中有这样一段按键消抖程序modulekey_f2(clk,key,count1,count2);inputclk;input[3:0]key;outputreg[3:0... 书中有这样一段按键消抖程序
module key_f2(clk,key,count1,count2);
input clk;
input[3:0]key;
output reg[3:0]count1,count2;
reg[3:0] key_temp0,key_temp;
parameter s0=3'b001,
s1=3'b010,
s2=3'b100;
reg[2:0] current_state,next_state;
always@(posedge clk) //这个应该就是消抖程序,不过怎么都没看明白。
begin
key_temp<=key_temp0;
key_temp0<=key;
end
always@(posedge clk)
begin
current_state<=next_state;
end
always@(current_state)
case(current_state)
s0:next_state<=s1;
s1:if((key_temp[0]==0)&(key_temp==key_temp0)&(key_temp0!=key)) //if后的这段是什么意思,完全没有看懂呀。
next_state<=s2;
else next_state<=s1;

谁给我解释下
always@(posedge clk) begin
key_temp<=key_temp0;
key_temp0<=key;
end

s1:if((key_temp[0]==0)&(key_temp==key_temp0)&(key_temp0!=key))
这两段代码是什么意思呀?
展开
 我来答
萌神12UI47
2014-07-21 · TA获得超过175个赞
知道答主
回答量:120
采纳率:100%
帮助的人:101万
展开全部
module sw_debounce(
clk,rst_n,
sw1_n,sw2_n,sw3_n,
led_d1,led_d2,led_d3
);

input clk; //主时钟信号,50MHz
input rst_n; //复位信号,低有效
input sw1_n,sw2_n,sw3_n; //三个独立按键,低表示按下
output led_d1,led_d2,led_d3; //发光二极管,分别由按键控制

//---------------------------------------------------------------------------
reg[2:0] key_rst;

always @(posedge clk or negedge rst_n)
if (!rst_n) key_rst <= 3'b111;
else key_rst <= {sw3_n,sw2_n,sw1_n};

reg[2:0] key_rst_r; //每个时钟周期的上升沿将low_sw信号锁存到low_sw_r中

always @ ( posedge clk or negedge rst_n )
if (!rst_n) key_rst_r <= 3'b111;
else key_rst_r <= key_rst;

//当寄存器key_rst由1变为0时,led_an的值变为高,维持一个时钟周期
wire[2:0] key_an = key_rst_r & ( ~key_rst);

//---------------------------------------------------------------------------
reg[19:0] cnt; //计数寄存器

always @ (posedge clk or negedge rst_n)
if (!rst_n) cnt <= 20'd0; //异步复位
else if(key_an) cnt <=20'd0;
else cnt <= cnt + 1'b1;

reg[2:0] low_sw;

always @(posedge clk or negedge rst_n)
if (!rst_n) low_sw <= 3'b111;
else if (cnt == 20'hfffff) //满20ms,将按键值锁存到寄存器low_sw中 cnt == 20'hfffff
low_sw <= {sw3_n,sw2_n,sw1_n};

//---------------------------------------------------------------------------
reg [2:0] low_sw_r; //每个时钟周期的上升沿将low_sw信号锁存到low_sw_r中

always @ ( posedge clk or negedge rst_n )
if (!rst_n) low_sw_r <= 3'b111;
else low_sw_r <= low_sw;

//当寄存器low_sw由1变为0时,led_ctrl的值变为高,维持一个时钟周期
wire[2:0] led_ctrl = low_sw_r[2:0] & ( ~low_sw[2:0]);

reg d1;
reg d2;
reg d3;

always @ (posedge clk or negedge rst_n)
if (!rst_n) begin
d1 <= 1'b0;
d2 <= 1'b0;
d3 <= 1'b0;
end
else begin //某个按键值变化时,LED将做亮灭翻转
if ( led_ctrl[0] ) d1 <= ~d1;
if ( led_ctrl[1] ) d2 <= ~d2;
if ( led_ctrl[2] ) d3 <= ~d3;
end

assign led_d3 = d1 ? 1'b1 : 1'b0; //LED翻转输出
assign led_d2 = d2 ? 1'b1 : 1'b0;
assign led_d1 = d3 ? 1'b1 : 1'b0;

endmodule
百度网友de9133d
推荐于2017-05-22 · TA获得超过1283个赞
知道小有建树答主
回答量:918
采纳率:100%
帮助的人:321万
展开全部
always@(posedge clk) begin
key_temp<=key_temp0;
key_temp0<=key;
end
=============================
这一段因为用的是非阻塞幅值<=,这样在第一个时钟key的最新值只能传到key_temp0,等到下个周期才能传到key_temp那里。这样如果key的值不能持续超过两个时钟,那么就不可能出现key_temp=key的情况出现。这样就能达到消抖的作用。想必下文肯定有相关判定按键有无有效的语句。

====================================
s1:if((key_temp[0]==0)&(key_temp==key_temp0)&(key_temp0!=key))
这两段代码是什么意思呀?
====================================
if后面的这段意思只要条件同时满足:key_temp[0]==0、key_temp==key_temp0、key_temp0!=key
才会跳转到状态s2,否则回到s1的状态。
追问
always后接的
key_temp<=key_temp0;
key_temp0<=key;
end
这一段必然会让key_temp==key_temp0 ,key_temp0<=key 呀,这明显与s1的触发条件:key_temp==key_temp0、key_temp0!=key
不相等嘛。所以我感觉这样的话s1因为条件永远不会满足,而不会被触发的。
不知道我说的对不对,还请您指教啦!
追答
s1这个条件是可能满足的,这是因为key_temp0<=key用了非阻塞幅值,在同一个上升沿里面,上面的赋值影响不到下面的比较或者是赋值。如果你还不明白非阻塞幅值,那么我举个例子:
初始值a=0 ;b=1.
always @(posedge Clk)
b <= a;
a <= 1;
第一个上升沿,a=1,b=0.第二个上升沿,a=1,b=1.你可以看到第一个周期a、b始终(赋值前跟幅值后均不相等)都是不相等的。
本回答被网友采纳
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式