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


// ==========================================================================
// multi_melody_player_final
// Полностью рабочий: 8 мелодий, 7-сегм. индикация, кнопки выбора,
// антидребезг, коррекция пауз, автосброс при переключении.
// Исправлен конфликт драйверов step.
// ==========================================================================
module multi_melody_player_final #(
    parameter SEG_ANODE = 1'b0  // 1 - общий анод (инвертировать), 0 - общий катод
)(
    input  wire         clk,
    input  wire [7:0]   btn,          // активный 0
    output wire [7:0]   led,
    output wire [7:0]   dig0, dig1, dig2, dig3,
    output wire         speaker
);

// --------------------------------------------------------------------------
// Антидребезг и детектор фронта нажатия кнопок
// --------------------------------------------------------------------------
reg [7:0] btn_sync0, btn_sync1;
reg [3:0] btn_cnt [0:7];
wire [7:0] btn_pressed;  // импульс 1 такт при стабильном нажатии
genvar i;
generate for (i = 0; i < 8; i = i + 1) begin : debounce
    always @(posedge clk) begin
        btn_sync0 <= ~btn;   // инвертируем: 1 = нажата
        btn_sync1 <= btn_sync0;
        if (btn_sync1[i]) begin
            if (btn_cnt[i] < 10)
                btn_cnt[i] <= btn_cnt[i] + 1'b1;
        end else begin
            btn_cnt[i] <= 4'd0;
        end
    end
    assign btn_pressed[i] = (btn_cnt[i] == 4'd10); // 1 такт при достижении порога
end
endgenerate

// --------------------------------------------------------------------------
// Единый блок управления: мелодия, шаг и темп
// --------------------------------------------------------------------------
localparam [23:0] TEMPO_MAX = 24'd2_999_999;  // 0.25 сек (1/16 при ♩=60)
reg [2:0] melody = 3'd0;
reg [7:0] step = 8'd0;           // 0..255
reg [23:0] tempo_cnt = 0;

always @(posedge clk) begin
    // Приоритетная обработка нажатий кнопок (сброс и выбор мелодии)
    if (btn_pressed[0]) begin
        melody <= 3'd0;
        step <= 8'd0;
        tempo_cnt <= 0;
    end else if (btn_pressed[1]) begin
        melody <= 3'd1;
        step <= 8'd0;
        tempo_cnt <= 0;
    end else if (btn_pressed[2]) begin
        melody <= 3'd2;
        step <= 8'd0;
        tempo_cnt <= 0;
    end else if (btn_pressed[3]) begin
        melody <= 3'd3;
        step <= 8'd0;
        tempo_cnt <= 0;
    end else if (btn_pressed[4]) begin
        melody <= 3'd4;
        step <= 8'd0;
        tempo_cnt <= 0;
    end else if (btn_pressed[5]) begin
        melody <= 3'd5;
        step <= 8'd0;
        tempo_cnt <= 0;
    end else if (btn_pressed[6]) begin
        melody <= 3'd6;
        step <= 8'd0;
        tempo_cnt <= 0;
    end else if (btn_pressed[7]) begin
        melody <= 3'd7;
        step <= 8'd0;
        tempo_cnt <= 0;
    end else begin
        // Работа темпового генератора
        if (tempo_cnt == TEMPO_MAX) begin
            tempo_cnt <= 0;
            step <= step + 1'b1;
        end else begin
            tempo_cnt <= tempo_cnt + 1'b1;
        end
    end
end

// --------------------------------------------------------------------------
// ПЗУ мелодий (8 мелодий, шаг 0..255, код ноты 0..15)
// --------------------------------------------------------------------------
reg [3:0] note;
always @* begin
    case(melody)
        // Мелодия 0: Дебюсси – заполните по желанию
        3'd0: note = 4'd0;

        // Мелодия 1: Ода к радости (расширенная)
        3'd1: case(step)
            8'd0,8'd1: note = 4'd3;     // E4
            8'd2,8'd3: note = 4'd3;
            8'd4,8'd5: note = 4'd4;     // F4
            8'd6,8'd7: note = 4'd5;     // G4
            8'd8,8'd9: note = 4'd5;
            8'd10,8'd11: note = 4'd4;
            8'd12,8'd13: note = 4'd3;
            8'd14,8'd15: note = 4'd2;   // D4
            8'd16,8'd17: note = 4'd1;   // C4
            8'd18,8'd19: note = 4'd1;
            8'd20,8'd21: note = 4'd2;
            8'd22,8'd23: note = 4'd3;
            8'd24,8'd25: note = 4'd3;
            8'd26,8'd27: note = 4'd2;
            8'd28,8'd29: note = 4'd2;
            default: note = 4'd0;
        endcase

        // Мелодия 2: Happy Birthday
        3'd2: case(step)
            8'd0,8'd1: note = 4'd5;
            8'd2,8'd3: note = 4'd5;
            8'd4,8'd5: note = 4'd6;
            8'd6,8'd7: note = 4'd5;
            8'd8,8'd9,8'd10,8'd11: note = 4'd8;    // C5
            8'd12,8'd13,8'd14,8'd15: note = 4'd7;  // B4
            8'd16,8'd17: note = 4'd5;
            8'd18,8'd19: note = 4'd5;
            8'd20,8'd21: note = 4'd6;
            8'd22,8'd23: note = 4'd5;
            8'd24,8'd25,8'd26,8'd27: note = 4'd9;  // D5
            8'd28,8'd29,8'd30,8'd31: note = 4'd8;  // C5
            8'd32,8'd33: note = 4'd5;
            8'd34,8'd35: note = 4'd5;
            8'd36,8'd37: note = 4'd3;   // E4
            8'd38,8'd39: note = 4'd8;
            8'd40,8'd41: note = 4'd7;
            8'd42,8'd43: note = 4'd6;
            8'd44,8'd45,8'd46,8'd47: note = 4'd0; // пауза
            8'd48,8'd49: note = 4'd4;  // F4
            8'd50,8'd51: note = 4'd4;
            8'd52,8'd53: note = 4'd3;
            8'd54,8'd55,8'd56,8'd57: note = 4'd8;
            8'd58,8'd59: note = 4'd9;
            8'd60,8'd61,8'd62,8'd63: note = 4'd8;
            default: note = 4'd0;
        endcase

        // Мелодия 3: Имперский марш (упрощённый)
        3'd3: case(step)
            8'd0: note = 4'd3; // E4
            8'd1: note = 4'd3;
            8'd2: note = 4'd3;
            8'd3,8'd4: note = 4'd1; // C4
            8'd5: note = 4'd5; // G4
            8'd6: note = 4'd3;
            8'd7,8'd8: note = 4'd1;
            8'd9: note = 4'd5;
            8'd10: note = 4'd3;
            default: note = 4'd0;
        endcase

        // Мелодия 4: Jingle Bells (куплет)
        3'd4: case(step)
            8'd0,8'd1: note = 4'd3; 8'd2,8'd3: note = 4'd3; 8'd4,8'd5: note = 4'd3;
            8'd6,8'd7: note = 4'd3; 8'd8,8'd9: note = 4'd3; 8'd10,8'd11: note = 4'd3;
            8'd12,8'd13: note = 4'd3; 8'd14,8'd15: note = 4'd5; // G4
            8'd16,8'd17: note = 4'd1; // C4
            8'd18,8'd19: note = 4'd2; // D4
            8'd20,8'd21: note = 4'd3;
            default: note = 4'd0;
        endcase

        // Мелодия 5: Маленькая ночная серенада
        3'd5: case(step)
            8'd0: note = 4'd5; 8'd1,8'd2: note = 4'd2; 8'd3: note = 4'd3;
            8'd4: note = 4'd4; 8'd5: note = 4'd3; 8'd6: note = 4'd2;
            8'd7: note = 4'd1; 8'd8: note = 4'd2; 8'd9: note = 4'd3;
            8'd10: note = 4'd4; 8'd11: note = 4'd3; 8'd12: note = 4'd2;
            8'd13: note = 4'd1;
            default: note = 4'd0;
        endcase

        // Мелодия 6: Yesterday
        3'd6: case(step)
            8'd0: note = 4'd4; 8'd1: note = 4'd3; 8'd2: note = 4'd3;
            8'd3: note = 4'd4; 8'd4,8'd5: note = 4'd5; 8'd6,8'd7: note = 4'd6;
            8'd8: note = 4'd5; 8'd9: note = 4'd4; 8'd10: note = 4'd3;
            8'd11: note = 4'd2; 8'd12: note = 4'd1;
            default: note = 4'd0;
        endcase

        // Мелодия 7: Тетрис (Коробейники)
        3'd7: case(step)
            8'd0: note = 4'd3; 8'd1: note = 4'd7; 8'd2: note = 4'd8;
            8'd3: note = 4'd9; 8'd4: note = 4'd10; 8'd5: note = 4'd9;
            8'd6: note = 4'd8; 8'd7: note = 4'd7; 8'd8: note = 4'd6;
            8'd9: note = 4'd6; 8'd10: note = 4'd8; 8'd11: note = 4'd10;
            8'd12: note = 4'd9; 8'd13: note = 4'd8; 8'd14: note = 4'd7;
            default: note = 4'd0;
        endcase

        default: note = 4'd0;
    endcase
end

// --------------------------------------------------------------------------
// Делители частоты (таблица 16 нот)
// --------------------------------------------------------------------------
reg [15:0] divider;
always @* begin
    case(note)
        4'd0: divider = 16'd0;
        4'd1: divider = 16'h5996; // C4
        4'd2: divider = 16'h4FD2; // D4
        4'd3: divider = 16'h471A; // E4
        4'd4: divider = 16'h431F; // F4
        4'd5: divider = 16'h3BCA; // G4
        4'd6: divider = 16'h3544; // A4
        4'd7: divider = 16'h2F74; // B4
        4'd8: divider = 16'h2CCB; // C5
        4'd9: divider = 16'h27E9; // D5
        4'd10: divider = 16'h238D; // E5
        4'd11: divider = 16'h218F; // F5
        4'd12: divider = 16'h1DE5; // G5
        4'd13: divider = 16'h1AA2; // A5
        4'd14: divider = 16'h3245; // Bb4
        4'd15: divider = 16'h5490; // C#4 (Db4)
        default: divider = 16'd0;
    endcase
end

// --------------------------------------------------------------------------
// Генератор звука (меандр с паузой)
// --------------------------------------------------------------------------
reg [15:0] cnt = 0;
reg spk = 0;
always @(posedge clk) begin
    if (divider == 16'd0) begin
        cnt <= 0;
        spk <= 1'b0;
    end else begin
        if (cnt == 16'd0) begin
            cnt <= divider;
            spk <= ~spk;
        end else begin
            cnt <= cnt - 1'b1;
        end
    end
end
assign speaker = spk;

// --------------------------------------------------------------------------
// LED индикация
// --------------------------------------------------------------------------
assign led = {melody, step[4:0]};

// --------------------------------------------------------------------------
// 7-сегментная индикация (dig0..dig3)
// --------------------------------------------------------------------------
wire [3:0] d3 = {1'b0, melody};   // номер мелодии
wire [3:0] d2 = note;            // код ноты
reg  [3:0] octave;
always @* begin
    case(note)
        4'd1,4'd2,4'd3,4'd4,4'd5,4'd6,4'd7,4'd14,4'd15: octave = 4'd4;
        4'd8,4'd9,4'd10,4'd11,4'd12,4'd13: octave = 4'd5;
        default: octave = 4'd10; // '-'
    endcase
end
wire [3:0] d1 = octave;
wire [3:0] d0 = (note == 4'd0) ? 4'd16 : 4'd15; // 16 -> 'P', 15 -> пусто

// Дешифратор 5 бит -> 8 бит сегментов (a - младший бит)
function [7:0] seg_decode;
    input [4:0] sym;
    reg [7:0] code;
    begin
        case(sym)
            5'd0: code = 8'b00111111; // 0
            5'd1: code = 8'b00000110; // 1
            5'd2: code = 8'b01011011; // 2
            5'd3: code = 8'b01001111; // 3
            5'd4: code = 8'b01100110; // 4
            5'd5: code = 8'b01101101; // 5
            5'd6: code = 8'b01111101; // 6
            5'd7: code = 8'b00000111; // 7
            5'd8: code = 8'b01111111; // 8
            5'd9: code = 8'b01101111; // 9
            5'd10: code = 8'b01000000; // '-'
            5'd11: code = 8'b00000000; // пусто
            5'd12: code = 8'b00000000;
            5'd13: code = 8'b00000000;
            5'd14: code = 8'b00000000;
            5'd15: code = 8'b00000000; // пусто
            5'd16: code = 8'b01110011; // P
            default: code = 8'b00000000;
        endcase
        if (SEG_ANODE)
            code = ~code;
        seg_decode = code;
    end
endfunction

assign dig0 = seg_decode({1'b0, d0});
assign dig1 = seg_decode({1'b0, d1});
assign dig2 = seg_decode({1'b0, d2});
assign dig3 = seg_decode({1'b0, d3});

endmodule