微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > FPGA,CPLD和ASIC > verilog代码,无法实现用按键控制变量值的增减,求助

verilog代码,无法实现用按键控制变量值的增减,求助

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

我想用两个独立按键分别控制一个变量的增减:key_ctrl[1]控制duty_cycle增,每按一次duty_cycle加1,直到6;key_ctrl[0]控制duty_cycle减,每按一次
duty_cycle减1,直到0。

  1. reg [2:0] duty_cycle = 3'b000; //初始化duty_cycle的值为0
  2. always@(posedge key_ctrl[1] or posedge key_ctrl[0] or negedge rst_n)
  3. begin  if(!rst_n) duty_cycle <= 3'b000;                //复位
  4.          else
  5.          begin
  6.          if(key_ctrl[1])                             //如果key_ctrl[1]按下
  7.             begin
  8.                 if(duty_cycle < 3'b110)           //且duty_cycle值小于6
  9.                     duty_cycle <= duty_cycle + 3'b001; //则duty_cycle值加1
  10.                 else
  11.                         duty_cycle <= duty_cycle;  //否则duty_cycle值不变  
  12.             end
  13.     else
  14.          if(key_ctrl[0])                           //如果key_ctrl[0]按下
  15.             begin
  16.                 if(duty_cycle > 3'b000)         //且duty_cycle值大于0
  17.                     duty_cycle <= duty_cycle - 3'b001; //则duty_cycle值减1
  18.                 else
  19.                     duty_cycle <= duty_cycle;   //否则duty_cycle值不变
  20.              end
  21.                  
  22.     else
  23.         duty_cycle <= duty_cycle;
  24.     end
  25. end

复制代码


编译可以通过,但是下载到板子上并没有实现我想要的功能,duty_cycle的值只能减小,不能增大,如果将代码中的控制duty_cycle增与减换换位置,现象刚好相反,即duty_cycle的值只能增大,而不能减小。故推测是第一个if块没起作用,想不明白,请求大大们指教

always@(posedge key_ctrl[1] or posedge key_ctrl[0] or negedge rst_n)
这句代码在ISE中是编译不过的,
触发器只有一个时钟端只支持一个边沿时钟触发。
再按键按下的过程,信号会有毛刺或者反弹,不建议将信号直接接触发器时钟。
自己通过采集输入去判断按键是否出现上升沿,再去控计数器。


谢谢回复,按键我已经做过消陡处理。如果此方不通,那该如何实现对一个变量进行加减控制呢?



   2L已经说的比较明白了。lz可以搜索下边沿检测/电平检测方法?

可以用类似如下方法:

  1. always @(posedge clk of negedge rst_n) begin
  2.   if(!rst_n) begin
  3.     key_ctrl0_f <= 0;
  4.     key_ctrl1_f <= 0;
  5.   end
  6.   else begin
  7.     key_ctrl0_f <= key_ctrl[0];
  8.     key_ctrl1_f <= key_ctrl[1];
  9.   end
  10. end
  11. assign key_ctrl0_pulse = key_ctrl0 & ~key_ctrl0_f;
  12. assign key_ctrl1_pulse = key_ctrl1 & ~key_ctrl1_f;

  13. always @(posedge clk or negedge rst_n) begin  
  14.   if(!rst_n) begin
  15.     duty_cycle <= 0;
  16.   end
  17.   else begin
  18.      case({key_ctrl1_pulse, key_ctrl0_pulse})
  19.      2'b10: duty_cycle <= duty_cycle - 1;
  20.      2'b01: duty_cycle <= duty_cycle + 1;
  21.      default: duty_cycle <= duty_cycle;
  22.      endcase
  23.   end
  24. end

复制代码



以上为设计思路,仅供参考


你代码的问题是always@(posedge key_ctrl[1] or posedge key_ctrl[0] or negedge rst_n)语句综合不过,
后面是对你代码处理方式的建议,像4楼说的,你去搜边沿/电平检测方法就知道了。

always 后面的上升沿河下降沿只写时钟和复位,尽量不要写其它的。因为一般都是基于时钟变化的,是时钟触发的的电路。

受教了

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

网站地图

Top