// Integration proof for the runtime CLUT writer mux in the BRAM board top.
`timescale 1ns/1ps

module tb_top_psmct32_runtime_clut;
    logic clk = 1'b0;
    always #5 clk = ~clk;
    logic rst_n, core_go;
    logic runtime_wr_en, runtime_busy;
    logic [7:0] runtime_wr_idx;
    logic [31:0] runtime_wr_data;
    logic [7:0] r,g,b;
    logic hsync,vsync,de,core_halt,dma_done_seen,frame_seen,raster_overflow,frame_toggle,dma_done_toggle;
    int errors;

    top_psmct32_raster_demo_bram #(.PSMCT32_SWIZZLE(1'b0)) dut (
        .clk, .rst_n, .core_go, .r, .g, .b, .hsync, .vsync, .de,
        .core_halt, .dma_done_seen, .frame_seen, .raster_overflow,
        .frame_toggle, .dma_done_toggle,
        .joy_a_pressed_i(1'b0), .joy_b_pressed_i(1'b0),
        .runtime_clut_wr_en_i(runtime_wr_en),
        .runtime_clut_wr_idx_i(runtime_wr_idx),
        .runtime_clut_wr_data_i(runtime_wr_data),
        .runtime_clut_busy_i(runtime_busy)
    );

    task automatic runtime_write(input logic [7:0] idx, input logic [31:0] data);
        @(posedge clk);
        runtime_wr_idx  <= idx;
        runtime_wr_data <= data;
        runtime_wr_en   <= 1'b1;
        @(posedge clk);
        runtime_wr_en   <= 1'b0;
    endtask

    task automatic check(input string label, input logic [31:0] got, input logic [31:0] want);
        if (got !== want) begin
            $error("[%s] got 0x%08x expected 0x%08x",label,got,want);
            errors = errors + 1;
        end
    endtask

    initial begin
        rst_n=0; core_go=0; runtime_wr_en=0; runtime_wr_idx=0; runtime_wr_data=0; runtime_busy=0; errors=0;
        repeat(4) @(posedge clk);
        rst_n=1;
        runtime_write(8'h00,32'h10203040);
        runtime_write(8'h37,32'hA1B2C3D4);
        runtime_write(8'hFF,32'h55667788);
        repeat(2) @(posedge clk);
        check("clut[0]",dut.u_clut.mem[0],32'h10203040);
        check("clut[55]",dut.u_clut.mem[8'h37],32'hA1B2C3D4);
        check("clut[255]",dut.u_clut.mem[8'hFF],32'h55667788);
        runtime_busy=1;
        repeat(2) @(posedge clk);
        if (dut.clut_busy !== 1'b1) begin $error("runtime busy did not stall CLUT consumer"); errors=errors+1; end
        if(errors) $fatal(1,"tb_top_psmct32_runtime_clut FAILED: %0d errors",errors);
        $display("tb_top_psmct32_runtime_clut PASS: writer mux + busy gate");
        $finish;
    end
endmodule
