// ============================================================================
// ca_music.v - CA音乐合成引擎
// 将CA状态映射为MIDI音符序列
// 支持：音阶选择、节奏控制、力度映射
// ============================================================================
module ca_music #(
    parameter WIDTH  = 32,          // 32列 = 32个音高
    parameter SCALE  = 0            // 0=大调 1=小调 2=五声 3=半音
)(
    input  wire             clk,
    input  wire             rst_n,
    input  wire             step_en,      // 步进（每步=一个节拍）
    input  wire [WIDTH-1:0] ca_row,       // CA当前行
    input  wire [3:0]       octave,       // 八度选择
    input  wire [7:0]       tempo,        // 速度（BPM）
    output wire [6:0]       midi_note,    // MIDI音符号
    output wire [6:0]       midi_velocity,// 力度
    output wire             note_valid,   // 音符有效脉冲
    output wire [WIDTH-1:0] chord_out     // 和弦输出（同时发声的音符掩码）
);

    // ---- 音阶映射 ----
    // 将32列映射到特定音阶的音符
    reg [4:0] note_map [0:WIDTH-1];

    always @(*) begin
        case (SCALE)
            0: begin  // C大调：C D E F G A B
                note_map[0]  = 5'd0;   // C
                note_map[1]  = 5'd2;   // D
                note_map[2]  = 5'd4;   // E
                note_map[3]  = 5'd5;   // F
                note_map[4]  = 5'd7;   // G
                note_map[5]  = 5'd9;   // A
                note_map[6]  = 5'd11;  // B
                note_map[7]  = 5'd12;  // C(高八度)
                // 重复...
            end
            1: begin  // A小调
                note_map[0] = 5'd9;   // A
                note_map[1] = 5'd11;  // B
                note_map[2] = 5'd0;   // C
                note_map[3] = 5'd2;   // D
                note_map[4] = 5'd4;   // E
                note_map[5] = 5'd5;   // F
                note_map[6] = 5'd7;   // G
                note_map[7] = 5'd9;   // A(高)
            end
            default: begin  // 半音阶
                for (integer i = 0; i < WIDTH; i = i + 1)
                    note_map[i] = i % 12;
            end
        endcase
    end

    // ---- 和弦检测 ----
    assign chord_out = ca_row;  // 所有活元胞同时发声

    // ---- 主旋律提取 ----
    // 取最左边的活元胞作为主旋律
    reg [4:0] melody_idx;
    integer j;
    always @(*) begin
        melody_idx = 5'd0;
        for (j = 0; j < WIDTH; j = j + 1) begin
            if (ca_row[j]) begin
                melody_idx = j[4:0];
            end
        end
    end

    // ---- MIDI音符生成 ----
    assign midi_note = octave * 12 + note_map[melody_idx];

    // ---- 力度计算 ----
    // 力度 = 活元胞数 / 总列数 * 127
    reg [6:0] vel;
    integer k;
    always @(*) begin
        vel = 7'd0;
        for (k = 0; k < WIDTH; k = k + 1)
            vel = vel + ca_row[k];
    end
    assign midi_velocity = (vel > 7'd100) ? 7'd100 : vel;

    assign note_valid = step_en;

endmodule