button.v 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. module debouncer#(
  2. parameter WIDTH = 4,
  3. parameter LAG = 10
  4. )(
  5. input wire clk,
  6. input wire nrst,
  7. input wire debounce_tick, //1kHz
  8. input wire butt,
  9. output reg filtered
  10. );
  11. reg [WIDTH-1:0] cnt;
  12. reg prev_butt;
  13. reg butt_buff;//just to make button synced with clock
  14. always @(posedge clk or negedge nrst) begin
  15. if(!nrst) begin
  16. cnt<=LAG;
  17. butt_buff<=0;
  18. prev_butt<=0;
  19. filtered<=0;
  20. end else if (debounce_tick) begin
  21. if (prev_butt == butt_buff) begin
  22. if (cnt) begin
  23. cnt <= cnt-1;
  24. end else begin
  25. filtered <= butt_buff;
  26. end
  27. end else begin
  28. cnt <= LAG;
  29. end
  30. prev_butt <= butt_buff;
  31. butt_buff <= butt;
  32. end
  33. end
  34. endmodule
  35. module button#(
  36. parameter WIDTH = 5,
  37. parameter DEBOUNCE_LAG = 10, //250000 = 10ms
  38. parameter FIRST_CLICK = 25,//100ms
  39. parameter FREQ_START = 31,//(1/f) 3Hz -> 333ms rounded down to 310ms to reduce bits
  40. //parameter FREQ_DECREMENT = 12,// hardcoded -> percentage * 16: 12 -> 12/16 = 75% of prev each loop
  41. parameter FREQ_MAX = 5 //(1/f) 20Hz -> 50ms
  42. )(
  43. input wire clk, //25MHz
  44. input wire nrst,
  45. input wire debounce_tick, //100Hz
  46. input wire cnt_tick, //1kHz
  47. input wire butt,
  48. output reg [7:0] press_count
  49. );
  50. reg butt_filt;
  51. reg [WIDTH-1:0] time_cntr;
  52. //reg [WIDTH-1:0] curr_period;
  53. reg [WIDTH-1:0] next_period;
  54. reg [WIDTH-1:0] period_decremented;
  55. reg is_pressed;
  56. reg if_increment;
  57. debouncer#(.LAG(DEBOUNCE_LAG)) deb(
  58. .clk(clk),
  59. .nrst(nrst),
  60. .debounce_tick(debounce_tick),
  61. .butt(butt),
  62. .filtered(butt_filt)
  63. );
  64. always @(posedge clk or negedge nrst) begin
  65. if(!nrst) begin
  66. press_count<=0;
  67. time_cntr<=FIRST_CLICK;
  68. next_period<=FREQ_START;
  69. is_pressed<=0;
  70. if_increment<=0;
  71. end else if (cnt_tick) begin
  72. if_increment <= 0;
  73. if(is_pressed) begin
  74. if (time_cntr==0) begin
  75. if_increment <= 1;
  76. time_cntr <= next_period;
  77. if (period_decremented < FREQ_MAX) begin
  78. next_period <= FREQ_MAX;
  79. end else begin
  80. next_period <= period_decremented;
  81. end
  82. end else begin
  83. time_cntr <= time_cntr-1;
  84. end
  85. end else begin
  86. time_cntr<=FIRST_CLICK;
  87. next_period<=FREQ_START;
  88. end
  89. is_pressed <= butt_filt;
  90. press_count <= press_count + (if_increment | (!is_pressed & butt_filt));
  91. //period_decremented <= (next_period>>4)*FREQ_DECREMENT; // we loose some prec here, but who cares with this time resolution
  92. //12=0b1100
  93. period_decremented <= ({next_period,1'h0} + {1'h0,next_period})>>2;
  94. end
  95. end
  96. endmodule