• ZYNQ_project:key_beep


    通过按键控制蜂鸣器工作。

    模块框图:

    时序图

     

    代码:

    1. /*
    2. 1位按键消抖
    3. */
    4. module key_filter (
    5. input wire sys_clk ,
    6. input wire sys_rst_n ,
    7. input wire key_in ,
    8. output reg key_flag
    9. );
    10. // 参数定义
    11. parameter MAX_CNT_10MS = 500_000 ;
    12. localparam IDLE = 4'b0001 ,
    13. FILTER_UP = 4'b0010 ,
    14. SAMPLING = 4'b0100 ,
    15. FILTER_BACK = 4'b1000 ;
    16. // reg signal define
    17. reg key_in_r1 ;
    18. reg key_in_r2 ;
    19. reg [18:0] cnt_core ;
    20. reg [3:0] state_c ;
    21. reg [3:0] state_n ;
    22. // wire signal define
    23. wire nege ;
    24. wire pose ;
    25. wire IDLEtoFILTER_UP ;
    26. wire FILTER_UPtoIDLE ;
    27. wire FILTER_UPtoSAMPLING ;
    28. wire SAMPLINGtoFILTER_BACK ;
    29. wire FILTER_BACKtoIDLE ;
    30. wire filter_done ;
    31. /******************************************************************/
    32. // reg key_in_r1 ;
    33. always @(posedge sys_clk or negedge sys_rst_n) begin
    34. if(~sys_rst_n)
    35. key_in_r1 <= 1'b1 ;
    36. else
    37. key_in_r1 <= key_in ;
    38. end
    39. // reg key_in_r2 ;
    40. always @(posedge sys_clk or negedge sys_rst_n) begin
    41. if(~sys_rst_n)
    42. key_in_r2 <= 1'b1 ;
    43. else
    44. key_in_r2 <= key_in_r1 ;
    45. end
    46. // wire nege ;
    47. assign nege = ~key_in_r1 && key_in_r2 ;
    48. // wire pose ;
    49. assign pose = key_in_r1 && ~key_in_r2 ;
    50. // reg [3:0] state_c ;
    51. always @(posedge sys_clk or negedge sys_rst_n) begin
    52. if(~sys_rst_n)
    53. state_c <= IDLE ;
    54. else
    55. state_c <= state_n ;
    56. end
    57. // reg [3:0] state_n ;
    58. always @(*) begin
    59. case(state_c)
    60. IDLE : if(IDLEtoFILTER_UP)
    61. state_n = FILTER_UP ;
    62. else
    63. state_n = IDLE ;
    64. FILTER_UP : if(FILTER_UPtoIDLE)
    65. state_n = IDLE ;
    66. else if(FILTER_UPtoSAMPLING)
    67. state_n = SAMPLING ;
    68. else
    69. state_n = FILTER_UP ;
    70. SAMPLING : if(SAMPLINGtoFILTER_BACK)
    71. state_n = FILTER_BACK ;
    72. else
    73. state_n = SAMPLING ;
    74. FILTER_BACK:if(FILTER_BACKtoIDLE)
    75. state_n = IDLE ;
    76. else
    77. state_n = FILTER_BACK ;
    78. default : state_n = IDLE ;
    79. endcase
    80. end
    81. assign IDLEtoFILTER_UP = (state_c == IDLE) && (nege) ;
    82. assign FILTER_UPtoIDLE = (state_c == FILTER_UP) && (pose) ;
    83. assign FILTER_UPtoSAMPLING = (state_c == FILTER_UP) && (filter_done) ;
    84. assign SAMPLINGtoFILTER_BACK = (state_c == SAMPLING) && (pose) ;
    85. assign FILTER_BACKtoIDLE = (state_c == FILTER_BACK)&& (filter_done) ;
    86. // reg [18:0] cnt_core ;
    87. always @(posedge sys_clk or negedge sys_rst_n) begin
    88. if(~sys_rst_n)
    89. cnt_core <= 19'd0 ;
    90. else
    91. case (state_c)
    92. IDLE :cnt_core <= 19'd0 ;
    93. FILTER_UP :if(filter_done)
    94. cnt_core <= 19'd0 ;
    95. else
    96. cnt_core <= cnt_core + 1'b1 ;
    97. SAMPLING :cnt_core <= 19'd0 ;
    98. FILTER_BACK:if(filter_done)
    99. cnt_core <= 19'd0 ;
    100. else
    101. cnt_core <= cnt_core + 1'b1 ;
    102. default : cnt_core <= 19'd0 ;
    103. endcase
    104. end
    105. // wire filter_done
    106. assign filter_done = (cnt_core == MAX_CNT_10MS - 1) ;
    107. // output reg key_flag
    108. always @(posedge sys_clk or negedge sys_rst_n) begin
    109. if(~sys_rst_n)
    110. key_flag <= 1'b0 ;
    111. else if(FILTER_UPtoSAMPLING)
    112. key_flag <= ~key_in_r2 ;
    113. else
    114. key_flag <= 1'b0 ;
    115. end
    116. endmodule

    1. /*
    2. 蜂鸣器驱动模块,NPN三极管,beep_en == 1 鸣叫。有源电磁式。
    3. 1, 初始状态鸣叫,按键每按下一次,蜂鸣器状态翻转。
    4. 2. 初始状态蜂鸣器工作,响100ms , 不响100ms, 响100ms, 不响300ms.按键每按下一次,蜂鸣器工作状态翻转。
    5. */
    6. module beep (
    7. input wire sys_clk ,
    8. input wire sys_rst_n ,
    9. input wire key_flag ,
    10. output reg beep_en
    11. );
    12. // // output reg beep_en
    13. // always @(posedge sys_clk or negedge sys_rst_n) begin
    14. // if(~sys_rst_n)
    15. // beep_en <= 1'b1 ;
    16. // else if(key_flag)
    17. // beep_en <= ~beep_en ;
    18. // end
    19. // parameter
    20. parameter MAX_CNT_100MS = 5_000_000 ,
    21. MAX_CNT_300MS = 15_000_000 ;
    22. localparam RING = 3'b001 ,
    23. NO_RING_MOD1 = 3'b010 ,
    24. NO_RING_MOD2 = 3'b100 ;
    25. // reg signal define
    26. reg beep_work ;
    27. reg [23:0] cnt_core ;
    28. reg [2:0] state_c ;
    29. reg [2:0] state_n ;
    30. reg mod1_flag ;
    31. // wire signal define
    32. wire RINGtoNO_RING_MOD1 ;
    33. wire RINGtoNO_RING_MOD2 ;
    34. wire NO_RING_MOD1toRING ;
    35. wire NO_RING_MOD2toRING ;
    36. wire no_ring_done ;
    37. /*****************************************************/
    38. // reg beep_work ;
    39. always @(posedge sys_clk or negedge sys_rst_n) begin
    40. if(~sys_rst_n)
    41. beep_work <= 1'b1 ;
    42. else if(key_flag)
    43. beep_work <= ~beep_work ;
    44. else
    45. beep_work <= beep_work ;
    46. end
    47. // reg [2:0] state_c ;
    48. always @(posedge sys_clk or negedge sys_rst_n) begin
    49. if(~sys_rst_n)
    50. state_c <= RING ;
    51. else
    52. state_c <= state_n ;
    53. end
    54. // reg [2:0] state_n ;
    55. always @(*) begin
    56. if(beep_work) begin
    57. case(state_c)
    58. RING : if(RINGtoNO_RING_MOD1)
    59. state_n = NO_RING_MOD1 ;
    60. else if(RINGtoNO_RING_MOD2)
    61. state_n = NO_RING_MOD2 ;
    62. else
    63. state_n = RING ;
    64. NO_RING_MOD1: if(NO_RING_MOD1toRING)
    65. state_n = RING ;
    66. else
    67. state_n = NO_RING_MOD1 ;
    68. NO_RING_MOD2: if(NO_RING_MOD2toRING)
    69. state_n = RING ;
    70. else
    71. state_n = NO_RING_MOD2 ;
    72. default : state_n = RING ;
    73. endcase
    74. end
    75. else
    76. state_n = RING ;
    77. end
    78. assign RINGtoNO_RING_MOD1 = (state_c == RING) && (no_ring_done && (mod1_flag)) ;
    79. assign RINGtoNO_RING_MOD2 = (state_c == RING) && (no_ring_done && (!mod1_flag)) ;
    80. assign NO_RING_MOD1toRING = (state_c == NO_RING_MOD1) && (no_ring_done) ;
    81. assign NO_RING_MOD2toRING = (state_c == NO_RING_MOD2) && (no_ring_done) ;
    82. // reg [23:0] cnt_core ;
    83. always @(posedge sys_clk or negedge sys_rst_n) begin
    84. if(~sys_rst_n)
    85. cnt_core <= 24'd0 ;
    86. else
    87. if(beep_work) begin
    88. case (state_c)
    89. RING : if(no_ring_done)
    90. cnt_core <= 24'd0 ;
    91. else
    92. cnt_core <= cnt_core + 1'b1 ;
    93. NO_RING_MOD1: if(no_ring_done)
    94. cnt_core <= 24'd0 ;
    95. else
    96. cnt_core <= cnt_core + 1'b1 ;
    97. NO_RING_MOD2: if(no_ring_done)
    98. cnt_core <= 24'd0 ;
    99. else
    100. cnt_core <= cnt_core + 1'b1 ;
    101. default : cnt_core <= 24'd0 ;
    102. endcase
    103. end
    104. else
    105. cnt_core <= 24'd0 ;
    106. end
    107. // reg mod1_flag ;
    108. always @(posedge sys_clk or negedge sys_rst_n) begin
    109. if(~sys_rst_n)
    110. mod1_flag <= 1'b1 ;
    111. else if(beep_work) begin
    112. if((state_c != RING) && (no_ring_done))
    113. mod1_flag <= ~mod1_flag ;
    114. else
    115. mod1_flag <= mod1_flag ;
    116. end
    117. else
    118. mod1_flag <= 1'b1 ;
    119. end
    120. // wire no_ring_done;
    121. assign no_ring_done = (((state_c != NO_RING_MOD2)&&(cnt_core == MAX_CNT_100MS - 1))||((state_c == NO_RING_MOD2)&&(cnt_core == MAX_CNT_300MS - 1))) ? 1'b1 : 1'b0 ;
    122. // output reg beep_en
    123. always @(posedge sys_clk or negedge sys_rst_n) begin
    124. if(~sys_rst_n)
    125. beep_en <= 1'b1 ;
    126. else if(beep_work) begin
    127. if(state_c == RING)
    128. beep_en <= 1'b1 ;
    129. else
    130. beep_en <= 1'b0 ;
    131. end
    132. else
    133. beep_en <= 1'b0 ;
    134. end
    135. endmodule

    1. module top(
    2. input wire sys_clk ,
    3. input wire sys_rst_n ,
    4. input wire key_in ,
    5. output wire beep
    6. );
    7. // 例化间连线
    8. wire key_flag ;
    9. key_filter key_filter_inst(
    10. .sys_clk ( sys_clk ) ,
    11. .sys_rst_n ( sys_rst_n ) ,
    12. .key_in ( key_in ) ,
    13. .key_flag ( key_flag )
    14. );
    15. beep beep_inst(
    16. .sys_clk ( sys_clk ) ,
    17. .sys_rst_n ( sys_rst_n ) ,
    18. .key_flag ( key_flag ) ,
    19. .beep_en ( beep )
    20. );
    21. endmodule

    1. `timescale 1ns/1ns
    2. module test_top();
    3. reg sys_clk ;
    4. reg sys_rst_n ;
    5. reg key_in ;
    6. wire beep ;
    7. top top_inst(
    8. .sys_clk ( sys_clk ) ,
    9. .sys_rst_n ( sys_rst_n ) ,
    10. .key_in ( key_in ) ,
    11. .beep ( beep )
    12. );
    13. parameter CYCLE = 20 ;
    14. defparam top_inst.key_filter_inst.MAX_CNT_10MS = 50 ;
    15. defparam top_inst.beep_inst.MAX_CNT_100MS = 500 ;
    16. defparam top_inst.beep_inst.MAX_CNT_300MS = 1500 ;
    17. initial begin
    18. sys_clk = 1'b1 ;
    19. sys_rst_n <= 1'b0 ;
    20. key_in <= 1'b1 ;
    21. #( CYCLE * 10 ) ;
    22. sys_rst_n <= 1'b1 ;
    23. #( CYCLE * 10 ) ;
    24. #( CYCLE * 3000 ) ;
    25. #( CYCLE * 500 ) ; // 检测蜂鸣器状态机是否正常工作。
    26. key_in <= 1'b0 ;
    27. #( CYCLE * 50 * 3 ); // 按下足够长的时间,第一次按键按下。
    28. key_in <= 1'b1 ;
    29. #( CYCLE * 3000 ) ;
    30. #( CYCLE * 500 ) ; // 检测蜂鸣器状态机是否正常工作。
    31. key_in <= 1'b0 ;
    32. #( CYCLE * 50 * 3 ); // 按下足够长的时间,第二次按键按下。
    33. key_in <= 1'b1 ;
    34. #( CYCLE * 3000 ) ;
    35. #( CYCLE * 500 ) ; // 检测蜂鸣器状态机是否正常工作。
    36. $stop ;
    37. end
    38. always #( CYCLE / 2 ) sys_clk = ~sys_clk ;
    39. endmodule

    仿真:

  • 相关阅读:
    互联网摸鱼日报(2023-09-22)
    你不应该依赖CSS 100vh,这就是原因
    安利几个堪称黑科技的电脑软件
    FreeSWITCH入门到精通系列(三):FreeSWITCH基础概念与架构
    NLP模型(二)——GloVe介绍
    Bootstrap框架
    PCIe设备的枚举过程
    晶振的等效电路模型
    吐槽 B 站收费,是怪它没钱么?
    导航集成测试
  • 原文地址:https://blog.csdn.net/Meng_long2022/article/details/134296220