`timescale 1ns / 1ps ////////////////////////////////////////////////////////////////////////////////// // Company: // Engineer: // // Create Date: 2026/03/31 13:01:26 // Design Name: // Module Name: tb_uart_ctrl_sysreg // Project Name: // Target Devices: // Tool Versions: // Description: // // Dependencies: // // Revision: // Revision 0.01 - File Created // Additional Comments: // ////////////////////////////////////////////////////////////////////////////////// `timescale 1ns / 1ps module tb_uart_ctrl_sysreg(); // --- 参数与信号 --- parameter CLK_PERIOD = 20; // 50MHz parameter BAUD = 115200; // 提高波特率加快仿真 localparam BIT_TIME = 1_000_000_000 / BAUD; // 计算1比特持续的ns数 // 端口信号 reg clk; reg rst_n; reg uart_rx; // 发给 DUT 的 UART 数据 wire uart_tx; // DUT 回发数据 wire [31:0] o_wrdata; // DUT -> SRAM 写数据 wire [24:0] o_addr; // DUT -> SRAM 地址 wire o_wren; // 写使能 wire o_rden; // 读使能 reg [31:0] i_rddata; // SRAM -> DUT 读数据 // 例化待测模块 (DUT) uart_ctrl_sysreg #( .BAUD (BAUD), .CLOCK_FREQ (50_000_000) ) u_dut ( .clk (clk), .rst_n (rst_n), .uart_rx (uart_rx), .uart_tx (uart_tx), .o_wrdata (o_wrdata), .o_addr (o_addr), .o_wren (o_wren), .o_rden (o_rden), .i_rddata (i_rddata) ); // --- 时钟产生 --- initial clk = 0; always #(CLK_PERIOD/2) clk = ~clk; // ============================================================ // 模拟上位机:字节发送任务 (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 // ============================================================ // 监听回传:捕捉 FPGA 返回的读数据 // ============================================================ // 简单起见,这里直接观察波形,或者你可以写一个串口接收任务 initial begin $display("[%t] 监听器已启动...", $time); end endmodule