//====================================================================
// texture_sampler.v - 纹理采样器
// 第14课：双线性/三线性插值采样
//====================================================================
module texture_sampler #(
    parameter COORD_WIDTH = 16,
    parameter COLOR_WIDTH = 24,
    parameter TEX_SIZE    = 128,
    parameter FRAC_BITS  = 12
)(
    input  wire                          clk, rst_n,
    input  wire                          sample_valid,
    input  wire [COORD_WIDTH-1:0]        sample_u, sample_v,
    input  wire                          bilinear_enable,
    output reg                           sample_ready,
    // 纹理RAM接口
    output reg  [13:0]                   tex_addr,
    output reg                           tex_read,
    input  wire [COLOR_WIDTH-1:0]        tex_data,
    input  wire                          tex_data_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 */

    reg [7:0] c00_r, c00_g, c00_b, c10_r, c10_g, c10_b;
    reg [7:0] c01_r, c01_g, c01_b, c11_r, c11_g, c11_b;
    reg [3:0] frac_u, frac_v;  // 小数部分(4位精度)
    reg [7:0] r0, g0, b0, r1, g1, b1;
    localparam S_IDLE=3'd0, S_FETCH00=3'd1, S_FETCH10=3'd2, S_FETCH01=3'd3, S_FETCH11=3'd4, S_INTERP=3'd5, S_OUT=3'd6;
    reg [2:0] state;
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin state<=S_IDLE; sample_ready<=1; result_valid<=0; end
        else begin
            result_valid <= 0; tex_read <= 0;
            case (state)
                S_IDLE: begin
                    sample_ready <= 1;
                    if (sample_valid) begin
                        sample_ready <= 0;
                        frac_u <= sample_u[3:0]; frac_v <= sample_v[3:0];
                        if (bilinear_enable) begin
                            tex_addr <= sample_v[COORD_WIDTH-1:4] * TEX_SIZE + sample_u[COORD_WIDTH-1:4];
                            tex_read <= 1; state <= S_FETCH00;
                        end else begin
                            tex_addr <= sample_v[COORD_WIDTH-1:4] * TEX_SIZE + sample_u[COORD_WIDTH-1:4];
                            tex_read <= 1; state <= S_FETCH00; // 简化：仍用fetch路径
                        end
                    end
                end
                S_FETCH00: begin
                    if (tex_data_valid) begin
                        c00_r<=tex_data[23:16]; c00_g<=tex_data[15:8]; c00_b<=tex_data[7:0];
                            tex_addr <= sample_v[COORD_WIDTH-1:4]*TEX_SIZE + sample_u[COORD_WIDTH-1:4]+1;
                        tex_read <= 1; state <= S_FETCH10;
                    end
                end
                S_FETCH10: begin
                    if (tex_data_valid) begin
                        c10_r<=tex_data[23:16]; c10_g<=tex_data[15:8]; c10_b<=tex_data[7:0];
                            tex_addr <= (sample_v[COORD_WIDTH-1:4]+1)*TEX_SIZE + sample_u[COORD_WIDTH-1:4];
                        tex_read <= 1; state <= S_FETCH01;
                    end
                end
                S_FETCH01: begin
                    if (tex_data_valid) begin
                        c01_r<=tex_data[23:16]; c01_g<=tex_data[15:8]; c01_b<=tex_data[7:0];
                            tex_addr <= (sample_v[COORD_WIDTH-1:4]+1)*TEX_SIZE + sample_u[COORD_WIDTH-1:4]+1;
                        tex_read <= 1; state <= S_FETCH11;
                    end
                end
                S_FETCH11: begin
                    if (tex_data_valid) begin
                        c11_r<=tex_data[23:16]; c11_g<=tex_data[15:8]; c11_b<=tex_data[7:0];
                        state <= S_INTERP;
                    end
                end
                S_INTERP: begin
                    // 上行插值: r0 = c00*(1-fu) + c10*fu
                    r0 <= (c00_r*(16-frac_u) + c10_r*frac_u) >> 4;
                    g0 <= (c00_g*(16-frac_u) + c10_g*frac_u) >> 4;
                    b0 <= (c00_b*(16-frac_u) + c10_b*frac_u) >> 4;
                    // 下行插值
                    r1 <= (c01_r*(16-frac_u) + c11_r*frac_u) >> 4;
                    g1 <= (c01_g*(16-frac_u) + c11_g*frac_u) >> 4;
                    b1 <= (c01_b*(16-frac_u) + c11_b*frac_u) >> 4;
                    state <= S_OUT;
                end
                S_OUT: begin
                    // 垂直插值: final = r0*(1-fv) + r1*fv
                    result_color <= {
                        (r0*(16-frac_v) + r1*frac_v) >> 4,
                        (g0*(16-frac_v) + g1*frac_v) >> 4,
                        (b0*(16-frac_v) + b1*frac_v) >> 4
                    };
                    result_valid <= 1; state <= S_IDLE;
                end
                default: state <= S_IDLE;
            endcase
        end
    end
endmodule