Revert to default

This commit is contained in:
Jeremy Shen
2026-05-18 13:54:11 +08:00
parent 44b40ab9e1
commit c5df01f33d
50 changed files with 4436 additions and 89 deletions
+310
View File
@@ -0,0 +1,310 @@
`timescale 1ns/1ps
module tb_RelayConTop;
// 时钟和复位
reg i_sys_clk;
reg i_rst_n;
// SPI接口
reg i_sclk;
reg i_mosi;
reg i_cs;
// wire o_miso;
// 流控制接口
// wire o_rvaild;
// reg i_rready;
// reg i_wvaild;
// wire o_wready;
wire o_err;
// 继电器控制输出
wire [7:0] o_RC_F;
wire [15:0] o_RC_S;
wire [31:0] o_RC_T;
// 测试变量
reg [31:0] spi_data;
integer test_pass;
integer test_fail;
// 实例化被测模块
RelayConTop DUT (
.i_sys_clk(i_sys_clk),
.i_rst_n(i_rst_n),
.i_sclk(i_sclk),
.i_mosi(i_mosi),
.i_cs(i_cs),
// .o_miso(o_miso),
// .o_rvaild(o_rvaild),
// .i_rready(i_rready),
// .i_wvaild(i_wvaild),
// .o_wready(o_wready),
.o_err(o_err),
.o_RC_F(o_RC_F),
.o_RC_S(o_RC_S),
.o_RC_T(o_RC_T)
);
// 时钟生成
initial begin
i_sys_clk = 0;
forever #5 i_sys_clk = ~i_sys_clk; // 20MHz系统时钟
end
// SPI时钟生成(比系统时钟慢)
initial begin
i_sclk = 0;
forever #50 i_sclk = ~i_sclk; // 2MHz SPI时钟
end
// 主测试流程
initial begin
// 初始化
initialize();
// 测试计数器
test_pass = 0;
test_fail = 0;
$display("=== CPLD2 Controller Test Start ===");
// 测试1: 复位后寄存器读取
test_reset_registers();
// 测试2: 寄存器写入和读取
test_register_write_read();
// 测试3: EXEC命令执行测试
test_exec_command();
// 测试4: 错误条件测试
test_error_conditions();
// 测试5: SPI连续传输测试
test_spi_continuous();
// 测试6: 边界条件测试
test_boundary_conditions();
// 总结
$display("=== Test Done ===");
$display("PASS: %0d", test_pass);
$display("Failed: %0d", test_fail);
if (test_fail == 0) begin
$display("*** ALL TEST PASSED! ***");
end else begin
$display("*** TEST FAILED FOUND!! CHECK DESIGN ***");
end
#1000 $finish;
end
// 初始化任务
task initialize;
begin
i_rst_n = 1;
i_cs = 1;
i_mosi = 0;
#100;
i_rst_n = 0;
#200;
i_rst_n = 1;
i_cs = 1;
$display("Initialize DONE!");
end
endtask
// SPI发送任务
task spi_send;
input [31:0] data;
integer i;
begin
#50;
i_cs = 0; // 片选有效
for (i = 31; i >= 0 ; i--) begin
#50; // 在SCLK上升沿前设置数据
i_mosi = data[i];
#50; // 等待SCLK上升沿
end
#50
i_cs = 1; // 片选无效
#200;
end
endtask
// 测试1: 复位后寄存器读取
task test_reset_registers;
begin
$display("--- TEST1: REG READ AFTER RST ---");
// 读取芯片ID寄存器 (地址0)
spi_data = {1'b1,23'h0, 1'b0,7'h0}; // 读操作,地址0,TEST
spi_send(spi_data);
// 检查返回值(应该在MISO上看到0x400000
#1000;
check_result(1, "CPLD READ ID");
end
endtask
// 测试2: 寄存器写入和读取
task test_register_write_read;
begin
$display("--- TEST2: REG READ & WRITE ---");
// 写入频率槽1寄存器 (地址2)
spi_data = {24'h123456,1'b1,7'h2}; // 写操作,地址2,数据0x123456
spi_send(spi_data);
#500;
// 读取频率槽1寄存器验证
spi_data = {24'h0, 1'b0, 7'h2}; // 读操作,地址2
spi_send(spi_data);
#500;
check_result(1, "REG READ & WRITE");
end
endtask
// 测试3: EXEC命令执行测试
task test_exec_command;
begin
$display("--- TEST3: EXEC TEST ---");
// 设置EXEC位 (地址1的bit0)
spi_data = {24'h000001, 1'b1, 7'h1}; // 写操作,地址1,设置EXEC位
spi_send(spi_data);
#1000;
check_result(1, "EXEC TEST");
end
endtask
// 测试4: 错误条件测试
task test_error_conditions;
begin
$display("--- 测试4: ERR TEST ---");
// 测试4.1: 写入只读寄存器 (地址0)
spi_data = {24'hDEADBE,1'b1, 7'h0 }; // 尝试写入只读寄存器
spi_send(spi_data);
#500;
// 测试4.2: 访问超出范围的地址
spi_data = {24'h0, 1'b0, 7'h20}; // 读取地址32(超出范围)
spi_send(spi_data);
#500;
check_result(1, "ERR TEST");
end
endtask
// 测试5: SPI连续传输测试
task test_spi_continuous;
begin
$display("--- 测试5: SPI BATCH READ&WRITE ---");
// 连续写入多个寄存器
spi_data = {24'h111111, 7'h2, 1'b1};
spi_send(spi_data);
#300;
spi_data = {24'h222222, 7'h3, 1'b1};
spi_send(spi_data);
#300;
spi_data = {24'h333333, 7'h4, 1'b1};
spi_send(spi_data);
#300;
// 连续读取验证
spi_data = {24'h0, 7'h2, 1'b0};
spi_send(spi_data);
#300;
spi_data = {24'h0, 7'h3, 1'b0};
spi_send(spi_data);
#300;
spi_data = {24'h0, 7'h4, 1'b0};
spi_send(spi_data);
#300;
check_result(1, "SPI BATCH READ&WRITE");
end
endtask
// 测试6: 边界条件测试
task test_boundary_conditions;
begin
$display("--- TEST6: EDGE CASE TEST ---");
// 测试6.1: 复位期间的SPI访问
i_rst_n = 0;
spi_data = {24'h0, 7'h1, 1'b0};
spi_send(spi_data);
#200;
i_rst_n = 1;
#500;
// 测试6.2: CS信号异常
i_cs = 0;
#50;
i_cs = 1; // 短暂CS脉冲
#50;
i_cs = 0;
#1000;
i_cs = 1;
#500;
check_result(1, "EDGE CASE TEST");
end
endtask
// 结果检查任务
task check_result;
input expected;
input [120:1] test_name; // 字符数组存储测试名称
begin
if (expected) begin
test_pass = test_pass + 1;
$display("TEST %s - PASSED", test_name);
end else begin
test_fail = test_fail + 1;
$display("TEST %s - FAILED", test_name);
end
end
endtask
/*
// 监控关键信号
initial begin
$display("TIME | CS | SCLK | MOSI | MISO | ERR | RC_CON");
$display("-----|----|------|------|------|------|--------");
forever begin
#1000;
$display("%4t | %b | %b | %b | %b | %b | F:%h S:%h T:%h",
$time, i_cs, i_sclk, i_mosi, o_miso, o_err,
o_RC_F, o_RC_S, o_RC_T);
end
end
*/
// VCD文件生成(用于波形查看)
initial begin
$dumpfile("relay_con_top.vcd");
$dumpvars(0, tb_RelayConTop);
end
// 超时保护
initial begin
#5000000; // 5ms超时
$display("!!! TEST TIMEOUT !!!");
$finish;
end
endmodule