探索flutter框架开发的app在移动应用市场的潜力与挑战
1099
2022-11-22
[笔记]再笔记--边干边学Verilog HDL --003
lab03 消抖模块之一
本实验是一个简单的按键消抖。主要由电平检测和10ms延时2个模块组成。
以前,知道按键要消抖,但一直没做过。究其原因,可能是觉得麻烦,效果不炫,悲哀。无论如何,“出来混,总要还的”。咋消抖呢?大大们说,先检测电平变化,再将确定的变化延时输出。说起来简单,其中还有些小九九:
1> 消的是什么抖?
首先,要搞清楚,“抖”(跳变)是从哪里来的,最开始,我们的常识:按下按键,电平就变了。假设是由高变低。事实上,在按下的过程中,由于,按键大多是机械结构,就会产生轻微的跳变,瞬间(us级)跳变n次。也就是说这个瞬间,电平不是那么“干净”,所以就有了消抖的需求:期颐得到“干净”、确定的电平。这要求真不高,只是,俺以前直接无视了。
2> 咋消?
接着上面的按键的动作说,既然电平瞬间就由高变为我们要的低,那么,消抖就要在这个瞬间完成。首先,要知道按键想得到一个什么样的电平,就需要检测电平,而前面说了,电平有段时间是抖动的,干脆从100us之后开始检测,这样就忽略了抖动,(至于这100us是咋来的,科学吗?不晓得,做实验测试,还OK)。检测电平之后,判断出是高变低还是低变高,这个判断有需要很短的时间(ns级),然后,就是稳定的电平了,至此,我们得到了电平的确切变化动作,再加上一个延时模块,包含判断电平变化的时间,也就是akuei2说的“过滤”。这里用的10ms,够吗,当然够,为啥是10ms,不晓得,不过同样,实验可以验证。
3> 设计思路
(1)一旦检测到按键按下(高电平到低电平变化),“电平检查模块”就会拉高H2L_sig电平,然后拉低。
(2)“10ms延迟模块”,检测到H2L_sig高电平,就会利用10ms过滤H2L_sig, 拉高输出。
(3)当按键释放,“电平检测模块”会拉高L2H_sig电平,然后拉低。
(4)“10ms延迟模块”检查到L2H_sig就会利用10ms过滤L2H_sig,然后拉低输出。
1 /**2 * File name: detect_mocule.v3 *4 */56 module detect_module7 (8 clk, rst_n, pin_in, H2L_sig, L2H_sig9 );1011 input clk;12 input rst_n;13 input pin_in;14 output H2L_sig;15 output L2H_sig;1617 parameter T100US = 13'd5000-1;1819 reg [12:0] count;20 reg isEn;2122 always @(posedge clk or negedge rst_n)23 if (!rst_n)24 begin25 count <= 13'd0;26 isEn <= 1'b0;27 end28 else if (count == T100US)29 isEn <= 1'b1;30 else31 count <= count + 1'b1;3233 reg H2L_F1;34 reg H2L_F2;35 reg L2H_F1;36 reg L2H_F2;3738 always @(posedge clk or negedge rst_n)39 if (!rst_n)40 begin41 H2L_F1 <= 1'b1;42 H2L_F2 <= 1'b1;43 L2H_F1 <= 1'b0;44 L2H_F2 <= 1'b0;45 end46 else47 begin48 H2L_F1 <= pin_in;49 H2L_F2 <= H2L_F1;50 L2H_F1 <= pin_in;51 L2H_F2 <= L2H_F1;52 end5354 assign H2L_sig = isEn ? (H2L_F2 & !H2L_F1) : 1'b0;55 assign L2H_sig = isEn ? (!L2H_F2 & L2H_F1) : 1'b0;5657 endmodule58
这里isEn = 1寄存器是表示100us的延迟完成。电平检测模块的有效是发生在100us之后。
复制代码1 /**2 * File name: delay_mocule.v3 *4 */56 module delay_module7 (8 clk, rst_n, H2L_sig, L2H_sig, pin_out9 );1011 input clk;12 input rst_n;13 input H2L_sig;14 input L2H_sig;15 output pin_out;1617 parameter T1MS = 16'd50_000 - 1;1819 reg [15:0] count;2021 always @(posedge clk or negedge rst_n)22 if (!rst_n)23 count <= 16'd0;24 else if (isCount && count == T1MS)25 count <= 16'd0;26 else if (isCount)27 count <= count + 1'b1;28 else if (!isCount)29 count <= 16'd0;3031 reg [3:0] count_ms;3233 always @(posedge clk or negedge rst_n)34 if (!rst_n)35 count_ms <= 4'd0;36 else if (isCount && count == T1MS)37 count_ms <= count_ms + 1'b1;38 else if (!isCount)39 count_ms <= 4'd0;4041 reg isCount;42 reg rpin_out;43 reg [1:0] i;4445 always @(posedge clk or negedge rst_n)46 if (!rst_n)47 begin48 isCount <= 1'b0;49 rpin_out <= 1'b0;50 i <= 2'd0;51 end52 else53 case (i)5455 2'd0:56 if (H2L_sig) i <= 2'd1;57 else if (L2H_sig) i <= 2'd2;5859 2'd1:60 if (count_ms == 4'd10) begin61 isCount <= 1'b0;62 rpin_out <= 1'b1;63 i <= 2'd0;64 end65 else66 isCount <= 1'b1;6768 2'd2:69 if (count_ms == 4'd10) begin70 isCount <= 1'b0;71 rpin_out <= 1'b0;72 i <= 2'd0;73 end74 else75 isCount <= 1'b1;7677 endcase7879 assign pin_out = rpin_out;8081 endmodule82
这里isCount是定时器和计数器的使能。由其控制10ms延时的开始。
1 /**2 * File name: debounce_mocule.v3 * Function: debounce module.4 * ------------------------------5 * Pins: KEY0-rst_n, KEY1-pin_in, LEDG8-pin_out6 *7 * Target board: DE2.8 * Software: Quartus II 9.1 sp19 * ----------------------------10 * yf.x11 * 7-12-201112 *13 */1415 module debounce_module16 (17 CLOCK_50, KEY, LEDG18 );1920 input CLOCK_50;21 input [1:0] KEY;22 output [8:8] LEDG;2324 wire H2L_sig;25 wire L2H_sig;2627 detect_module U128 (29 .clk (CLOCK_50),30 .rst_n (KEY[0]),31 .pin_in (KEY[1]),32 .H2L_sig (H2L_sig),33 .L2H_sig (L2H_sig)34 );3536 delay_module U237 (38 .clk (CLOCK_50),39 .rst_n (KEY[0]),40 .H2L_sig (H2L_sig),41 .L2H_sig (L2H_sig),42 .pin_out (LEDG[8])43 );4445 endmodule4647
RTL图
小结
本实验的目的是体验“低级建模”里的单模块单功能的建模准则。直观,方便人读。
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~