`timescale 1ns / 1ps module tb_lvds_1to3_copy_reg; // 输入信号 reg clk_in_p, clk_in_n; reg [2:0] data_in_p, data_in_n; // 输出信号 wire clk_out0_p, clk_out0_n; wire clk_out1_p, clk_out1_n; wire clk_out2_p, clk_out2_n; wire [2:0] data_out0_p, data_out0_n; wire [2:0] data_out1_p, data_out1_n; wire [2:0] data_out2_p, data_out2_n; // 时钟参数 parameter CLK_PERIOD = 10.0; // 100MHz时钟 parameter HALF_PERIOD = CLK_PERIOD / 2; // 实例化被测试模块 lvds_1to3_copy_reg dut ( .clk_in_p(clk_in_p), .clk_in_n(clk_in_n), .data_in_p(data_in_p), .data_in_n(data_in_n), .clk_out0_p(clk_out0_p), .clk_out0_n(clk_out0_n), .clk_out1_p(clk_out1_p), .clk_out1_n(clk_out1_n), .clk_out2_p(clk_out2_p), .clk_out2_n(clk_out2_n), .data_out0_p(data_out0_p), .data_out0_n(data_out0_n), .data_out1_p(data_out1_p), .data_out1_n(data_out1_n), .data_out2_p(data_out2_p), .data_out2_n(data_out2_n) ); // 生成差分时钟信号 always #HALF_PERIOD begin clk_in_p = ~clk_in_p; clk_in_n = ~clk_in_p; // 差分信号相位相反 end // 生成差分数据信号 task generate_diff_data; input [2:0] data_value; begin data_in_p = data_value; data_in_n = ~data_value; // 差分信号取反 end endtask // 检查输出同步性 task check_output_sync; input integer test_case; begin #1; // 等待稳定 // 检查三组输出是否相同 if ((data_out0_p === data_out1_p) && (data_out1_p === data_out2_p) && (data_out0_n === data_out1_n) && (data_out1_n === data_out2_n)) begin $display("[PASS] Test Case %0d: 三组输出完全同步", test_case); end else begin $display("[FAIL] Test Case %0d: 三组输出不同步", test_case); $display(" Data0_p: %b, Data1_p: %b, Data2_p: %b", data_out0_p, data_out1_p, data_out2_p); $display(" Data0_n: %b, Data1_n: %b, Data2_n: %b", data_out0_n, data_out1_n, data_out2_n); end // 检查差分对一致性 if ((data_out0_p === ~data_out0_n) && (data_out1_p === ~data_out1_n) && (data_out2_p === ~data_out2_n)) begin $display("[PASS] Test Case %0d: 差分对极性正确", test_case); end else begin $display("[FAIL] Test Case %0d: 差分对极性错误", test_case); end end endtask // 主要测试向量 initial begin // 初始化信号 clk_in_p = 1'b1; clk_in_n = 1'b0; data_in_p = 3'b000; data_in_n = 3'b111; $display("=== LVDS信号复制模块仿真开始 ==="); $display("时钟周期: %0t ns", CLK_PERIOD); $timeformat(-9, 0, " ns", 10); // 等待复位完成 #(CLK_PERIOD * 2); // 测试用例1: 全0数据 $display("\n--- 测试用例1: 输入全0 ---"); generate_diff_data(3'b000); #(CLK_PERIOD * 3); // 等待多个周期稳定 check_output_sync(1); // 测试用例2: 全1数据 $display("\n--- 测试用例2: 输入全1 ---"); generate_diff_data(3'b111); #(CLK_PERIOD * 3); check_output_sync(2); // 测试用例3: 递增模式 $display("\n--- 测试用例3: 数据递增模式 ---"); for (integer i = 0; i < 8; i = i + 1) begin generate_diff_data(i); #(CLK_PERIOD); $display("时间 %t: 输入数据 %b -> 输出0_p %b", $time, i, data_out0_p); if (i > 0) check_output_sync(3); end // 测试用例4: 随机数据 $display("\n--- 测试用例4: 随机数据测试 ---"); for (integer j = 0; j < 10; j = j + 1) begin generate_diff_data($random % 8); #(CLK_PERIOD); check_output_sync(4); end // 测试用例5: 快速数据变化 $display("\n--- 测试用例5: 快速数据变化测试 ---"); repeat(5) begin generate_diff_data(3'b010); #(CLK_PERIOD/4); generate_diff_data(3'b101); #(CLK_PERIOD/4); generate_diff_data(3'b110); #(CLK_PERIOD/4); generate_diff_data(3'b001); #(CLK_PERIOD/4); check_output_sync(5); end // 测试用例6: 验证寄存器延迟 $display("\n--- 测试用例6: 寄存器延迟验证 ---"); generate_diff_data(3'b010); #(CLK_PERIOD/2); // 半周期后检查 if ((data_out0_p !== 3'b010) && (data_out0_p === data_out1_p) && (data_out1_p === data_out2_p)) begin $display("[PASS] 寄存器延迟正确:输出尚未更新"); end #(CLK_PERIOD/2); // 完整周期后检查 if ((data_out0_p === 3'b010) && (data_out0_p === data_out1_p) && (data_out1_p === data_out2_p)) begin $display("[PASS] 寄存器延迟正确:输出已更新"); end $display("\n=== 仿真完成 ==="); #100 $finish; end // 监控关键信号 initial begin $monitor("时间 %t: 输入=%b, 输出0_p=%b, 输出1_p=%b, 输出2_p=%b", $time, data_in_p, data_out0_p, data_out1_p, data_out2_p); end // 波形文件生成(用于Vivado仿真) initial begin $dumpfile("lvds_1to3_copy_reg.vcd"); $dumpvars(0, tb_lvds_1to3_copy_reg); end endmodule