//====================================================================
// mipmap_generator.v - Mipmap生成器
// 第15课：多级纹理生成与选择
//====================================================================
module mipmap_generator #(
    parameter COORD_WIDTH = 16,
    parameter COLOR_WIDTH = 24,
    parameter TEX_SIZE    = 128,
    parameter MAX_LEVEL   = 7,
    parameter FRAC_BITS  = 12
)(
    input  wire                          clk, rst_n,
    input  wire                          level_valid,
    input  wire [2:0]                    level,
    input  wire [COORD_WIDTH-1:0]        u, v,
    output reg  [2:0]                    sel_level,
    output reg                           level_ready,
    output reg  [13:0]                   tex_addr,
    output reg                           tex_req,
    input  wire [COLOR_WIDTH-1:0]        tex_data,
    input  wire                          tex_valid,
    output reg                           result_valid,
    output reg  [COLOR_WIDTH-1:0]        result_color
);
/* verilator lint_off WIDTHEXPAND */
/* verilator lint_off WIDTHTRUNC */
/* verilator lint_off CASEOVERLAP */
/* verilator lint_off CMPCONST */
/* verilator lint_off UNSIGNED */
/* verilator lint_off WIDTHCONCAT */

    // Mipmap级别选择：基于屏幕空间导数
    // 简化：直接使用输入level
    reg [COORD_WIDTH-1:0] shifted_u, shifted_v;
    always @(*) begin
        shifted_u = u >> level;
        shifted_v = v >> level;
    end
    localparam S_IDLE=2'd0, S_REQ=2'd1, S_WAIT=2'd2, S_OUT=2'd3;
    reg [1:0] state;
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin state<=S_IDLE; level_ready<=1; result_valid<=0; tex_req<=0; end
        else begin
            result_valid <= 0; tex_req <= 0;
            case (state)
                S_IDLE: begin
                    level_ready <= 1;
                    if (level_valid) begin
                        level_ready <= 0;
                        sel_level <= level;
                        tex_addr <= (shifted_v[COORD_WIDTH-1:4] * (TEX_SIZE >> level)) + shifted_u[COORD_WIDTH-1:4];
                        state <= S_REQ;
                    end
                end
                S_REQ: begin
                    tex_req <= 1; state <= S_WAIT;
                end
                S_WAIT: begin
                    if (tex_valid) begin
                        result_color <= tex_data;
                        state <= S_OUT;
                    end
                end
                S_OUT: begin
                    result_valid <= 1; state <= S_IDLE;
                end
                default: state <= S_IDLE;
            endcase
        end
    end
endmodule