• 状态机实验


    一:实验任务

    画出可以检测10010串的状态图,并用verilog编程实现

    思路:

    使用按键KEY1和KEY2分别代表0和1,这里要使用按键消抖,可以参考我的另一篇博客中的按键消抖FPGA按键消抖+蜂鸣器

    通过有限的6个状态进行切换,当识别到数字串10010时,LED闪烁2s。

    状态图:

     

    设计按键消抖模块

    key_debounce.v

    1. module key_debounce(
    2. input wire clk,
    3. input wire rst_n,
    4. input wire key,
    5. output reg flag, //判断抖动是否消除的标志信号,0为抖动,1为抖动结束
    6. output reg key_value //消抖后稳定的按键值给到蜂鸣器模块和LED模块
    7. );
    8. //定义20ms延迟计数器,0.2s,1_000_000次
    9. reg [19:0] delay_cnt;
    10. //寄存依次key的值用来判断按键是否消抖成功
    11. reg key_reg;
    12. //按下按键20ms延时计数器
    13. always@(posedge clk or negedge rst_n)begin
    14. if(!rst_n)
    15. begin
    16. key_reg <= 1'b1; //复位信号,设置按键无效
    17. delay_cnt <= 1'b0; //计数器设置为0
    18. end
    19. else
    20. begin
    21. key_reg <= key;
    22. if(key_reg ^ key) //当这一次key值和上一次key值不一样,证明正在抖动
    23. delay_cnt <= 20'd1_000_000; //延迟时间20ms
    24. else if(delay_cnt > 0)
    25. delay_cnt <= delay_cnt - 1; //没有抖动,开始20ms倒计时
    26. else
    27. delay_cnt <= 1'b0;
    28. end
    29. end
    30. //根据延时计数器获取按键状态以及按键值
    31. always@(posedge clk or negedge rst_n)begin
    32. if(!rst_n)
    33. begin
    34. flag <= 1'b0; //复位信号,设置信号标志为抖动
    35. key_value <= 1'b1; //设置抽样值为1
    36. end
    37. else
    38. begin
    39. if(delay_cnt == 20'd1) //倒计时1_000_000到1
    40. begin
    41. flag <= 1'b1;
    42. key_value <= key; //稳定20ms后将key值给到key_value
    43. end
    44. else
    45. begin
    46. flag <= 1'b0;
    47. key_value <= key_value; //20ms内先不取样
    48. end
    49. end
    50. end
    51. endmodule

     设计状态机模块Verilog HDL文件

    fsm_10010.v

    1. module fsm_10010(
    2. input clk,
    3. input rst_n,
    4. input [1:0] key,
    5. output wire [3:0] led
    6. );
    7. parameter MAX_NUM = 24'd9_999_999;//0.2s计时器
    8. parameter T = 4'd10;//2s,100_000_000次
    9. reg [2:0] cstate; //现态
    10. //状态划分
    11. localparam state_0 = 0; //初始状态
    12. localparam state_1 = 1; //按下1
    13. localparam state_10 = 2; //按下10
    14. localparam state_100 = 3; //按下100
    15. localparam state_1001 = 4; //按下1001
    16. localparam state_10010 = 5; //按下10010
    17. reg [3:0] cnt = 0; //计时器赋初值为0
    18. reg [23:0] cnt_02 = 0;
    19. reg time_flag;//计时标志,1:开始计时,0:结束计时
    20. reg [3:0] led_r;
    21. //0.2计数器模块
    22. always@(posedge clk or negedge rst_n)begin
    23. if(!rst_n)
    24. cnt_02 <= 1'b0; //按下复位键,清零
    25. else if(cnt_02 == MAX_NUM)
    26. cnt_02 <= 1'b0;
    27. else
    28. cnt_02 <= cnt_02 + 1'b1;
    29. end
    30. //2s计数器模块
    31. always@(posedge clk or negedge rst_n)begin
    32. if(!rst_n)
    33. cnt <= 1'b0;//按下复位键,清零
    34. else if(time_flag == 1'b1)begin//开始计时
    35. if(cnt_02 == MAX_NUM)begin
    36. if(cnt < T)begin
    37. cnt <= cnt + 1'b1;
    38. end
    39. else begin
    40. cnt <= 1'b0;//cnt计数达到最大就清空
    41. end
    42. end
    43. else begin
    44. cnt <= cnt;//其余时间保持
    45. end
    46. end
    47. else begin
    48. cnt <= 1'b0;//不计时,cnt清空
    49. end
    50. end
    51. //状态切换模块
    52. always@(posedge clk or negedge rst_n)begin
    53. if(!rst_n)
    54. begin
    55. cstate <= state_0;
    56. end
    57. else
    58. case(cstate)
    59. state_0: begin
    60. if(key[1] == 1'b1) //该状态持续时间为1s,1s后,下一次状态更改为led1亮
    61. cstate <= state_1;
    62. else if(key[0] == 1'b1)
    63. cstate <= state_0;
    64. else
    65. cstate <= state_0;
    66. end
    67. state_1: begin
    68. if(key[0] == 1'b1)
    69. cstate <= state_10;
    70. else if(key[1] == 1'b1)
    71. cstate <= state_0;
    72. else
    73. cstate <= state_1;
    74. end
    75. state_10: begin
    76. if(key[0] == 1'b1)
    77. cstate <= state_100;
    78. else if(key[1] == 1'b1)
    79. cstate <= state_0;
    80. else
    81. cstate <= state_10;
    82. end
    83. state_100: begin
    84. if(key[1] == 1'b1)
    85. cstate <= state_1001;
    86. else if(key[0] == 1'b1)
    87. cstate <= state_0;
    88. else
    89. cstate <= state_100;
    90. end
    91. state_1001: begin
    92. if(key[0] == 1'b1)begin
    93. cstate <= state_10010;
    94. time_flag <= 1'b1;//开始计时
    95. end
    96. else if(key[1] == 1'b1)
    97. cstate <= state_0;
    98. else
    99. cstate <= state_1001;
    100. end
    101. state_10010: begin
    102. if(cnt == T)begin
    103. cstate <= state_0;
    104. time_flag <= 1'b0;//结束计时
    105. end
    106. else
    107. cstate <= state_10010;
    108. end
    109. default: ;
    110. endcase
    111. end
    112. //第三段:跟随状态输出
    113. always@(posedge clk or negedge rst_n)begin
    114. if(!rst_n)
    115. led_r <= 4'b0001;
    116. else
    117. case(cstate)
    118. state_10010:if(cnt_02 == 24'd4_999_999)
    119. led_r <= 4'b1111;
    120. else if(cnt_02 == MAX_NUM)
    121. led_r <= 4'b0000;
    122. else
    123. led_r <= led_r;
    124. default : led_r <= 4'b0001;
    125. endcase
    126. end
    127. assign led = led_r;
    128. endmodule

    设计顶层模块

    top_fsm_10010.v

    1. module top_fsm_10010(
    2. input wire clk,
    3. input wire rst_n,
    4. input wire [1:0] key,
    5. output wire [3:0] led
    6. );
    7. wire [1:0] flag;
    8. wire [1:0] key_value;
    9. //例化按键KEY1
    10. key_debounce inst_key_debounce(
    11. .clk (clk ),
    12. .rst_n (rst_n ),
    13. .key (key[0] ),
    14. .flag (flag[0] ), //判断抖动是否消除的标志信号,0为抖动,1为抖动结束
    15. .key_value(key_value[0]) //消抖后稳定的按键值给到蜂鸣器模块和LED模块
    16. );
    17. //例化按键KEY2
    18. key_debounce inst_key_debounce1(
    19. .clk (clk ),
    20. .rst_n (rst_n ),
    21. .key (key[1] ),
    22. .flag (flag[1] ), //判断抖动是否消除的标志信号,0为抖动,1为抖动结束
    23. .key_value(key_value[1]) //消抖后稳定的按键值给到蜂鸣器模块和LED模块
    24. );
    25. //例化状态机
    26. fsm_10010(
    27. .clk (clk ),
    28. .rst_n(rst_n ),
    29. .key ({~key_value[1]&&flag[1],~key_value[0]&&flag[0]}),
    30. .led (led)
    31. );
    32. endmodule

     查看RTL门级电路

  • 相关阅读:
    NVIDIA GPU MIG
    Mac M2芯片安装Anaconda的版本不兼容的问题
    离散数学 一阶逻辑基本概念 习题
    产品经理就业喜报:沉舟侧畔终迎万木春
    WEIXIN day_07(8.24) 学子影院项目实践3
    TCP三次握手与四次挥手详细解释与文献参考
    (南京观海微电子)——屏幕材质及优缺点对比
    NIO简单介绍
    Java9-17新特性一览,了解少于3个你可能脱节了
    案例分享|金融业数据运营运维一体化建设
  • 原文地址:https://blog.csdn.net/mxh3600/article/details/126148829