`timescale 1ns / 1ps

module tb_uart_rx;

    reg clk = 0;
    reg rx = 1;  
    wire [7:0] data;
    wire valid;
    wire ready;

    localparam CLK_FREQ = 27_000_000;
    localparam BAUD_RATE = 115_200;
    localparam BIT_PERIOD = CLK_FREQ / BAUD_RATE; 
    localparam CLK_PERIOD_NS = 1000000000 / CLK_FREQ; 

    uart_rx #(
        .CLK_FREQ(CLK_FREQ),
        .BAUD_RATE(BAUD_RATE)
    ) rx_instance (
        .clk(clk),
        .rx(rx),
        .data(data),
        .valid(valid),
        .ready(ready)
    );

    always #(CLK_PERIOD_NS/2) clk = ~clk;

    task send_bit(input reg b);
        begin
            rx <= b;
            #(BIT_PERIOD * CLK_PERIOD_NS); 
        end
    endtask

    integer i;

    task send_byte(input [7:0] byte);
        begin
            send_bit(0); 
            for (i = 0; i < 8; i = i + 1)
                send_bit(byte[i]); 
            send_bit(1); 
            
            #(BIT_PERIOD * CLK_PERIOD_NS);
        end
    endtask

    initial begin
        $display("Start UART RX test");
        #100; 

        send_byte(8'b01010101); 

        #(10 * BIT_PERIOD * CLK_PERIOD_NS);

        if (valid && data == 8'b01010101)
            $display("Test ok : data = %b", data);
        else
            $display("Test pas ok : data = %b, valid = %b", data, valid);

        $finish;
    end
endmodule
