当前位置:   article > 正文

北邮22级信通院数电:Verilog-FPGA(9)第九周实验(3)实现一个具有清零功能的按键计数器,对按键进行计数并显示_fpga用verilog设计一个具有异步清零同步置数,计数和保持功能的十进制按键计数器

fpga用verilog设计一个具有异步清零同步置数,计数和保持功能的十进制按键计数器

北邮22信通一枚~

跟随课程进度更新北邮信通院数字系统设计的笔记、代码和文章

持续关注作者 迎接数电实验学习~

获取更多文章,请访问专栏:

北邮22级信通院数电实验_青山如墨雨如画的博客-CSDN博客

 

目录

一.代码部分

1.1 counter.v

1.2 debounce.v

二.管脚分配

三.实现效果


一.代码部分

1.1 counter.v

  1. module counter
  2. (
  3. input clk,
  4. input rst,
  5. input button_1,
  6. input button_2,
  7. output [8:0] seg_1,
  8. output [8:0] seg_2
  9. );
  10. reg [8:0] seg [9:0];
  11. wire key_pulse_1;
  12. wire key_pulse_2;
  13. reg [6:0] counting=2'b00;
  14. reg [3:0] seg_data_1=1'b0;
  15. reg [3:0] seg_data_2=1'b0;
  16. initial
  17. begin
  18. seg[0]=9'h3f;
  19. seg[1]=9'h06;
  20. seg[2]=9'h5b;
  21. seg[3]=9'h4f;
  22. seg[4]=9'h66;
  23. seg[5]=9'h6d;
  24. seg[6]=9'h7d;
  25. seg[7]=9'h07;
  26. seg[8]=9'h7f;
  27. seg[9]=9'h6f;
  28. end
  29. debounce debounce_1
  30. (
  31. .clk(clk),
  32. .rst(rst),
  33. .key(button_1),
  34. .key_pulse(key_pulse_1)
  35. );
  36. debounce debounce_2
  37. (
  38. .clk(clk),
  39. .rst(rst),
  40. .key(button_2),
  41. .key_pulse(key_pulse_2)
  42. );
  43. always @ (posedge clk or negedge rst)
  44. begin
  45. if(!rst)
  46. begin counting<=0; end
  47. else
  48. begin
  49. if(key_pulse_1)
  50. begin counting<=(counting+1)%100;end
  51. else if(key_pulse_2)
  52. begin counting<=(counting-1+100)%100;end
  53. else
  54. begin counting<=counting; end
  55. seg_data_1<=counting/10;
  56. if(counting%10==0)
  57. begin seg_data_2<=0;end
  58. else
  59. begin seg_data_2<=counting-10*seg_data_1;end
  60. end
  61. end
  62. assign seg_1=seg[seg_data_1];
  63. assign seg_2=seg[seg_data_2];
  64. endmodule

1.2 debounce.v

  1. module debounce (clk,rst,key,key_pulse);
  2. parameter N = 1; //要消除的按键的数量
  3. input clk;
  4. input rst;
  5. input [N-1:0] key; //输入的按键
  6. output [N-1:0] key_pulse; //按键动作产生的脉冲
  7. reg [N-1:0] key_rst_pre; //定义一个寄存器型变量存储上一个触发时的按键值
  8. reg [N-1:0] key_rst; //定义一个寄存器变量储存储当前时刻触发的按键值
  9. wire [N-1:0] key_edge; //检测到按键由高到低变化是产生一个高脉冲
  10. //利用非阻塞赋值特点,将两个时钟触发时按键状态存储在两个寄存器变量中
  11. always @(posedge clk or negedge rst)
  12. begin
  13. if (!rst) begin
  14. key_rst <= {N{1'b1}}; //初始化时给key_rst赋值全为1,{}中表示N个1
  15. key_rst_pre <= {N{1'b1}};
  16. end
  17. else begin
  18. key_rst <= key; //第一个时钟上升沿触发之后key的值赋给key_rst,
  19. //同时key_rst的值赋给key_rst_pre
  20. key_rst_pre <= key_rst; //非阻塞赋值。
  21. //相当于经过两个时钟触发,
  22. //key_rst存储的是当前时刻key的值,
  23. //key_rst_pre存储的是前一个时钟的key的值
  24. end
  25. end
  26. assign key_edge = key_rst_pre & (~key_rst);//脉冲边沿检测。
  27. //key检测到下降沿时,
  28. //key_edge产生一个时钟周期的高电平
  29. reg [17:0] cnt; //产生延时所用的计数器,系统时钟12MHz,
  30. //要延时20ms左右时间,至少需要18位计数器
  31. //产生20ms延时,当检测到key_edge有效是计数器清零开始计数
  32. always @(posedge clk or negedge rst)
  33. begin
  34. if(!rst)
  35. cnt <= 18'h0;
  36. else if(key_edge)
  37. cnt <= 18'h0;
  38. else
  39. cnt <= cnt + 1'h1;
  40. end
  41. reg [N-1:0] key_sec_pre; //延时后检测电平寄存器变量
  42. reg [N-1:0] key_sec;
  43. //延时后检测key,如果按键状态变低产生一个时钟的高脉冲。如果按键状态是高的话说明按键无效
  44. always @(posedge clk or negedge rst)
  45. begin
  46. if (!rst)
  47. key_sec <= {N{1'b1}};
  48. else if (cnt==18'h3ffff)
  49. key_sec <= key;
  50. end
  51. always @(posedge clk or negedge rst)
  52. begin
  53. if (!rst)
  54. key_sec_pre <= {N{1'b1}};
  55. else
  56. key_sec_pre <= key_sec;
  57. end
  58. assign key_pulse = key_sec_pre & (~key_sec);
  59. endmodule

二.管脚分配

三.实现效果

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/115816
推荐阅读
相关标签
  

闽ICP备14008679号