在线咨询
eetop公众号 创芯大讲堂 创芯人才网
切换到宽版

EETOP 创芯网论坛 (原名:电子顶级开发网)

手机号码,快捷登录

手机号码,快捷登录

找回密码

  登录   注册  

快捷导航
搜帖子
查看: 3937|回复: 7

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

[复制链接]
发表于 2014-5-2 18:31:01 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?注册

x
本帖最后由 crazypo 于 2014-5-2 18:33 编辑

我想用两个独立按键分别控制一个变量的增减: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块没起作用,想不明白,请求大大们指教
发表于 2014-5-2 19:46:52 | 显示全部楼层
always@(posedge key_ctrl[1] or posedge key_ctrl[0] or negedge rst_n)
这句代码在ISE中是编译不过的,
触发器只有一个时钟端只支持一个边沿时钟触发。

再按键按下的过程,信号会有毛刺或者反弹,不建议将信号直接接触发器时钟。
自己通过采集输入去判断按键是否出现上升沿,再去控计数器。
 楼主| 发表于 2014-5-2 22:29:45 | 显示全部楼层
回复 2# lwukang
谢谢回复,按键我已经做过消陡处理。如果此方不通,那该如何实现对一个变量进行加减控制呢?
发表于 2014-5-3 09:04:27 | 显示全部楼层
回复 3# crazypo


   2L已经说的比较明白了。lz可以搜索下边沿检测/电平检测方法?
发表于 2014-5-3 09:18:25 | 显示全部楼层
本帖最后由 acgoal 于 2014-5-3 09:25 编辑

可以用类似如下方法:





  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


复制代码



以上为设计思路,仅供参考
发表于 2014-5-3 09:25:23 | 显示全部楼层
回复 3# crazypo
你代码的问题是always@(posedge key_ctrl[1] or posedge key_ctrl[0] or negedge rst_n)语句综合不过,
后面是对你代码处理方式的建议,像4楼说的,你去搜边沿/电平检测方法就知道了。
发表于 2014-5-3 11:56:36 | 显示全部楼层
always 后面的上升沿河下降沿只写时钟和复位,尽量不要写其它的。因为一般都是基于时钟变化的,是时钟触发的的电路。。
发表于 2014-5-9 20:55:29 | 显示全部楼层
受教了
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

站长推荐 上一条 /2 下一条

×

小黑屋| 关于我们| 联系我们| 在线咨询| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2024-5-14 10:46 , Processed in 0.043597 second(s), 10 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
快速回复 返回顶部 返回列表