微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > FPGA,CPLD和ASIC > 小梅哥FPGA设计思想与验证方法视频教程之基于状态机的独立按键消抖

小梅哥FPGA设计思想与验证方法视频教程之基于状态机的独立按键消抖

时间:10-02 整理:3721RD 点击:

        大家好,今天,小梅哥继续连载本人精心录制和编辑的FPGA学习系列教程——《小梅哥FPGA设计思想与验证方法视频教程》。教程充分考虑0基础朋友的实际情况,手把手带领学习者分析思路、编写代码、仿真验证、板级调试。教语法,学仿真,一步一步,直到最后设计若干较为综合的逻辑系统。

                教程以我们自主开发的芯航线FPGA学习板为实验平台,通过若干基础和综合的系统设计讲解,一步一步掌握FPGA设计与验证的思想和方法,希望了解芯航线FPGA学习板的,请点击这里:


http://z.elecfans.com/1?ck=snow

                今天是视频第八讲,主要通过独立按键消抖这样一个实验,来进一步举例讲解状态机的设计思想,独立按键消抖有多种方式可以实现,这里采用状态机的方式,既能方便大家理解按键消抖的整个过程,又能进一步领会状态机的设计思想。


                接下来,大家请看视频教程,由于视频中有部分网络的链接,因此上传优酷会被屏蔽,这里就直接分享在百度云盘中了。欢迎大家转载观看。(1280*720分辨率,MP4格式,用手机观看效果非常爽哦,建议大家下载了再观看)

好消息:

从此再也不需要一个一个回复才能看下载地址了


全部开源视频下载地址:

http://pan.baidu.com/s/1kUs0vkF
视频教程中配套源码下载地址:
http://pan.baidu.com/s/1qX5hz9y


觉得好的,记得回来帮忙顶个帖哦



?欢迎加入芯航线FPGA技术支持群:472607506

小梅哥

2015年9月28日星期一

芯航线电子工作室

顶!

用这个练习状态机不错,尤其是testbench写得佷威武

我按照视频的思想,写了个三段式的状态机,请梅总指点:
Step1. 接口设计

  1. //按键消抖实验
  2. //每次按下按键led翻转
  3. module key_filter(
  4.     clk_50M,
  5.     rst_n,
  6.     key_in,     //按键输入
  7.     key_out,    //滤波后的按键信号
  8.     led         //led灯,0亮,1灭
  9. );
  10.     input clk_50M;
  11.     input rst_n;
  12.     input key_in;
  13.     output key_out;
  14.     output led;
  15. endmodule

复制代码


编译,只有警告

Step2. 三段式状态机的前两段

  1. parameter
  2.         IDLE    = 4'b0001,
  3.         FILTER0 = 4'b0010,
  4.         DOWN    = 4'b0100,
  5.         FILTER1 = 4'b1000;
  6.     reg[3:0] cur_state;
  7.     reg[3:0] next_state;

  8.     always  @(posedge clk_50M or negedge rst_n)begin
  9.         if(rst_n==1'b0)begin
  10.             cur_state <= IDLE;
  11.         end
  12.         else begin
  13.             cur_state <= next_state;
  14.         end
  15.     end

  16.     always  @(*)begin
  17.         case( cur_state )
  18.             IDLE:
  19.                 if( nedge ) next_state = FILTER0;
  20.                 else next_state = IDLE;
  21.             FILTER0:
  22.                 if( down_20ms ) next_state = DOWN;
  23.                 else if( pedge || nedge ) next_state = IDLE;
  24.                 else next_state = FILTER0;
  25.             DOWN:
  26.                 if( pedge ) next_state = FILTER1;
  27.                 else next_state = DOWN;
  28.             FILTER1:
  29.                  if( down_20ms ) next_state = IDLE;
  30.                  else if( pedge || nedge ) next_state = DOWN;
  31.                  else next_state = FILTER1;
  32.             default: next_state = IDLE;
  33.         endcase
  34. end

复制代码


编译,nedge,pedge,down_20ms没有定义,下面逐个定义它们。

Step3. pedge和nedge

  1.    reg key_in0;//key_in打两拍
  2.     reg key_in1;
  3.     wire pedge; //key_in上升沿检测
  4.     wire nedge; //key_in下降沿检测

  5.     //边沿检测得到pedge和nedge
  6.     always  @(posedge clk_50M or negedge rst_n)begin
  7.         if(rst_n==1'b0)begin
  8.             key_in0 <= 1'd1;
  9.             key_in1 <= 1'd1;
  10.         end
  11.         else begin
  12.             key_in0 <= key_in;
  13.             key_in1 <= key_in0;
  14.         end
  15.     end
  16.     assign pedge = key_in0 & ~key_in1;
  17.     assign nedge = ~key_in0 & key_in1;

复制代码

Step4. down_20ms

  1. parameter
  2.         TOP_20MS = 20'd1_000_000;

  3.     reg[19:0] cnt;//20ms计数器
  4.     wire down_20ms;

  5.     //计数器计数得到down_20ms信号
  6.     always  @(posedge clk_50M or negedge rst_n)begin
  7.         if(rst_n==1'b0)begin
  8.             cnt <= 20'd0;
  9.         end
  10.         else begin
  11.             if( cur_state == FILTER0 || cur_state == FILTER1 ) begin
  12.                 if( pedge || nedge ) cnt <= 20'd0;
  13.                 else if( cnt < TOP_20MS-1 ) cnt <= cnt + 1'd1;
  14.                 else;
  15.             end
  16.             else cnt <= 20'd0;
  17.         end
  18.     end
  19.     assign down_20ms = ( cnt == TOP_20MS-1 );

复制代码

Step5. 第三段状态机,处理输出信号

  1.    reg key_out_r;
  2.     reg led;
  3.     //输出信号处理
  4.     always  @(posedge clk_50M or negedge rst_n)begin
  5.         if(rst_n==1'b0)begin
  6.             key_out_r <= 1'd1;
  7.         end
  8.         else begin
  9.             key_out_r <= ~( cur_state == DOWN );
  10.         end
  11.     end
  12.     assign key_out = key_out_r;

  13.     always  @(posedge clk_50M or negedge rst_n)begin
  14.         if(rst_n==1'b0)begin
  15.             led <= 1'd0;
  16.         end
  17.         else begin
  18.             if( cur_state == FILTER0 && next_state == DOWN )
  19.                 led <= ~led;
  20.         end
  21.     end

复制代码

整个文件

  1. //按键消抖实验
  2. //每次按下按键led翻转
  3. module key_filter(
  4.     clk_50M,
  5.     rst_n,
  6.     key_in,     //按键输入
  7.     key_out,    //滤波后的按键信号
  8.     led         //led灯,0亮,1灭
  9. );
  10.     input clk_50M;
  11.     input rst_n;
  12.     input key_in;
  13.     output key_out;
  14.     output led;

  15.     parameter
  16.         IDLE    = 4'b0001,
  17.         FILTER0 = 4'b0010,
  18.         DOWN    = 4'b0100,
  19.         FILTER1 = 4'b1000;

  20.     parameter
  21.         TOP_20MS = 20'd1_000_000;

  22.     reg[3:0] cur_state;
  23.     reg[3:0] next_state;

  24.     reg key_in0;//key_in打两拍
  25.     reg key_in1;
  26.     wire pedge; //key_in上升沿检测
  27.     wire nedge; //key_in下降沿检测

  28.     reg[19:0] cnt;//20ms计数器
  29.     wire down_20ms;

  30.     reg key_out_r;
  31.     reg led;

  32.     always  @(posedge clk_50M or negedge rst_n)begin
  33.         if(rst_n==1'b0)begin
  34.             cur_state <= IDLE;
  35.         end
  36.         else begin
  37.             cur_state <= next_state;
  38.         end
  39.     end

  40.     always  @(*)begin
  41.         case( cur_state )
  42.             IDLE:
  43.                 if( nedge ) next_state = FILTER0;
  44.                 else next_state = IDLE;
  45.             FILTER0:
  46.                 if( down_20ms ) next_state = DOWN;
  47.                 else if( pedge || nedge ) next_state = IDLE;
  48.                 else next_state = FILTER0;
  49.             DOWN:
  50.                 if( pedge ) next_state = FILTER1;
  51.                 else next_state = DOWN;
  52.             FILTER1:
  53.                  if( down_20ms ) next_state = IDLE;
  54.                  else next_state = FILTER1;
  55.             default: next_state = IDLE;
  56.         endcase
  57.     end

  58.     //边沿检测得到pedge和nedge
  59.     always  @(posedge clk_50M or negedge rst_n)begin
  60.         if(rst_n==1'b0)begin
  61.             key_in0 <= 1'd1;
  62.             key_in1 <= 1'd1;
  63.         end
  64.         else begin
  65.             key_in0 <= key_in;
  66.             key_in1 <= key_in0;
  67.         end
  68.     end
  69.     assign pedge = key_in0 & ~key_in1;
  70.     assign nedge = ~key_in0 & key_in1;


  71.     //计数器计数得到down_20ms信号
  72.     always  @(posedge clk_50M or negedge rst_n)begin
  73.         if(rst_n==1'b0)begin
  74.             cnt <= 20'd0;
  75.         end
  76.         else begin
  77.             if( cur_state == FILTER0 || cur_state == FILTER1 ) begin
  78.                 if( pedge || nedge ) cnt <= 20'd0;
  79.                 else if( cnt < TOP_20MS-1 ) cnt <= cnt + 1'd1;
  80.                 else;
  81.             end
  82.             else cnt <= 20'd0;
  83.         end
  84.     end
  85.     assign down_20ms = ( cnt == TOP_20MS-1 );

  86.     //输出信号处理
  87.     always  @(posedge clk_50M or negedge rst_n)begin
  88.         if(rst_n==1'b0)begin
  89.             key_out_r <= 1'd1;
  90.         end
  91.         else begin
  92.             key_out_r <= ~( cur_state == DOWN );
  93.         end
  94.     end
  95.     assign key_out = key_out_r;

  96.     always  @(posedge clk_50M or negedge rst_n)begin
  97.         if(rst_n==1'b0)begin
  98.             led <= 1'd0;
  99.         end
  100.         else begin
  101.             if( cur_state == FILTER0 && next_state == DOWN )
  102.                 led <= ~led;
  103.         end
  104.     end
  105. endmodule

复制代码

感觉输出led和key_out没对齐,led似乎还应该再打一拍才对齐。

贴上仿真结果。远看看不见key_in的抖动。但近看。确实是有抖那么两三下的。


尝试将抖动次数加多,就能看到了吧

支持!感觉小梅哥讲的视频把老师一学期讲的课给概括了!点赞!

小梅哥FPGA设计思想与验证方法视频教程

支持梅哥,好好学习,谢谢

好好好好好好好好好好好好好好好好好好好好

bucuo 支持                                 

好好好好好好好好好好好好好好好好好好好好

顶 ,用这个练习状态机不错,学习中

希望观看视频学习

小梅哥FPGA设计思想与验证方法视频教程之高性能计数器IP核使用

下载了,不错的视频

顶                                   

大力支持小梅哥

拉大无聊的卡我打我电话干的哈1

看一看,学习了。哈哈

好。。

谢谢小编分享,

謝謝

                 学习

小梅哥FPGA设计思想与验证方法视频教程之UART串口发送模块设计与验证
Good

把小梅哥的视频都保存了

回帖试试                           

用这个练习状态机不错,尤其是testbench写得佷威武

小梅哥FPGA设计思想与验证方法视频教程

顶!d=====( ̄▽ ̄*)b~感谢分享!

顶顶顶。

dggdfgsdfsfsdfsdfsdfsf

谢谢分享~~~~~~~~~~~~

支持!感觉小梅哥讲的视频把老师一学期讲的课给概括了!点赞!

支持!感觉小梅哥讲的视频把老师一学期讲的课给概括了!点赞!

讲的蛮好的,很实用。

继续学习第九弹

支持小梅哥的教学视频

小梅哥讲得不错哦。

谢小梅哥  无私奉献啊

谢谢分享,持续关注中!

谢谢梅哥的无私分享......

持续关注小梅哥的视频中。

小编真好,小编好人啊啊   啊啊

接下来,大家请看视频教程,

这个很好、、、、、、、、、、、、、、、

按键消抖应用非常广泛,跟着学吧!

好好,非常感谢

111111111111111111111111111111111111111111111111111111111111111111111111111111

支持一下,顶!

,不错期待后续视频

不错期待后续视频;请问小梅哥有没有usb,以太网这样的教程呢

非常不错哦~~~~~~~~~~~~~

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top