芯路恒电子技术论坛

 找回密码
 立即注册

扫一扫,访问微社区

热搜: 活动
查看: 296|回复: 2

【07.08已解决】状态机按键消抖实验

[复制链接]
  • TA的每日心情
    难过
    2018-8-25 09:43
  • 3

    主题

    15

    帖子

    187

    积分

    初级会员

    Rank: 3Rank: 3

    积分
    187
    发表于 2018-7-7 01:21:48 | 显示全部楼层 |阅读模式
    本帖最后由 Deer-菜籽 于 2018-7-8 23:59 编辑

    按键消抖实验当中,编译过程出现以下报错(抱歉图片上传频繁出现“文件过大”报错)


    于是 分析错误描述
    应该是 在一个always块中,[19:3]cnt赋值产生冲突

    以下附上个人认为可能有问题的地方
    1.     <font color="Red">always@(posedge clk or negedge rst_n)</font>
    2.         if(!rst_n)
    3.             cnt <= 20'd0;
    4.         else if (en_cnt && <font color="Red">cnt < 999_999</font>)
    5.             <font color="Red">cnt <= cnt + 1'b1;</font>
    6.                         
    7.         
    8.         <font color="Blue">always@(posedge clk or negedge rst_n)</font>
    9.                 if(!rst_n)        begin
    10.                         state <= 2'd0;
    11.                 end
    12.                 else begin
    13.                         case (state)
    14. ...
    15. ...
    16.                         
    17.                         <font color="Blue">2'd1</font>:        begin
    18.                                 if<font color="Blue">(cnt >= 999_999)</font> begin
    19.                                         state <= 2'd2;
    20.                                         <font color="Blue">cnt <= 20'd0</font>;
    21.                                 end
    22.                                 else if(pedgekey)
    23.                                         en_cnt <= 1'b0;
    24.                         end
    复制代码

    前一个always块
    条件:clk上升沿 rst_n无效 cnt小于999_999
    执行:cnt 计数

    后一个always块
    条件:clk上升沿 rst_n无效 cnt大于等于999_999
    执行:cnt 清零

    以上,cnt执行不同操作时所需的条件并不相同。因此有两个疑问:
    1.cnt执行不同操作时所需的条件不同,为什么会出现quartus的报错
    2.quartus报错只针对cnt[19:3],那对于[2:0]的低三位呢?

    最后,附上完整源码
    1. module key_detact(
    2.     clk,
    3.     rst_n,
    4.     key,
    5.     led
    6. );


    7.     input clk,rst_n;
    8.     input key;
    9.     output reg[3:0]led;
    10.         
    11.         
    12.         //定义key_r储存上一个时钟周期时的key电平
    13.         //用作判断上升沿和下降沿
    14.     reg key_r;
    15.         
    16.     always@(posedge clk)
    17.         key_r <= key;
    18.                
    19.                
    20.     wire pedgekey,nedgekey;
    21.     assign pedgekey = ( (!key_r) && (key) );//按键上升沿即 上一状态为低且现状态为高
    22.     assign nedgekey = ( (key_r) && (!key) );
    23.         
    24.     reg en_cnt;
    25.     reg        [20:0]cnt;
    26.     reg [1:0] state;
    27.         
    28.     always@(posedge clk or negedge rst_n)
    29.         if(!rst_n)
    30.             cnt <= 20'd0;
    31.         else if (en_cnt && cnt < 999_999)
    32.             cnt <= cnt + 1'b1;
    33.                         
    34.         
    35.         always@(posedge clk or negedge rst_n)
    36.                 if(!rst_n)        begin
    37.                         state <= 2'd0;
    38.                 end
    39.                 else begin
    40.                         case (state)
    41.                         2'd0:        begin
    42.                                 if(nedgekey) begin
    43.                                         state <= 2'd1;
    44.                                         en_cnt <= 1'b1;
    45.                                 end
    46.                                 else
    47.                                         state <= state;
    48.                         end
    49.                         
    50.                         2'd1:        begin
    51.                                 if(cnt >= 999_999) begin
    52.                                         state <= 2'd2;
    53.                                         cnt <= 20'd0;
    54.                                 end
    55.                                 else if(pedgekey)
    56.                                         en_cnt <= 1'b0;
    57.                         end
    58.                         
    59.                         2'd2:        begin
    60.                                 if(pedgekey) begin
    61.                                         en_cnt <= 1'b1;
    62.                                         state <= 2'd3;
    63.                                 end
    64.                                 else
    65.                                         state <=2'd2;
    66.                         end
    67.                         
    68.                         2'd3:        begin
    69.                                 if(cnt >= 999_999) begin
    70.                                         state <= 2'd0;
    71.                                         cnt <= 20'd0;
    72.                                 end
    73.                                 else if(nedgekey) begin
    74.                                         en_cnt <= 1'b0;
    75.                                         if (cnt < 999_999)
    76.                                                 state <= 2'd0;
    77.                                 end
    78.                         end
    79.                         
    80.                         default:state <= 2'd0;
    81.                                        
    82.                         endcase
    83.                
    84.                 end

    85. endmodule
    复制代码

    重复一下我的问题:
    1.cnt执行不同操作时所需的条件不同,为什么会出现quartus的报错
    2.quartus报错只针对cnt[19:3],那对于[2:0]的低三位呢?

    希望能得到解答,先行谢过啦
    回复

    使用道具 举报

  • TA的每日心情
    难过
    2018-8-25 09:43
  • 3

    主题

    15

    帖子

    187

    积分

    初级会员

    Rank: 3Rank: 3

    积分
    187
     楼主| 发表于 2018-7-9 00:02:36 | 显示全部楼层
    1. //按键防抖
    2. //2018.06.29
    3. //时钟频率50M

    4. /*        2018.07.04
    5. 修改计数器数值
    6. 计数器计算方法应为 时钟频率(HZ)*时间(S)
    7. */


    8. /*        2018.07.07
    9. 独立 按键上升沿&下降沿判断
    10. 独立 计数器
    11. 代码风格向小梅哥学习
    12. */

    13. module Key_Delay(
    14.         clk,
    15.         rst_n,
    16.         key,
    17.         state,
    18.         cnt,
    19.         key_flag
    20. );


    21.         input        clk;
    22.         input        rst_n;
    23.         input        key;

    24.         output reg key_flag; //按键触发标志,1为按下,0为松开
    25.         output reg [1:0] state;
    26.         output reg [19:0] cnt;
    27.        
    28.         reg en_cnt;
    29.        
    30.        
    31.         //上升沿 & 下降沿 判断
    32.         reg [2:0]key_r;
    33.        
    34.         always@ (posedge clk)
    35.                 key_r <= {key_r[1:0],key};
    36.        
    37.        
    38.         assign key_posedge = ( key_r[1] && (!key_r[2]) );
    39.         assign key_negedge = ( (!key_r[1]) && key_r[2]);
    40.        
    41.        
    42.        
    43.         //计数器
    44.         always@ (posedge clk or negedge rst_n)
    45.                 if (!rst_n)
    46.                         cnt <= 0;
    47.                 else if (en_cnt)
    48.                         cnt <= cnt + 1;
    49.                         else
    50.                                 cnt <= 0;
    51.                
    52.        
    53.        
    54.        
    55.         //状态定义
    56.         localparam
    57.                 WAIT_LOW         =         4'b0001,                //等待出现低电平
    58.                 LOW_STABLE         =         4'b0010,                //等待20ms稳定低电平
    59.                 WAIT_HIGH         =         4'b0100,                //等待出现高电平
    60.                 HIGH_STABLE =         4'b1000;                //等待20ms稳定高电平
    61.                
    62.                
    63.                
    64.         //状态机
    65.         always@ (posedge clk or negedge rst_n)
    66.                 if (!rst_n)
    67.                         begin
    68.                         key_flag <= 1'b0;
    69.                         state <= WAIT_LOW;
    70.                         en_cnt <= 1'b0;
    71.                         end
    72.                 else begin
    73.                         case (state)
    74.                                 WAIT_LOW:        begin
    75.                                         key_flag <= 1'b0;
    76.                                         if (key_negedge)begin
    77.                                                 state <= LOW_STABLE;
    78.                                                 en_cnt <= 1'b1;
    79.                                         end
    80.                                         else
    81.                                                 state <= WAIT_LOW;
    82.                                 end
    83.                                        
    84.                                 LOW_STABLE:        begin
    85.                                         if (cnt >= 999_999) begin
    86.                                                 state <= WAIT_HIGH;
    87.                                                 en_cnt <= 1'b0;
    88.                                                 key_flag <= 1'b1;//表示按键已按下
    89.                                         end
    90.                                         else if (key_posedge) begin
    91.                                                         state <= WAIT_LOW;
    92.                                                         en_cnt <= 1'b0;
    93.                                                 end
    94.                                                 else
    95.                                                         state <= LOW_STABLE;
    96.                                                
    97.                                 end
    98.                                
    99.                                 WAIT_HIGH:        begin
    100.                                         if (key_posedge) begin
    101.                                                 state <= HIGH_STABLE;
    102.                                                 en_cnt <= 1'b1;
    103.                                         end
    104.                                         else
    105.                                                 state <= WAIT_HIGH;
    106.                                        
    107.                                 end
    108.                                
    109.                                 HIGH_STABLE: begin
    110.                                         if (cnt >= 999_999) begin
    111.                                                 key_flag <= 1'b0;
    112.                                                 en_cnt <= 1'b0;
    113.                                                 state <= WAIT_LOW;
    114.                                         end
    115.                                         else if (key_negedge) begin
    116.                                                 en_cnt <= 1'b0;
    117.                                                 state <= WAIT_HIGH;
    118.                                         end
    119.                                                 else
    120.                                                         state <= HIGH_STABLE;
    121.                                 end
    122.                                        
    123.                                 default: begin
    124.                                         state <= WAIT_LOW;
    125.                                         en_cnt <= 1'b0;
    126.                                         key_flag <=1'b0;
    127.                                         end
    128.                                
    129.                         endcase
    130.                 end
    131.                                        
    132. endmodule

    复制代码
    最后调试的代码如上,虽然还没有解决为什么cnt仅高位报错
    但似乎只要不在两个always块中对同一个变量进行赋值就不会产生冲突。

    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    可爱
    2018-7-9 22:12
  • 0

    主题

    15

    帖子

    325

    积分

    版主

    Rank: 7Rank: 7Rank: 7

    积分
    325
    发表于 2018-7-9 22:13:25 | 显示全部楼层
    Deer-菜籽 发表于 2018-7-9 00:02
    最后调试的代码如上,虽然还没有解决为什么cnt仅高位报错
    但似乎只要不在两个always块中对同一个变量进行赋 ...

    同一变量在不同always赋值,语法上不对,编辑器会报错的
    回复 支持 反对

    使用道具 举报

    *滑动验证:
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|小黑屋|手机版|Archiver|芯路恒电子技术论坛  

    GMT+8, 2018-9-20 01:36 , Processed in 0.200483 second(s), 8 queries , File On.

    Powered by Discuz! X3.3

    © 2001-2017 Comsenz Inc. Template By 【未来科技】【 www.wekei.cn 】

    快速回复 返回顶部 返回列表