`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2026/04/03 22:09:36
// Design Name: 
// Module Name: tb_diginal_top
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module tb_diginal_top();

    reg clk;
    reg rst_n;
    wire uart_tx;
    reg uart_rx;

    parameter CLK_PERIOD = 20;     // 50MHz
    parameter BAUD       = 115200; // 提高波特率加快仿真
    localparam BIT_TIME  = 1_000_000_000 / BAUD; // 计算1比特持续的ns数

    initial clk = 0;
    always #(CLK_PERIOD/2) clk = ~clk;

    digital_top u_digital_top(
        .clk(clk),
        .rst_n(rst_n),
        .uart_rx(uart_rx),
        .uart_tx(uart_tx)
    );

        // ============================================================
    // 模拟上位机：字节发送任务 (Serial UART TX)
    // ============================================================
    task send_byte;
        input [7:0] data;
        integer i;
        begin
            uart_rx = 0; // 起始位
            #(BIT_TIME);
            for (i = 0; i < 8; i = i + 1) begin
                uart_rx = data[i]; // 数据位 (LSB first)
                #(BIT_TIME);
            end
            uart_rx = 1; // 停止位
            #(BIT_TIME);
            #(BIT_TIME); // 字节间隙
        end
    endtask

    // 发送 32 位数据 (拆分为 4 个字节)
    task send_32bit;
        input [31:0] data;
        begin
            // 注意：这里发送顺序要和你的串口接收模块端序一致
            // 假设小端发送：先发 [7:0]
            send_byte(data[7:0]);
            send_byte(data[15:8]);
            send_byte(data[23:16]);
            send_byte(data[31:24]);
        end
    endtask

    integer file_ptr;
    integer status;
    reg [63:0] temp_cmd;
    reg [31:0] temp_data;
    
    initial begin
        // 初始化
        rst_n = 0;
        uart_rx = 1;
        #(CLK_PERIOD * 10);
        rst_n = 1;
        #(CLK_PERIOD * 100);

        // 打开测试文件
        file_ptr = $fopen("D:/shortname/thermometer/try/test_cases.txt", "r");
        if (file_ptr == 0) begin
            $display("====Error: can not open test_cases.txt file!===");
            $finish;
        end

        $display("======= Begin Send Case =======");

        while (!$feof(file_ptr)) begin
            // 尝试读取一行（先尝试按 64 位 CMD 读取）
            status = $fscanf(file_ptr, "%h\n", temp_cmd);
            
            if (status == 1) begin
                if (temp_cmd > 64'hFFFF_FFFF) begin
                    // 如果读到的是 64 位，认为是 CMD
                    $display("[%t] Send command frame: 0x%h", $time, temp_cmd);
                    send_32bit(temp_cmd[63:32]); // 先发高32位
                    send_32bit(temp_cmd[31:0]);  // 再发低32位
                end else begin
                    // 如果读到的是 32 位，认为是 DATA
                    $display("[%t] Send data stream: 0x%h", $time, temp_cmd[31:0]);
                    send_32bit(temp_cmd[31:0]);
                end
            end
            #(BIT_TIME * 20); // 指令/数据组之间的间隔
        end

        $display("======= All Cases Sent =======");
        $fclose(file_ptr);
        
        #(BIT_TIME * 200);
        $stop;
    end
endmodule
