Files
LVDS1M/modules/LVDS/sim/testbench/tb_lvds_1to3_copy_reg.v

179 lines
5.9 KiB
Coq
Raw Normal View History

2026-02-02 17:58:25 +08:00
`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