Files
eb001/tb/shinTest/ShinTopSpiTb.v
2025-05-28 10:34:26 +08:00

1069 lines
31 KiB
Verilog
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
`timescale 1 ns / 1 ps
`define ENABLE_REG_RW_TEST
`define ENABLE_DET_TEST
`define ENABLE_SET_ADDR_TEST
//`define ENABLE_SM1_SEND_TEST
//`define ENABLE_SMx_SEND_TEST
`define ENABLE_EXCHG_DATA_SEQ_TEST
//`define ENABLE_EXCHG_DATA_SEQ0_TEST
//`define ENABLE_EXCHG_DATA_SEQ1_TEST
//`define ENABLE_EXCHG_DATA_SEQ2_TEST
//`define ENABLE_EXCHG_DATA_BC_TEST
`define ENABLE_SYNC_TEST
`define ENABLE_SYNC_SIG0_TEST
`define ENABLE_SYNC_SIG1_TEST
module ShinTopSpiTb(
);
reg clock;
reg reset;
reg clk8x;
wire [3:0] dDat_w;
wire [3:0] uDat_w;
wire spi_sck;
wire spi_mosi;
wire [4:0] spi_miso;
reg [14:0] spi_csn;
wire qspi_sck;
wire [3:0] qspi_mosi;
wire [40-1:0] qspi_miso;
wire isResp;
integer spidata_file;
integer c_line;
integer _pos;
integer _len;
integer _t_start;
integer _t_end;
reg [63:0] _temp_time;
wire [4:0] isSoftReset;
ShinTop s_ShinTop_Mst(
.clock(clock),
.reset(reset | isSoftReset[0]),
.io_clk8x(clk8x),
.io_dDatIn(1'b0),
.io_dDatOut(dDat_w[0]),
.io_uDatIn(uDat_w[0]),
.io_uDatOut(),
.io_iqspi_sck(qspi_sck),
.io_iqspi_mosi(qspi_mosi),
.io_iqspi_miso(qspi_miso[3:0]),
.io_iqspi_isDirIn(),
.io_iqspi_csn(spi_csn[0]),
.io_ospi_sck (spi_sck),
.io_ospi_mosi(spi_mosi),
.io_ospi_miso(spi_miso[0]),
.io_ospi_csn (spi_csn[5]),
.io_oqspi_sck(qspi_sck),
.io_oqspi_mosi(qspi_mosi),
.io_oqspi_miso(qspi_miso[4*5+3:4*5]),
.io_oqspi_isDirIn(),
.io_oqspi_csn(spi_csn[10]),
.io_rsp_valid(isResp),
.io_rsp_bits_isError(),
.io_isSoftReset(isSoftReset[0]),
.io_interrupt()
);
ShinTop s_ShinTop_slv0(
.clock(clock),
.reset(reset | isSoftReset[1]),
.io_clk8x(clk8x),
.io_dDatIn(dDat_w[0]),
.io_dDatOut(dDat_w[1]),
.io_uDatIn(uDat_w[1]),
.io_uDatOut(uDat_w[0]),
.io_iqspi_sck(qspi_sck),
.io_iqspi_mosi(qspi_mosi),
.io_iqspi_miso(qspi_miso[4*1+3:4*1]),
.io_iqspi_isDirIn(),
.io_iqspi_csn(spi_csn[1]),
.io_ospi_sck (spi_sck),
.io_ospi_mosi(spi_mosi),
.io_ospi_miso(spi_miso[1]),
.io_ospi_csn (spi_csn[6]),
.io_oqspi_sck(qspi_sck),
.io_oqspi_mosi(qspi_mosi),
.io_oqspi_miso(qspi_miso[4*6+3:4*6]),
.io_oqspi_isDirIn(),
.io_oqspi_csn(spi_csn[11]),
.io_rsp_valid(),
.io_rsp_bits_isError(),
.io_isSoftReset(isSoftReset[1]),
.io_interrupt()
);
ShinTop s_ShinTop_slv1(
.clock(clock),
.reset(reset | isSoftReset[2]),
.io_clk8x(clk8x),
.io_dDatIn(dDat_w[1]),
.io_dDatOut(dDat_w[2]),
.io_uDatIn(uDat_w[2]),
.io_uDatOut(uDat_w[1]),
.io_iqspi_sck(qspi_sck),
.io_iqspi_mosi(qspi_mosi),
.io_iqspi_miso(qspi_miso[4*2+3:4*2]),
.io_iqspi_isDirIn(),
.io_iqspi_csn(spi_csn[2]),
.io_ospi_sck (spi_sck),
.io_ospi_mosi(spi_mosi),
.io_ospi_miso(spi_miso[2]),
.io_ospi_csn (spi_csn[7]),
.io_oqspi_sck(qspi_sck),
.io_oqspi_mosi(qspi_mosi),
.io_oqspi_miso(qspi_miso[4*7+3:4*7]),
.io_oqspi_isDirIn(),
.io_oqspi_csn(spi_csn[12]),
.io_rsp_valid(),
.io_rsp_bits_isError(),
.io_isSoftReset(isSoftReset[2]),
.io_interrupt()
);
ShinTop s_ShinTop_slv2(
.clock(clock),
.reset(reset | isSoftReset[3]),
.io_clk8x(clk8x),
.io_dDatIn(dDat_w[2]),
.io_dDatOut(dDat_w[3]),
.io_uDatIn(uDat_w[3]),
.io_uDatOut(uDat_w[2]),
.io_iqspi_sck(qspi_sck),
.io_iqspi_mosi(qspi_mosi),
.io_iqspi_miso(qspi_miso[4*3+3:4*3]),
.io_iqspi_isDirIn(),
.io_iqspi_csn(spi_csn[3]),
.io_ospi_sck (spi_sck),
.io_ospi_mosi(spi_mosi),
.io_ospi_miso(spi_miso[3]),
.io_ospi_csn (spi_csn[8]),
.io_oqspi_sck(qspi_sck),
.io_oqspi_mosi(qspi_mosi),
.io_oqspi_miso(qspi_miso[4*8+3:4*8]),
.io_oqspi_isDirIn(),
.io_oqspi_csn(spi_csn[13]),
.io_rsp_valid(),
.io_rsp_bits_isError(),
.io_isSoftReset(isSoftReset[3]),
.io_interrupt()
);
ShinTop s_ShinTop_slv3(
.clock(clock),
.reset(reset | isSoftReset[4]),
.io_clk8x(clk8x),
.io_dDatIn(dDat_w[3]),
.io_dDatOut(),
.io_uDatIn(1'b0),
.io_uDatOut(uDat_w[3]),
.io_iqspi_sck(qspi_sck),
.io_iqspi_mosi(qspi_mosi),
.io_iqspi_miso(qspi_miso[4*4+3:4*4]),
.io_iqspi_isDirIn(),
.io_iqspi_csn(spi_csn[4]),
.io_ospi_sck (spi_sck),
.io_ospi_mosi(spi_mosi),
.io_ospi_miso(spi_miso[4]),
.io_ospi_csn (spi_csn[9]),
.io_oqspi_sck(qspi_sck),
.io_oqspi_mosi(qspi_mosi),
.io_oqspi_miso(qspi_miso[4*9+3:4*9]),
.io_oqspi_isDirIn(),
.io_oqspi_csn(spi_csn[14]),
.io_rsp_valid(),
.io_rsp_bits_isError(),
.io_isSoftReset(isSoftReset[4]),
.io_interrupt()
);
initial begin
clock = 0;
clk8x = 0;
reset = 0;
spi_csn = ~15'b0;
#100
reset <= 1;
#240
reset <= 0;
//#20000000
#1000000000
$display("Time Out !!!");
$fclose(spidata_file);
$stop;
end
initial begin
forever begin #20 clk8x <= ~clk8x; end
end
initial begin
forever begin #80 clock <= ~clock; end
end
initial
begin
spidata_file = $fopen("spi_trans_data.txt", "w");
if (!spidata_file) $display("文件打开失败");
$dumpfile("./tb/build/wave.vcd"); //生成的vcd文件名称
$dumpvars(0, ShinTopSpiTb);//tb模块名称
end
`define SCKFRE #640
reg sck = 0;
initial begin
forever begin
`SCKFRE sck <= ~sck;
end
end
assign spi_sck = sck;
assign qspi_sck = sck;
reg [7:0] txBuf[0:2047];
reg [7:0] rxBuf[0:2047];
reg [7:0] exChangeRego;
reg [7:0] exChangeRegi;
assign spi_mosi = exChangeRego[7];
assign qspi_mosi = exChangeRego[7:4];
wire [3:0] qspi_mux_miso =
( qspi_miso[4*0+3:4*0] & ~{4{spi_csn[ 0]}}) |
( qspi_miso[4*1+3:4*1] & ~{4{spi_csn[ 1]}}) |
( qspi_miso[4*2+3:4*2] & ~{4{spi_csn[ 2]}}) |
( qspi_miso[4*3+3:4*3] & ~{4{spi_csn[ 3]}}) |
( qspi_miso[4*4+3:4*4] & ~{4{spi_csn[ 4]}}) |
( qspi_miso[4*5+3:4*5] & ~{4{spi_csn[10]}}) |
( qspi_miso[4*6+3:4*6] & ~{4{spi_csn[11]}}) |
( qspi_miso[4*7+3:4*7] & ~{4{spi_csn[12]}}) |
( qspi_miso[4*8+3:4*8] & ~{4{spi_csn[13]}}) |
( qspi_miso[4*9+3:4*9] & ~{4{spi_csn[14]}});
wire spi_mux_miso =
( spi_miso[0] & ~spi_csn[5] ) |
( spi_miso[1] & ~spi_csn[6] ) |
( spi_miso[2] & ~spi_csn[7] ) |
( spi_miso[3] & ~spi_csn[8] ) |
( spi_miso[4] & ~spi_csn[9] );
reg isReq = 0;
reg isBusy = 0;
reg [11:0] length;
reg [7:0] idx;
reg [11:0] transCnt;
reg [11:0] byteCnt;
reg [2:0] bitCnt;
always @(posedge clock) begin
if( isReq & sck == 0 ) begin
isBusy <= #5 1'b1;
transCnt <= #5 0;
byteCnt <= #5 ~12'b0;
bitCnt <= #5 ~3'b0;
spi_csn[idx] <= #5 1'b0;
exChangeRego <= txBuf[0];
end
end
wire isQspi = (idx >= 0 && idx <= 4) || idx >= 10;
wire [11:0] nextByteCnt = byteCnt + 1;
//输出
always @(negedge sck) begin
if( isBusy ) begin
if( &bitCnt ) begin
exChangeRego <= txBuf[nextByteCnt];
end else begin
exChangeRego <= isQspi ? exChangeRego << 4 : exChangeRego << 1;
end
end
end
//输入
always @(posedge sck) begin
if( isBusy ) begin
if( transCnt <= length ) begin
if( isQspi ) begin
bitCnt <= ~bitCnt;
end else begin
bitCnt <= bitCnt + 1;
end
if( &bitCnt ) begin
byteCnt <= byteCnt +1;
transCnt <= transCnt + 1;
if( txBuf[2] === 1 & nextByteCnt >= 4) begin
rxBuf[byteCnt] <= exChangeRegi;
//$display("spi read out %x", exChangeRegi);
end
if( txBuf[2] === 1 & nextByteCnt >= 3) begin
exChangeRegi <= isQspi ? {exChangeRegi[3:0], qspi_mux_miso} : {exChangeRegi[6:0], spi_mux_miso};
end else begin
exChangeRegi <= 0;
end
end else begin
exChangeRegi <= isQspi ? {exChangeRegi[3:0], qspi_mux_miso} : {exChangeRegi[6:0], spi_mux_miso};
end
end else begin
isBusy <= #5 1'b0;
spi_csn[idx] <= #5 1'b1;
end
end
end
//mst slv0~slv3的 内部qspi调用即设置
//sidx为0~4外部spi为5~9外部qspi为10~15
task spi_trans( input [15:0] saddress, input [7:0] scmd, input [12:0] slength,input [7:0] sidx );
begin
txBuf[0] <= saddress[7:0];
txBuf[1] <= saddress[15:8];
txBuf[2] <= scmd;
length <= slength + 3;
idx <= sidx;
#5
@(negedge sck)
isReq <= 1;
@(posedge sck) #5
isReq <= 0;
@( negedge isBusy) #1000
begin
//$fwrite(spidata_file, "------------%5t------------\n", $time);
$fwrite(spidata_file, "T:%2tns \tdev:%4d, addr:0x%02h%02h, %s, len:%4d\n",
$time/1000, ((sidx >= 5)? ((sidx >= 10)? (sidx - 10):(sidx - 5)):sidx), txBuf[1], txBuf[0],
((txBuf[2] == 0)? "Write":" Read"), slength);
if ( ((saddress == 16'h0800)
|| (saddress == 16'h1000)
|| (saddress == 16'h1800)
|| (saddress == 16'h2000)
|| (saddress == 16'h2800)
|| (saddress == 16'h3000)
|| (saddress == 16'h3800)
|| (saddress == 16'h4000))
&& ((sidx == 0) || (sidx == 5) || (sidx == 10))) begin
_pos = 3;
for (integer _k = 0; _k < 4; _k++) begin
if (scmd == 0) begin
$fwrite(spidata_file, "%02h ", txBuf[_k + _pos]);
end else begin
$fwrite(spidata_file, "%02h ", rxBuf[_k + _pos]);
end
end
$fwrite(spidata_file, "\n");
_pos = 4 + _pos;
for (; _pos < slength; ) begin
for (integer _k = 0; _k < 8; _k++) begin
if (scmd == 0) begin
$fwrite(spidata_file, "%02h ", txBuf[_k + _pos]);
_len = txBuf[_pos + 5] + (txBuf[_pos + 4] & 8'h0f) * 256;
end else begin
$fwrite(spidata_file, "%02h ", rxBuf[_k + _pos]);
_len = rxBuf[_pos + 5] + (rxBuf[_pos + 4] & 8'h0f) * 256;
end
end
$fwrite(spidata_file, "\n{{ ");
_pos = _pos + 8;
for (integer _k = 0; _k < _len; _k++) begin
if (scmd == 0) begin
$fwrite(spidata_file, "%02h ", txBuf[_k + _pos]);
end else begin
$fwrite(spidata_file, "%02h ", rxBuf[_k + _pos]);
end
c_line = 0;
if ((_k + 2)%16 == 0) begin
$fwrite(spidata_file, "\n");
c_line = 1;
end
end
$fwrite(spidata_file, "}}\n");
_pos = _pos + _len;
end
end else begin
for (integer i=0; i<slength; i++) begin
if (scmd == 0) begin
$fwrite(spidata_file, "%02h ", txBuf[i + 3]);
end else begin
$fwrite(spidata_file, "%02h ", rxBuf[i + 3]);
end
c_line = 0;
if ((i+1)%16 == 0) begin
$fwrite(spidata_file, "\n");
c_line = 1;
end
end
if (c_line == 0) begin
$fwrite(spidata_file, "\n");
end
c_line = 0;
end
end
end
endtask
`define INTERFACE_IDX 0 //internal spi
`define IF_IDX(idx) ((`INTERFACE_IDX)+(idx))
`define IF_IQSPI(idx) ((idx))
`define IF_OQSPI(idx) ((10) + (idx))
`define IF_OSPI(idx) ((5) + (idx))
`define SPI_WRITE 8'h0
`define SPI_READ 8'h1
`define MST_TX_TRIGGER(idx) (8'h1 + ((idx & 8'h3) * 8'h2) + ((idx & 8'h3) * 8'h8))
`define MST_RX0_ADDR 16'h0800
`define MST_TX0_ADDR 16'h1000
`define MST_RX1_ADDR 16'h1800
`define MST_TX1_ADDR 16'h2000
`define MST_RX2_ADDR 16'h2800
`define MST_TX2_ADDR 16'h3000
`define MST_RX3_ADDR 16'h3800
`define MST_TX3_ADDR 16'h4000
`define MST_RX0_LEN_ADDR 16'h0306
`define MST_TX0_LEN_ADDR 16'h0302
`define MST_RX1_LEN_ADDR 16'h030e
`define MST_TX1_LEN_ADDR 16'h030a
`define MST_RX2_LEN_ADDR 16'h0316
`define MST_TX2_LEN_ADDR 16'h0312
`define MST_RX3_LEN_ADDR 16'h031e
`define MST_TX3_LEN_ADDR 16'h031a
`define MST_TX_TRG (`MST_TX_TRIGGER(0))
`define MST_RX_ADDR (`MST_RX0_ADDR)
`define MST_TX_ADDR (`MST_TX0_ADDR)
`define MST_RX_LEN_ADDR (`MST_RX0_LEN_ADDR)
`define MST_TX_LEN_ADDR (`MST_TX0_LEN_ADDR)
/*---------------------------------------------------------------------------------------------------------
测试用例1
---------------------------------------------------------------------------------------------------------*/
initial begin
#1000
`ifdef ENABLE_REG_RW_TEST
/*---------------------------------------------------------------------------------------------------------
测试用例
1. 从IP中读取寄存器上电后的寄存器期望值为0
---------------------------------------------------------------------------------------------------------*/
begin:READ_REG_TESTCASE
_t_start = $time;
$fdisplay(spidata_file, "测试用例从IP中读取寄存器上电后的寄存器期望值为0");
spi_trans( (16'h00), (`SPI_READ), (64), (`IF_IQSPI(0)) );
spi_trans( (16'h00), (`SPI_READ), (64), (`IF_IQSPI(1)) );
spi_trans( (16'h00), (`SPI_READ), (64), (`IF_IQSPI(2)) );
spi_trans( (16'h00), (`SPI_READ), (64), (`IF_IQSPI(3)) );
spi_trans( (16'h00), (`SPI_READ), (64), (`IF_IQSPI(4)) );
_t_end = $time;
$fdisplay(spidata_file, "该测试用例运行时间:%2tns", (_t_end - _t_start) / 1000);
end
`endif
begin:SETTING_INTERFACE
if ((`INTERFACE_IDX) == 5) begin
$fdisplay(spidata_file, "\n\n从内部QSPI配置使用外部的SPI接口访问EasyBus");
txBuf[0+3] = 8'h01;
spi_trans( (16'h09), (`SPI_WRITE), (1), (`IF_IQSPI(0)) );
spi_trans( (16'h09), (`SPI_WRITE), (1), (`IF_IQSPI(1)) );
spi_trans( (16'h09), (`SPI_WRITE), (1), (`IF_IQSPI(2)) );
spi_trans( (16'h09), (`SPI_WRITE), (1), (`IF_IQSPI(3)) );
spi_trans( (16'h09), (`SPI_WRITE), (1), (`IF_IQSPI(4)) );
end else if ((`INTERFACE_IDX) == 10) begin
$fdisplay(spidata_file, "\n\n从内部QSPI配置使用外部的QSPI接口访问EasyBus");
txBuf[0+3] = 8'h02;
spi_trans( (16'h09), (`SPI_WRITE), (1), (`IF_IQSPI(0)) );
spi_trans( (16'h09), (`SPI_WRITE), (1), (`IF_IQSPI(1)) );
spi_trans( (16'h09), (`SPI_WRITE), (1), (`IF_IQSPI(2)) );
spi_trans( (16'h09), (`SPI_WRITE), (1), (`IF_IQSPI(3)) );
spi_trans( (16'h09), (`SPI_WRITE), (1), (`IF_IQSPI(4)) );
end else begin
$fdisplay(spidata_file, "\n\n从内部QSPI接口访问EasyBus");
end
end
/*---------------------------------------------------------------------------------------------------------
测试用例
1. 设置IP为主站或从站并读取设置结果期望0主1~4从
---------------------------------------------------------------------------------------------------------*/
begin:SETTING_DEV_ROLE
//设置主站从站
$fdisplay(spidata_file, "\n\n测试用例设置IP为主站或从站并读取设置结果期望0主1~4从");
txBuf[0+3] = 8'h01;
spi_trans( (16'h00), (`SPI_WRITE), (1), (`IF_IDX(0)) );
#1000
txBuf[0+3] = 8'h02;
spi_trans( (16'h0), (`SPI_WRITE), (1), (`IF_IDX(1)) );
#1000
spi_trans( (16'h0), (`SPI_WRITE), (1), (`IF_IDX(2)) );
#1000
spi_trans( (16'h0), (`SPI_WRITE), (1), (`IF_IDX(3)) );
#1000
spi_trans( (16'h0), (`SPI_WRITE), (1), (`IF_IDX(4)) );
$fdisplay(spidata_file, "--->>>设置完毕,检查接口寄存器");
spi_trans( (16'h00), (`SPI_READ), (1), (`IF_IDX(0)) );
spi_trans( (16'h00), (`SPI_READ), (1), (`IF_IDX(1)) );
spi_trans( (16'h00), (`SPI_READ), (1), (`IF_IDX(2)) );
spi_trans( (16'h00), (`SPI_READ), (1), (`IF_IDX(3)) );
spi_trans( (16'h00), (`SPI_READ), (1), (`IF_IDX(4)) );
end
`ifdef ENABLE_DET_TEST
/*---------------------------------------------------------------------------------------------------------
测试用例3
---------------------------------------------------------------------------------------------------------*/
//嗅探
begin:DETECT_DEV_TESTCASE
_t_start = $time;
#1000
$fdisplay(spidata_file, "\n\n测试用例:发送嗅探包,需要在波形文件里检查");
$fdisplay(spidata_file, "--->>>嗅探前,检查链路状态寄存器");
//spi_trans( (16'h00c0), (`SPI_READ), (6), (`IF_IDX(0)) );
spi_trans( (16'h00c0), (`SPI_READ), (6), (`IF_IDX(1)) );
spi_trans( (16'h00c0), (`SPI_READ), (6), (`IF_IDX(2)) );
spi_trans( (16'h00c0), (`SPI_READ), (6), (`IF_IDX(3)) );
spi_trans( (16'h00c0), (`SPI_READ), (6), (`IF_IDX(4)) );
$fdisplay(spidata_file, "--->>>嗅探");
`include "detect_pkt.vh"
// 顺序索引
//#50000
#1000
$fdisplay(spidata_file, "--->>>嗅探后,检查链路状态寄存器");
//spi_trans( (16'h00c0), (`SPI_READ), (6), (`IF_IDX(0)) );
spi_trans( (16'h00c0), (`SPI_READ), (6), (`IF_IDX(1)) );
spi_trans( (16'h00c0), (`SPI_READ), (6), (`IF_IDX(2)) );
spi_trans( (16'h00c0), (`SPI_READ), (6), (`IF_IDX(3)) );
spi_trans( (16'h00c0), (`SPI_READ), (6), (`IF_IDX(4)) );
_t_end = $time;
$fdisplay(spidata_file, "该测试用例运行时间:%2tns", (_t_end - _t_start) / 1000);
end
`endif
`ifdef ENABLE_SET_ADDR_TEST
/*---------------------------------------------------------------------------------------------------------
测试用例
---------------------------------------------------------------------------------------------------------*/
begin:SET_ADDR_TESTCASE
_t_start = $time;
$fdisplay(spidata_file, "\n\n测试用例:设置顺序索引");
$display("index @ %d", s_ShinTop_Mst.interface__io_cReg_timeStamp);
$fdisplay(spidata_file, "--->>>设置顺序地址前,检查顺序地址");
//spi_trans( (16'h0010), (`SPI_READ), (5), (`IF_IDX(0)) );
spi_trans( (16'h0000), (`SPI_READ), (16), (`IF_IDX(1)) );
spi_trans( (16'h0000), (`SPI_READ), (16), (`IF_IDX(2)) );
spi_trans( (16'h0000), (`SPI_READ), (16), (`IF_IDX(3)) );
spi_trans( (16'h0000), (`SPI_READ), (16), (`IF_IDX(4)) );
$fdisplay(spidata_file, "--->>>设置顺序地址");
`include "set_addr_pkt.vh"
//长度
`DEF_set_addr_pkt_sm(txBuf);
spi_trans( (`MST_TX_LEN_ADDR), (`SPI_WRITE), (2), (`IF_IDX(0)) );
spi_trans( (`MST_RX_LEN_ADDR), (`SPI_WRITE), (2), (`IF_IDX(0)) );
//子报文
$fdisplay(spidata_file, "<<发包:");
`DEF_set_addr_pkt(txBuf);
spi_trans( (`MST_TX_ADDR), (`SPI_WRITE), (`DEF_set_addr_pkt_len), (`IF_IDX(0)) ); //写入SM1
//发布请求
txBuf[0+3] = `MST_TX_TRG;
spi_trans( (16'h20), (`SPI_WRITE), (1), (`IF_IDX(0)) );//发送SM0 接收SM0, 请求发送
@(posedge isResp) #5 begin end
$fdisplay(spidata_file, ">>回包:");
spi_trans( (`MST_RX_ADDR), (`SPI_READ), (`DEF_set_addr_pkt_len), (`IF_IDX(0)) );//读一下SM0的切换地址将fifo弹出
//测试
spi_trans( (16'hc0), (`SPI_READ), (6), (`IF_IDX(3)) );
spi_trans( (16'h0a), (`SPI_READ), (2), (`IF_IDX(1)) );
spi_trans( (16'h0a), (`SPI_READ), (2), (`IF_IDX(2)) );
spi_trans( (16'h0a), (`SPI_READ), (2), (`IF_IDX(3)) );
spi_trans( (16'h0a), (`SPI_READ), (2), (`IF_IDX(4)) );
//读写
#1000
$fdisplay(spidata_file, "--->>>设置顺序地址后,检查顺序地址");
//spi_trans( (16'h0010), (`SPI_READ), (5), (`IF_IDX(0)) );
spi_trans( (16'h0000), (`SPI_READ), (16), (`IF_IDX(1)) );
spi_trans( (16'h0000), (`SPI_READ), (16), (`IF_IDX(2)) );
spi_trans( (16'h0000), (`SPI_READ), (16), (`IF_IDX(3)) );
spi_trans( (16'h0000), (`SPI_READ), (16), (`IF_IDX(4)) );
_t_end = $time;
$fdisplay(spidata_file, "该测试用例运行时间:%2tns", (_t_end - _t_start) / 1000);
end
`endif
`ifdef ENABLE_DET_TEST
/*---------------------------------------------------------------------------------------------------------
测试用例
---------------------------------------------------------------------------------------------------------*/
begin:DETECT_DEV_TESTCASE_2
//嗅探
_t_start = $time;
#1000
$fdisplay(spidata_file, "\n\n测试用例:发送嗅探包,需要在波形文件里检查");
$fdisplay(spidata_file, "嗅探使用SM0");
$fdisplay(spidata_file, "--->>>嗅探前,检查链路状态寄存器");
//spi_trans( (16'h00c0), (`SPI_READ), (6), (`IF_IDX(0)) );
spi_trans( (16'h00c0), (`SPI_READ), (6), (`IF_IDX(1)) );
spi_trans( (16'h00c0), (`SPI_READ), (6), (`IF_IDX(2)) );
spi_trans( (16'h00c0), (`SPI_READ), (6), (`IF_IDX(3)) );
spi_trans( (16'h00c0), (`SPI_READ), (6), (`IF_IDX(4)) );
$fdisplay(spidata_file, "--->>>嗅探");
//设置SM1在写入0x3地址触发enq
`include "detect_pkt.vh"
$fdisplay(spidata_file, "--->>>嗅探后,检查链路状态寄存器");
//spi_trans( (16'h00c0), (`SPI_READ), (6), (`IF_IDX(0)) );
spi_trans( (16'h00c0), (`SPI_READ), (6), (`IF_IDX(1)) );
spi_trans( (16'h00c0), (`SPI_READ), (6), (`IF_IDX(2)) );
spi_trans( (16'h00c0), (`SPI_READ), (6), (`IF_IDX(3)) );
spi_trans( (16'h00c0), (`SPI_READ), (6), (`IF_IDX(4)) );
_t_end = $time;
$fdisplay(spidata_file, "该测试用例运行时间:%2tns", (_t_end - _t_start) / 1000);
end
`endif
`ifdef ENABLE_SM1_SEND_TEST
begin:SM1_SEND_TESTCASE
_t_start = $time;
$fdisplay(spidata_file, "\n单读使用SM1");
$fdisplay(spidata_file, "--->>>SM1数据包");
`include "sm1_pkt.vh"
_t_end = $time;
$fdisplay(spidata_file, "该测试用例运行时间:%2tns", (_t_end - _t_start) / 1000);
end
`endif
`ifdef ENABLE_SMx_SEND_TEST
begin:SM2_SEND_TESTCASE
_t_start = $time;
#1000
$display("read&write @ %d", s_ShinTop_Mst.interface__io_cReg_timeStamp);
$fdisplay(spidata_file, "\n广播读使用SM2");
$fdisplay(spidata_file, "--->>>广播读");
`include "sm2_pkt.vh"
_t_end = $time;
$fdisplay(spidata_file, "该测试用例运行时间:%2tns", (_t_end - _t_start) / 1000);
end
begin:SM3_SEND_TESTCASE
_t_start = $time;
#1000
$display("read&write @ %d", s_ShinTop_Mst.interface__io_cReg_timeStamp);
$fdisplay(spidata_file, "\n广播写使用SM3");
$fdisplay(spidata_file, "--->>>SM3广播写");
`include "sm3_pkt.vh"
spi_trans( (16'h0800), (`SPI_READ), (16), (`IF_IDX(1)) );
spi_trans( (16'h0800), (`SPI_READ), (16), (`IF_IDX(2)) );
spi_trans( (16'h0800), (`SPI_READ), (16), (`IF_IDX(3)) );
spi_trans( (16'h0800), (`SPI_READ), (16), (`IF_IDX(4)) );
_t_end = $time;
$fdisplay(spidata_file, "该测试用例运行时间:%2tns", (_t_end - _t_start) / 1000);
end
`endif
`ifdef ENABLE_EXCHG_DATA_SEQ_TEST
/*---------------------------------------------------------------------------------------------------------
测试用例
1. 交换数据sm0~sm7
2. 交换数据sm0~sm7
3. 交换数据sm0~sm7(中断、状态)
4. 交换数据sm0~sm7(R/W/RW, BR/BW/BRW)
4. 寄存器单读/写/读写,寄存器广播读/写/读写
5. 以上交换数据的错误形式
---------------------------------------------------------------------------------------------------------*/
`ifdef ENABLE_EXCHG_DATA_SEQ0_TEST
begin:EXCHG_DATA_SEQ0_TESTCASE
_t_start = $time;
#1000
$fdisplay(spidata_file, "\n\n测试用例:交换数据");
$display("read&write @ %d", s_ShinTop_Mst.interface__io_cReg_timeStamp);
$fdisplay(spidata_file, "--->>>交换数据sm0~sm7");
`include "seq_0_pkt.vh"
_t_end = $time;
$fdisplay(spidata_file, "该测试用例运行时间:%2tns", (_t_end - _t_start) / 1000);
end
`endif
`ifdef ENABLE_EXCHG_DATA_SEQ1_TEST
begin:EXCHG_DATA_SEQ1_TESTCASE
_t_start = $time;
#1000
$display("read&write @ %d", s_ShinTop_Mst.interface__io_cReg_timeStamp);
$fdisplay(spidata_file, "\n--->>>交换数据写dev2_sm0/dev1_sm2/dev3_sm4/dev4_sm6");
`include "seq_1_pkt.vh"
spi_trans( (16'h1800), (`SPI_READ), (64), (`IF_IDX(1)) );
spi_trans( (16'h0800), (`SPI_READ), (64), (`IF_IDX(2)) );
spi_trans( (16'h2800), (`SPI_READ), (64), (`IF_IDX(3)) );
spi_trans( (16'h3800), (`SPI_READ), (64), (`IF_IDX(4)) );
_t_end = $time;
$fdisplay(spidata_file, "该测试用例运行时间:%2tns", (_t_end - _t_start) / 1000);
end
`endif
`ifdef ENABLE_EXCHG_DATA_SEQ2_TEST
begin:EXCHG_DATA_SEQ2_TESTCASE
_t_start = $time;
#1000
$display("read&write @ %d", s_ShinTop_Mst.interface__io_cReg_timeStamp);
$fdisplay(spidata_file, "\n--->>>交换数据读dev1_sm1/dev2_sm3/dev3_sm5/dev4_sm7");
txBuf[3] = 8'h80;
txBuf[4] = 8'h00;
spi_trans((16'h0306), (`SPI_WRITE), (2), (`IF_IDX(1)) );//dev1_sm1
txBuf[3] = 8'h98;
txBuf[4] = 8'h00;
spi_trans((16'h030e), (`SPI_WRITE), (2), (`IF_IDX(2)) );//dev2_sm3
txBuf[3] = 8'h81;
txBuf[4] = 8'h00;
spi_trans((16'h0316), (`SPI_WRITE), (2), (`IF_IDX(3)) );//dev2_sm3
txBuf[3] = 8'h8c;
txBuf[4] = 8'h00;
spi_trans((16'h031e), (`SPI_WRITE), (2), (`IF_IDX(4)) );//dev2_sm3
for (integer i=0; i < 128; i++) begin
txBuf[i + 3] = i + 1;
end
spi_trans( (16'h1000), (`SPI_WRITE), (128), (`IF_IDX(1)) );
for (integer i=0; i < 152; i++) begin
txBuf[i + 3] = i + 2;
end
spi_trans( (16'h2000), (`SPI_WRITE), (152), (`IF_IDX(2)) );
for (integer i=0; i < 129; i++) begin
txBuf[i + 3] = i + 3;
end
spi_trans( (16'h3000), (`SPI_WRITE), (129), (`IF_IDX(3)) );
for (integer i=0; i < 140; i++) begin
txBuf[i + 3] = i + 4;
end
spi_trans( (16'h4000), (`SPI_WRITE), (140), (`IF_IDX(4)) );
`include "seq_2_pkt.vh"
_t_end = $time;
$fdisplay(spidata_file, "该测试用例运行时间:%2tns", (_t_end - _t_start) / 1000);
end
`endif
`endif
`ifdef ENABLE_EXCHG_DATA_BC_TEST
begin:EXCHG_DATA_BC_R_TESTCASE
_t_start = $time;
#1000
$fdisplay(spidata_file, "\n\n测试用例:广播交换数据");
$display("read&write @ %d", s_ShinTop_Mst.interface__io_cReg_timeStamp);
$fdisplay(spidata_file, "\n--->>>广播读");
`include "bc_r_pkt.vh"
`DEF_bc_r_pkt_sm(txBuf);
spi_trans( (`MST_TX_LEN_ADDR), (`SPI_WRITE), (2), (`IF_IDX(0)) );
spi_trans( (`MST_RX_LEN_ADDR), (`SPI_WRITE), (2), (`IF_IDX(0)) );
$fdisplay(spidata_file, "<<发包:");
`DEF_bc_r_pkt(txBuf);
spi_trans( (`MST_TX_ADDR), (`SPI_WRITE), (`DEF_bc_r_pkt_len), (`IF_IDX(0)) ); //写入SM1
//发布请求
txBuf[0+3] = `MST_TX_TRG;
spi_trans( (16'h20), (`SPI_WRITE), (1), (`IF_IDX(0)) );//发送SM0 接收SM0, 请求发送
@(posedge isResp) #5 begin end
$fdisplay(spidata_file, ">>回包:");
spi_trans( (`MST_RX_ADDR), (`SPI_READ), (`DEF_bc_r_pkt_len), (`IF_IDX(0)) );//读一下SM0的切换地址将fifo弹出
_t_end = $time;
$fdisplay(spidata_file, "该测试用例运行时间:%2tns", (_t_end - _t_start) / 1000);
end
begin:EXCHG_DATA_BC_W_TESTCASE
_t_start = $time;
#1000
$display("read&write @ %d", s_ShinTop_Mst.interface__io_cReg_timeStamp);
$fdisplay(spidata_file, "\n--->>>广播写");
`include "bc_w_pkt.vh"
`DEF_bc_w_pkt_sm(txBuf);
spi_trans( (`MST_TX_LEN_ADDR), (`SPI_WRITE), (2), (`IF_IDX(0)) );
spi_trans( (`MST_RX_LEN_ADDR), (`SPI_WRITE), (2), (`IF_IDX(0)) );
$fdisplay(spidata_file, "<<发包:");
`DEF_bc_w_pkt(txBuf);
spi_trans( (`MST_TX_ADDR), (`SPI_WRITE), (`DEF_bc_w_pkt_len), (`IF_IDX(0)) ); //写入SM1
//发布请求
txBuf[0+3] = `MST_TX_TRG;
spi_trans( (16'h20), (`SPI_WRITE), (1), (`IF_IDX(0)) );//发送SM0 接收SM0, 请求发送
@(posedge isResp) #5 begin end
$fdisplay(spidata_file, ">>回包:");
spi_trans( (`MST_RX_ADDR), (`SPI_READ), (`DEF_bc_w_pkt_len), (`IF_IDX(0)) );//读一下SM0的切换地址将fifo弹出
spi_trans( (16'h0800), (`SPI_READ), (32), (`IF_IDX(1)) );
spi_trans( (16'h0800), (`SPI_READ), (32), (`IF_IDX(2)) );
spi_trans( (16'h0800), (`SPI_READ), (32), (`IF_IDX(3)) );
spi_trans( (16'h0800), (`SPI_READ), (32), (`IF_IDX(4)) );
_t_end = $time;
$fdisplay(spidata_file, "该测试用例运行时间:%2tns", (_t_end - _t_start) / 1000);
end
`endif
`ifdef ENABLE_SYNC_TEST
/*---------------------------------------------------------------------------------------------------------
测试用例
1. 测试 同步(sync) 和 同步输出 (sync_out)
---------------------------------------------------------------------------------------------------------*/
// 同步
begin:SYNC_TESTCASE0
_t_start = $time;
#1000
$display("sync @ %d", s_ShinTop_Mst.interface__io_cReg_timeStamp);
$fdisplay(spidata_file, "\n\n测试用例:测试同步(sync)和同步输出(sync_out)");
//设置SM1在写入 0x18 len触发enq
`include "sync_pkt.vh"
`DEF_sync_pkt_sm(txBuf);
spi_trans( (`MST_TX_LEN_ADDR), (`SPI_WRITE), (2), (`IF_IDX(0)) );
spi_trans( (`MST_RX_LEN_ADDR), (`SPI_WRITE), (2), (`IF_IDX(0)) );
$fdisplay(spidata_file, "<<发包:");
`DEF_sync_pkt(txBuf);
spi_trans( (`MST_TX_ADDR), (`SPI_WRITE), (`DEF_sync_pkt_len), (`IF_IDX(0)) ); //写入SM1
//写入替换时间戳替换地址
txBuf[0+3] = 8'h0c;
txBuf[1+3] = 8'hc0;
spi_trans( (16'h24), (`SPI_WRITE), (2), (`IF_IDX(0)) ); //写入替换时间戳替换地址寄存器
//发布请求
txBuf[0+3] = `MST_TX_TRG;
spi_trans( (16'h20), (`SPI_WRITE), (1), (`IF_IDX(0)) );//发送SM0 接收SM0, 请求发送
@(posedge isResp) #5 begin
$fdisplay(spidata_file, ">>回包:");
spi_trans( (`MST_RX_ADDR), (`SPI_READ), (`DEF_sync_pkt_len), (`IF_IDX(0)) );//读一下SM0的切换地址将fifo弹出
end
//清除替换时间戳替换地址
txBuf[0+3] = 8'h00;
txBuf[1+3] = 8'h00;
spi_trans( (16'h25), (`SPI_WRITE), (2), (`IF_IDX(0)) ); //清除替换时间戳替换地址寄存器
_t_end = $time;
$fdisplay(spidata_file, "该测试用例运行时间:%2tns", (_t_end - _t_start) / 1000);
end
`endif
`ifdef ENABLE_SYNC_SIG0_TEST
begin:SYNC_TESTCASE1
_t_start = $time;
#1000
`include "sync_sig_pkt.vh"
//spi_trans( (16'h0100), (`SPI_READ), (32), (`IF_IDX(0)) );
spi_trans( (16'h0100), (`SPI_READ), (16'h48), (`IF_IDX(1)) );
spi_trans( (16'h0100), (`SPI_READ), (16'h48), (`IF_IDX(2)) );
spi_trans( (16'h0100), (`SPI_READ), (16'h48), (`IF_IDX(3)) );
spi_trans( (16'h0100), (`SPI_READ), (16'h48), (`IF_IDX(4)) );
#100000
//清脉冲
txBuf[0+3] = 0; //负载0x122 sync0脉冲宽度
txBuf[1+3] = 0; //负载0x123
txBuf[2+3] = 0; //负载0x124 sync1脉冲宽度
txBuf[3+3] = 0; //负载0x125
txBuf[4+3] = 0; //负载0x126 sync2脉冲宽度
txBuf[5+3] = 0; //负载0x127
txBuf[6+3] = 0; //负载0x128 sync3脉冲宽度
txBuf[7+3] = 0; //负载0x129
spi_trans( (16'h0122), (`SPI_WRITE), (8), (`IF_IDX(1)) ); //slv2
spi_trans( (16'h0122), (`SPI_WRITE), (8), (`IF_IDX(2)) ); //slv2
spi_trans( (16'h0122), (`SPI_WRITE), (8), (`IF_IDX(3)) ); //slv2
spi_trans( (16'h0122), (`SPI_WRITE), (8), (`IF_IDX(4)) ); //slv2
#100000
_t_end = $time;
$fdisplay(spidata_file, "该测试用例运行时间:%2tns", (_t_end - _t_start) / 1000);
end
`endif
`ifdef ENABLE_SYNC_SIG1_TEST
begin:SYNC_TESTCASE2
_t_start = $time;
#1000
`include "sync_sig2_pkt.vh"
//spi_trans( (16'h0100), (`SPI_READ), (32), (`IF_IDX(0)) );
spi_trans( (16'h0100), (`SPI_READ), (16'h48), (`IF_IDX(1)) );
spi_trans( (16'h0100), (`SPI_READ), (16'h48), (`IF_IDX(2)) );
spi_trans( (16'h0100), (`SPI_READ), (16'h48), (`IF_IDX(3)) );
spi_trans( (16'h0100), (`SPI_READ), (16'h48), (`IF_IDX(4)) );
_t_end = $time;
$fdisplay(spidata_file, "该测试用例运行时间:%2tns", (_t_end - _t_start) / 1000);
end
`endif
/*
#50000
//复位系统
txBuf[0+3] = 8'h01;
spi_trans( (16'h40), (`SPI_WRITE), (1), (`IF_IDX(0)) );//复位主站
spi_trans( (16'h40), (`SPI_WRITE), (1), (`IF_IDX(1)) );//复位从站2
*/
#1000000
$display("Testcase Finished! Time Out !!!");
$fclose(spidata_file);
$stop;
end
endmodule