verilog代码,无法实现用按键控制变量值的增减,求助
时间:10-02
整理:3721RD
点击:
我想用两个独立按键分别控制一个变量的增减:key_ctrl[1]控制duty_cycle增,每按一次duty_cycle加1,直到6;key_ctrl[0]控制duty_cycle减,每按一次
duty_cycle减1,直到0。
- reg [2:0] duty_cycle = 3'b000; //初始化duty_cycle的值为0
- always@(posedge key_ctrl[1] or posedge key_ctrl[0] or negedge rst_n)
- begin if(!rst_n) duty_cycle <= 3'b000; //复位
- else
- begin
- if(key_ctrl[1]) //如果key_ctrl[1]按下
- begin
- if(duty_cycle < 3'b110) //且duty_cycle值小于6
- duty_cycle <= duty_cycle + 3'b001; //则duty_cycle值加1
- else
- duty_cycle <= duty_cycle; //否则duty_cycle值不变
- end
- else
- if(key_ctrl[0]) //如果key_ctrl[0]按下
- begin
- if(duty_cycle > 3'b000) //且duty_cycle值大于0
- duty_cycle <= duty_cycle - 3'b001; //则duty_cycle值减1
- else
- duty_cycle <= duty_cycle; //否则duty_cycle值不变
- end
-
- else
- duty_cycle <= duty_cycle;
- end
- 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可以搜索下边沿检测/电平检测方法?
可以用类似如下方法:
- always @(posedge clk of negedge rst_n) begin
- if(!rst_n) begin
- key_ctrl0_f <= 0;
- key_ctrl1_f <= 0;
- end
- else begin
- key_ctrl0_f <= key_ctrl[0];
- key_ctrl1_f <= key_ctrl[1];
- end
- end
- assign key_ctrl0_pulse = key_ctrl0 & ~key_ctrl0_f;
- assign key_ctrl1_pulse = key_ctrl1 & ~key_ctrl1_f;
- always @(posedge clk or negedge rst_n) begin
- if(!rst_n) begin
- duty_cycle <= 0;
- end
- else begin
- case({key_ctrl1_pulse, key_ctrl0_pulse})
- 2'b10: duty_cycle <= duty_cycle - 1;
- 2'b01: duty_cycle <= duty_cycle + 1;
- default: duty_cycle <= duty_cycle;
- endcase
- end
- end
以上为设计思路,仅供参考
你代码的问题是always@(posedge key_ctrl[1] or posedge key_ctrl[0] or negedge rst_n)语句综合不过,
后面是对你代码处理方式的建议,像4楼说的,你去搜边沿/电平检测方法就知道了。
always 后面的上升沿河下降沿只写时钟和复位,尽量不要写其它的。因为一般都是基于时钟变化的,是时钟触发的的电路。
受教了
