Revert to default
This commit is contained in:
@@ -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
|
||||
Reference in New Issue
Block a user