`timescale 1ns / 1ps
// `default_nettype none
module tb_top_uart_rx_tx;

    // Signaux
    reg clk = 0;
    reg [7:0] data_in = 0;
    wire [7:0] rx_data;           // rx_data est maintenant la donnée reçue
    wire rx_data_valid;           // rx_data_valid est la validité des données reçues
    wire tx;                      // Signal tx à connecter à rx pour le test
    reg rx_data_ready;           // rx_data_ready sert a indiquer de passer à la réception suivante
    reg tx_data_valid;
    reg read_fifo = 0;
     
    // Instance du module à tester
    uart_top top_inst (
        .clk(clk),
        .rst(1'b0),              // Assurez-vous de définir un reset dans le testbench
        .uart_rx(rx),            // Connecte tx au rx pour le test
        .uart_tx(tx),            // Signal de transmission UART
        .rx_data(rx_data),       // Données reçues
        .rx_data_valid(rx_data_valid),  // Données reçues valides
        .rx_data_ready(rx_data_ready),  // Prêt à recevoir (observe ce signal, ne le connecte pas en entrée)
        .tx_data(data_in),       // Données à transmettre
        .tx_data_valid(tx_data_valid),    // Transmission valide (toujours activée dans ce test)
        .tx_data_ready(),         // Prêt pour la transmission (non utilisé dans ce test)
        .read_fifo(read_fifo)

    );

    // Boucle le tx sur rx
    assign rx = tx;


    always #18.5 clk = ~clk;

    // Simulation principale
    initial begin
        $display("Debut de la simulation");
        $dumpfile("uart_loopback.vcd"); // Pour GTKWave
        $dumpvars(0, tb_top_uart_rx_tx);

        // Attendre un peu
        #200;

        rx_data_ready = 1; // Indique que le module est prêt à recevoir des données

        // Envoi d'une valeur
        data_in = 8'hA5;  // Exemple de data
        tx_data_valid = 1; 
        #20; 
        tx_data_valid = 0; 
        rx_data_ready = 0; // Indique que le module n'est pas prêt à recevoir des données
        
        #200;

        // Attendre la réception (valeur valid = 1)
        $display("Attente de rx_data_valid");
        wait(rx_data_valid == 1);

        read_fifo = 1; // Indique que la FIFO doit être lue

        // Affichage des résultats
        $display("Data envoyee : 0x%h", data_in);
        $display("Data recue   : 0x%h", rx_data);

        read_fifo = 0; // Réinitialiser le signal de lecture de FIFO

        if (rx_data == data_in)
            $display("Test reussi !");
        else
            $display("Test echoue...");

        // Fin de simulation
        #200;
        $finish;
    end

endmodule
