Загрузка данных


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