//====================================================================
// matrix_transform.v - 矩阵变换单元
// 第07课：平移/旋转/缩放矩阵生成与组合
//====================================================================
module matrix_transform #(
    parameter COORD_WIDTH = 16,
    parameter FRAC_BITS  = 12
)(
    input  wire                          clk, rst_n,
    input  wire                          transform_valid,
    input  wire [2:0]                    transform_type,
    input  wire signed [COORD_WIDTH-1:0] param_x, param_y, param_z,
    output reg                           mat_valid,
    output reg  signed [COORD_WIDTH-1:0] mat_out_00, mat_out_01, mat_out_02, mat_out_03,
    output reg  signed [COORD_WIDTH-1:0] mat_out_10, mat_out_11, mat_out_12, mat_out_13,
    output reg  signed [COORD_WIDTH-1:0] mat_out_20, mat_out_21, mat_out_22, mat_out_23,
    output reg  signed [COORD_WIDTH-1:0] mat_out_30, mat_out_31, mat_out_32, mat_out_33
);
/* verilator lint_off WIDTHEXPAND */
/* verilator lint_off WIDTHTRUNC */
/* verilator lint_off CASEOVERLAP */
/* verilator lint_off CMPCONST */
/* verilator lint_off UNSIGNED */
/* verilator lint_off WIDTHCONCAT */

    function signed [COORD_WIDTH-1:0] qmul;
        input signed [COORD_WIDTH-1:0] a, b;
        reg signed [2*COORD_WIDTH-1:0] prod;
        begin prod = a * b; qmul = prod[2*COORD_WIDTH-FRAC_BITS-1:COORD_WIDTH-FRAC_BITS]; end
    endfunction
    reg signed [COORD_WIDTH-1:0] sin_val, cos_val;
    reg signed [COORD_WIDTH-1:0] sin_lut [0:15];
    initial begin
        sin_lut[0]=0; sin_lut[1]=402; sin_lut[2]=800; sin_lut[3]=1189;
        sin_lut[4]=1564; sin_lut[5]=1918; sin_lut[6]=2247; sin_lut[7]=2547;
        sin_lut[8]=2812; sin_lut[9]=3038; sin_lut[10]=3221; sin_lut[11]=3359;
        sin_lut[12]=3450; sin_lut[13]=3497; sin_lut[14]=3497; sin_lut[15]=3450;
    end
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin mat_valid <= 0; end
        else begin
            mat_valid <= 0;
            if (transform_valid) begin
                mat_out_00<=0; mat_out_01<=0; mat_out_02<=0; mat_out_03<=0;
                mat_out_10<=0; mat_out_11<=0; mat_out_12<=0; mat_out_13<=0;
                mat_out_20<=0; mat_out_21<=0; mat_out_22<=0; mat_out_23<=0;
                mat_out_30<=0; mat_out_31<=0; mat_out_32<=0; mat_out_33<=16'h1000;
                case (transform_type)
                    3'd0: begin // 平移
                        mat_out_00<=16'h1000; mat_out_11<=16'h1000; mat_out_22<=16'h1000;
                        mat_out_03<=param_x; mat_out_13<=param_y; mat_out_23<=param_z;
                    end
                    3'd1: begin // 缩放
                        mat_out_00<=param_x; mat_out_11<=param_y; mat_out_22<=param_z;
                    end
                    3'd4: begin // 绕Z轴旋转
                        sin_val <= sin_lut[param_x[5:2]];
                        cos_val <= sin_lut[(16 - param_x[5:2]) % 16];
                        mat_out_00 <= cos_val; mat_out_01 <= -sin_val;
                        mat_out_10 <= sin_val; mat_out_11 <= cos_val;
                        mat_out_22 <= 16'h1000;
                    end
                    default: begin mat_out_00<=16'h1000; mat_out_11<=16'h1000; mat_out_22<=16'h1000; end
                endcase
                mat_valid <= 1;
            end
        end
    end
endmodule