module button_counter (
input wire clk,
input wire rst,
input wire btn,
output reg [6:0] seg,
output reg [3:0] an
);
// Синхронизация кнопки
reg btn_sync1 = 0;
reg btn_sync2 = 0;
// Антидребезг: 20 мс при 50 МГц
reg [19:0] debounce_cnt = 0;
reg btn_stable = 0;
reg btn_stable_prev = 0;
// Счётчик
reg [3:0] count = 0;
// Делитель для мультиплексирования индикатора
reg [15:0] refresh_cnt = 0;
reg [1:0] digit = 0;
reg [3:0] current_digit;
// Синхронизация входа кнопки
always @(posedge clk) begin
btn_sync1 <= btn;
btn_sync2 <= btn_sync1;
end
// Антидребезг
always @(posedge clk) begin
if (rst) begin
debounce_cnt <= 0;
btn_stable <= 0;
btn_stable_prev <= 0;
end else begin
btn_stable_prev <= btn_stable;
if (btn_sync2 != btn_stable) begin
if (debounce_cnt == 20'd999999) begin
btn_stable <= btn_sync2;
debounce_cnt <= 0;
end else begin
debounce_cnt <= debounce_cnt + 1'b1;
end
end else begin
debounce_cnt <= 0;
end
end
end
// Изменение счётчика только по фронту нажатия
always @(posedge clk) begin
if (rst) begin
count <= 0;
end else if (btn_stable && !btn_stable_prev) begin
count <= count + 1'b1;
end
end
// Переключение разрядов индикатора
always @(posedge clk) begin
refresh_cnt <= refresh_cnt + 1'b1;
if (refresh_cnt == 16'd50000) begin
refresh_cnt <= 0;
digit <= digit + 1'b1;
end
end
// Выбор разряда
always @(*) begin
case (digit)
2'd0: begin
an = 4'b1110;
current_digit = count;
end
2'd1: begin
an = 4'b1111;
current_digit = 4'd0;
end
2'd2: begin
an = 4'b1111;
current_digit = 4'd0;
end
2'd3: begin
an = 4'b1111;
current_digit = 4'd0;
end
default: begin
an = 4'b1111;
current_digit = 4'd0;
end
endcase
end
// Декодер семисегментного индикатора
always @(*) begin
case (current_digit)
4'd0: seg = 7'b1000000;
4'd1: seg = 7'b1111001;
4'd2: seg = 7'b0100100;
4'd3: seg = 7'b0110000;
4'd4: seg = 7'b0011001;
4'd5: seg = 7'b0010010;
4'd6: seg = 7'b0000010;
4'd7: seg = 7'b1111000;
4'd8: seg = 7'b0000000;
4'd9: seg = 7'b0010000;
4'd10: seg = 7'b0001000;
4'd11: seg = 7'b0000011;
4'd12: seg = 7'b1000110;
4'd13: seg = 7'b0100001;
4'd14: seg = 7'b0000110;
4'd15: seg = 7'b0001110;
default: seg = 7'b1111111;
endcase
end
endmodule