Files
eb001/tb/shinTest/ShinTopSpiTb.v

999 lines
27 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
module ShinTopSpiTb(
);
reg clock;
reg reset;
reg clk8x;
reg [15:0] multiCLK;
`include "dev_predef.vh"
`ifdef DEFINE_SLAVE_DEVICE
`define DEV_NUM 4 //slave num
`define ALL_DEV_NUM (`DEV_NUM + 1) // slave + master
`define SPI_CSN_NUM (`ALL_DEV_NUM * 4)
`define HW_SERIAL 0 //48'h31303050584c //(48'h4c5850303031)
`define IQSPI_PINS(N) (`N*4+3):(`N*4)
`define EQSPI_PINS(N) ((`N + `ALL_DEV_NUM)*4+3):((`N + `ALL_DEV_NUM)*4)
//`define AQSPI_PINS(N) ((`N + `ALL_DEV_NUM)*4+3):((`N + `ALL_DEV_NUM)*4)
`define IQSPI_MISO(N) qspi_miso[`IQSPI_PINS(`N)]
`define EQSPI_MISO(N) qspi_miso[`EQSPI_PINS(`N)]
`define IQSPI_CSN_NUM(id) (`id)
`define ESPI_CSN_NUM(id) ((`id)+(`ALL_DEV_NUM))
`define EQSPI_CSN_NUM(id) ((`id)+(`ALL_DEV_NUM)*2)
//`define AQSPI_CSN_NUM(id) ((`id)+(`ALL_DEV_NUM)*3)
`define IQSPI_CSN(id) spi_csn[`IQSPI_CSN_NUM(`id)]
`define ESPI_CSN(id) spi_csn[`ESPI_CSN_NUM(`id)]
`define EQSPI_CSN(id) spi_csn[`EQSPI_CSN_NUM(`id)]
//`define AQSPI_CSN(id) spi_csn[`AQSPI_CSN_NUM(`id)]
`define QSPI_MUX_MISO_INIT \
(`IQSPI_MISO(0) & ~{4{`IQSPI_CSN(0)}}) |\
(`IQSPI_MISO(1) & ~{4{`IQSPI_CSN(1)}}) |\
(`IQSPI_MISO(2) & ~{4{`IQSPI_CSN(2)}}) |\
(`IQSPI_MISO(3) & ~{4{`IQSPI_CSN(3)}}) |\
(`IQSPI_MISO(4) & ~{4{`IQSPI_CSN(4)}}) |\
(`EQSPI_MISO(0) & ~{4{`EQSPI_CSN(0)}}) |\
(`EQSPI_MISO(1) & ~{4{`EQSPI_CSN(1)}}) |\
(`EQSPI_MISO(2) & ~{4{`EQSPI_CSN(2)}}) |\
(`EQSPI_MISO(3) & ~{4{`EQSPI_CSN(3)}}) |\
(`EQSPI_MISO(4) & ~{4{`EQSPI_CSN(4)}})
`define SPI_MUX_MISO_INIT \
( spi_miso[0] & ~`ESPI_CSN(0)) |\
( spi_miso[1] & ~`ESPI_CSN(1)) |\
( spi_miso[2] & ~`ESPI_CSN(2)) |\
( spi_miso[3] & ~`ESPI_CSN(3)) |\
( spi_miso[4] & ~`ESPI_CSN(4))
`endif
wire [(`DEV_NUM - 1):0] dDat_w;
wire [(`DEV_NUM - 1):0] uDat_w;
wire spi_sck;
wire spi_mosi;
wire [(`ALL_DEV_NUM - 1):0] spi_miso;
reg [(`SPI_CSN_NUM - 1):0] spi_csn;
wire qspi_sck;
wire [3:0] qspi_mosi;
//wire [40-1:0] qspi_miso;
wire [(`ALL_DEV_NUM * 4 * 3 - 1):0] qspi_miso;
integer spidata_file;
integer c_line;
integer _pos;
integer _len;
integer _t_start;
integer _t_end;
reg [63:0] _temp_time;
reg _reset_deactive;
wire [(`ALL_DEV_NUM - 1):0] isSoftReset;
reg [(`ALL_DEV_NUM - 1):0] isSoftReset_reg;
generate
for( genvar i = 0; i < `ALL_DEV_NUM; i = i + 1 ) begin
always @(posedge clock or posedge reset) begin
if(reset) isSoftReset_reg[i] <= 1'b0;
else isSoftReset_reg[i] <= isSoftReset[i];
end
end
endgenerate
wire [`DEV_NUM:0] io_int_sig;
reg latch0;
reg latch1;
ShinTop s_ShinTop_Mst(
.clock(clock),
.reset(reset | isSoftReset_reg[0]),
.io_multiCLK_0(multiCLK[0]),
.io_multiCLK_1(multiCLK[1]),
.io_multiCLK_2(multiCLK[2]),
.io_multiCLK_3(multiCLK[3]),
.io_multiCLK_4(multiCLK[4]),
.io_multiCLK_5(multiCLK[5]),
.io_multiCLK_6(multiCLK[6]),
.io_multiCLK_7(multiCLK[7]),
.io_multiCLK_8(multiCLK[8]),
.io_multiCLK_9(multiCLK[9]),
.io_multiCLK_10(multiCLK[10]),
.io_multiCLK_11(multiCLK[11]),
.io_multiCLK_12(multiCLK[12]),
.io_multiCLK_13(multiCLK[13]),
.io_multiCLK_14(multiCLK[14]),
.io_multiCLK_15(multiCLK[15]),
.io_multiCLKDiv4_0(multiCLK[0]),
.io_multiCLKDiv4_1(multiCLK[4]),
.io_multiCLKDiv4_2(multiCLK[8]),
.io_multiCLKDiv4_3(multiCLK[12]),
.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(`IQSPI_MISO(0)),
.io_iqspi_isDirIn(),
.io_iqspi_csn(`IQSPI_CSN(0)),
.io_ospi_sck (spi_sck),
.io_ospi_mosi(spi_mosi),
.io_ospi_miso(spi_miso[0]),
.io_ospi_csn (`ESPI_CSN(0)),
.io_oqspi_sck(qspi_sck),
.io_oqspi_mosi(qspi_mosi),
.io_oqspi_miso(`EQSPI_MISO(0)),
.io_oqspi_isDirIn(),
.io_oqspi_csn(`EQSPI_CSN(0)),
.io_aqspi_sck(qspi_sck),
.io_aqspi_mosi(qspi_mosi),
.io_aqspi_miso(`AQSPI_MISO(0)),
.io_aqspi_isDirIn(),
.io_aqspi_csn(`AQSPI_CSN(0)),
.io_isSoftReset(isSoftReset[0]),
.io_interrupt(io_int_sig[0]),
.io_latchPin_0(latch0),
.io_latchPin_1(latch1),
.io_hwSerial(`HW_SERIAL),
.io_uniCode(64'h0)
);
`include "slave_dev_def.vh"
`ifdef DEFINE_SLAVE_DEVICE
ShinTop s_ShinTop_slv0(
.clock(clock),
.reset(reset | isSoftReset_reg[1]),
.io_multiCLK_0(multiCLK[0]),
.io_multiCLK_1(multiCLK[1]),
.io_multiCLK_2(multiCLK[2]),
.io_multiCLK_3(multiCLK[3]),
.io_multiCLK_4(multiCLK[4]),
.io_multiCLK_5(multiCLK[5]),
.io_multiCLK_6(multiCLK[6]),
.io_multiCLK_7(multiCLK[7]),
.io_multiCLK_8(multiCLK[8]),
.io_multiCLK_9(multiCLK[9]),
.io_multiCLK_10(multiCLK[10]),
.io_multiCLK_11(multiCLK[11]),
.io_multiCLK_12(multiCLK[12]),
.io_multiCLK_13(multiCLK[13]),
.io_multiCLK_14(multiCLK[14]),
.io_multiCLK_15(multiCLK[15]),
.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(`IQSPI_MISO(1)),
.io_iqspi_isDirIn(),
.io_iqspi_csn(`IQSPI_CSN(1)),
.io_ospi_sck (spi_sck),
.io_ospi_mosi(spi_mosi),
.io_ospi_miso(spi_miso[1]),
.io_ospi_csn (`ESPI_CSN(1)),
.io_oqspi_sck(qspi_sck),
.io_oqspi_mosi(qspi_mosi),
.io_oqspi_miso(`EQSPI_MISO(1)),
.io_oqspi_isDirIn(),
.io_oqspi_csn(`EQSPI_CSN(1)),
.io_isSoftReset(isSoftReset[1]),
.io_interrupt(io_int_sig[1]),
.io_latchPin_0(latch0),
.io_latchPin_1(latch1),
.io_hwSerial(`HW_SERIAL),
.io_uniCode(0)
);
ShinTop s_ShinTop_slv1(
.clock(clock),
.reset(reset | isSoftReset_reg[2]),
.io_multiCLK_0(multiCLK[0]),
.io_multiCLK_1(multiCLK[1]),
.io_multiCLK_2(multiCLK[2]),
.io_multiCLK_3(multiCLK[3]),
.io_multiCLK_4(multiCLK[4]),
.io_multiCLK_5(multiCLK[5]),
.io_multiCLK_6(multiCLK[6]),
.io_multiCLK_7(multiCLK[7]),
.io_multiCLK_8(multiCLK[8]),
.io_multiCLK_9(multiCLK[9]),
.io_multiCLK_10(multiCLK[10]),
.io_multiCLK_11(multiCLK[11]),
.io_multiCLK_12(multiCLK[12]),
.io_multiCLK_13(multiCLK[13]),
.io_multiCLK_14(multiCLK[14]),
.io_multiCLK_15(multiCLK[15]),
.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(`IQSPI_MISO(2)),
.io_iqspi_isDirIn(),
.io_iqspi_csn(`IQSPI_CSN(2)),
.io_ospi_sck (spi_sck),
.io_ospi_mosi(spi_mosi),
.io_ospi_miso(spi_miso[2]),
.io_ospi_csn (`ESPI_CSN(2)),
.io_oqspi_sck(qspi_sck),
.io_oqspi_mosi(qspi_mosi),
.io_oqspi_miso(`EQSPI_MISO(2)),
.io_oqspi_isDirIn(),
.io_oqspi_csn(`EQSPI_CSN(2)),
.io_isSoftReset(isSoftReset[2]),
.io_interrupt(io_int_sig[2]),
.io_latchPin_0(latch0),
.io_latchPin_1(latch1),
.io_hwSerial(`HW_SERIAL),
.io_uniCode(0)
);
ShinTop s_ShinTop_slv2(
.clock(clock),
.reset(reset | isSoftReset_reg[3]),
.io_multiCLK_0(multiCLK[0]),
.io_multiCLK_1(multiCLK[1]),
.io_multiCLK_2(multiCLK[2]),
.io_multiCLK_3(multiCLK[3]),
.io_multiCLK_4(multiCLK[4]),
.io_multiCLK_5(multiCLK[5]),
.io_multiCLK_6(multiCLK[6]),
.io_multiCLK_7(multiCLK[7]),
.io_multiCLK_8(multiCLK[8]),
.io_multiCLK_9(multiCLK[9]),
.io_multiCLK_10(multiCLK[10]),
.io_multiCLK_11(multiCLK[11]),
.io_multiCLK_12(multiCLK[12]),
.io_multiCLK_13(multiCLK[13]),
.io_multiCLK_14(multiCLK[14]),
.io_multiCLK_15(multiCLK[15]),
.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(`IQSPI_MISO(3)),
.io_iqspi_isDirIn(),
.io_iqspi_csn(`IQSPI_CSN(3)),
.io_ospi_sck (spi_sck),
.io_ospi_mosi(spi_mosi),
.io_ospi_miso(spi_miso[3]),
.io_ospi_csn (`ESPI_CSN(3)),
.io_oqspi_sck(qspi_sck),
.io_oqspi_mosi(qspi_mosi),
.io_oqspi_miso(`EQSPI_MISO(3)),
.io_oqspi_isDirIn(),
.io_oqspi_csn(`EQSPI_CSN(3)),
.io_isSoftReset(isSoftReset[3]),
.io_interrupt(io_int_sig[3]),
.io_latchPin_0(latch0),
.io_latchPin_1(latch1),
.io_hwSerial(`HW_SERIAL),
.io_uniCode(0)
);
ShinTop s_ShinTop_slv3(
.clock(clock),
.reset(reset | isSoftReset_reg[4]),
.io_multiCLK_0(multiCLK[0]),
.io_multiCLK_1(multiCLK[1]),
.io_multiCLK_2(multiCLK[2]),
.io_multiCLK_3(multiCLK[3]),
.io_multiCLK_4(multiCLK[4]),
.io_multiCLK_5(multiCLK[5]),
.io_multiCLK_6(multiCLK[6]),
.io_multiCLK_7(multiCLK[7]),
.io_multiCLK_8(multiCLK[8]),
.io_multiCLK_9(multiCLK[9]),
.io_multiCLK_10(multiCLK[10]),
.io_multiCLK_11(multiCLK[11]),
.io_multiCLK_12(multiCLK[12]),
.io_multiCLK_13(multiCLK[13]),
.io_multiCLK_14(multiCLK[14]),
.io_multiCLK_15(multiCLK[15]),
.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(`IQSPI_MISO(4)),
.io_iqspi_isDirIn(),
.io_iqspi_csn(`IQSPI_CSN(4)),
.io_ospi_sck (spi_sck),
.io_ospi_mosi(spi_mosi),
.io_ospi_miso(spi_miso[4]),
.io_ospi_csn (`ESPI_CSN(4)),
.io_oqspi_sck(qspi_sck),
.io_oqspi_mosi(qspi_mosi),
.io_oqspi_miso(`EQSPI_MISO(4)),
.io_oqspi_isDirIn(),
.io_oqspi_csn(`EQSPI_CSN(4)),
.io_isSoftReset(isSoftReset[4]),
.io_interrupt(io_int_sig[4]),
.io_latchPin_0(latch0),
.io_latchPin_1(latch1),
.io_hwSerial(`HW_SERIAL),
.io_uniCode(0)
);
`endif
initial begin
clock = 0;
clk8x = 0;
reset = 1;
latch0 = 0;
latch1 = 0;
_reset_deactive = 1'b0;
$timeformat(-9, 2, " ns", 8);
spi_csn = {`SPI_CSN_NUM{1'b1}}; //~15'b0;
#100
reset <= 1;
#240
reset <= 0;
//#20000000
#1000000000
`ifdef USING_OSPI
#1000000000
#1000000000
`endif
//#5000000
$display("Time Out !!!");
$fclose(spidata_file);
//$stop;
$finish;
end
initial begin
forever begin #20 clk8x <= ~clk8x; end
end
initial begin
forever begin #80 clock <= ~clock; end
end
generate
for( genvar i = 0; i < 16; i = i + 1 ) begin
initial begin
multiCLK[i] = 0;
for( integer j = 0; j < i; j = j + 1 ) begin
#10
;
end
forever begin #80 multiCLK[i] <= ~multiCLK[i]; end
end
end
endgenerate
initial
begin
spidata_file = $fopen("spi_trans_data.txt", "w");
if (!spidata_file) $display("文件打开失败");
`ifdef VCS_COMPILE
$dumpfile("./generated/wave.vcd"); //生成的vcd文件名称
$dumpvars(0, ShinTopSpiTb);//tb模块名称
//$dumpvars(0, ShinTopSpiTb.s_ShinTop_Mst);//tb模块名称
//$dumpvars(0, ShinTopSpiTb.s_ShinTop_slv124);//tb模块名称
//$dumpvars(0, ShinTopSpiTb.s_ShinTop_slv125);//tb模块名称
//$dumpvars(0, ShinTopSpiTb.s_ShinTop_slv126);//tb模块名称
//$dumpvars(0, ShinTopSpiTb.s_ShinTop_slv127);//tb模块名称
`endif
`ifdef IVERILOG_COMPILE
$dumpfile("./generated/wave.fst"); //生成的fst文件名称
$dumpvars(0, ShinTopSpiTb);//tb模块名称
`endif
end
always @(posedge reset) begin
_reset_deactive <= 1'b0;
end
always @(negedge reset) begin
_reset_deactive <= 1'b1;
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_MUX_MISO_INIT;
//( 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]}});
/*
(`IQSPI_MISO(0) & ~{4{`IQSPI_CSN(0)}}) |
(`IQSPI_MISO(1) & ~{4{`IQSPI_CSN(1)}}) |
(`IQSPI_MISO(2) & ~{4{`IQSPI_CSN(2)}}) |
(`IQSPI_MISO(3) & ~{4{`IQSPI_CSN(3)}}) |
(`IQSPI_MISO(4) & ~{4{`IQSPI_CSN(4)}}) |
(`EQSPI_MISO(0) & ~{4{`EQSPI_CSN(0)}}) |
(`EQSPI_MISO(1) & ~{4{`EQSPI_CSN(1)}}) |
(`EQSPI_MISO(2) & ~{4{`EQSPI_CSN(2)}}) |
(`EQSPI_MISO(3) & ~{4{`EQSPI_CSN(3)}}) |
(`EQSPI_MISO(4) & ~{4{`EQSPI_CSN(4)}});
*/
wire spi_mux_miso = `SPI_MUX_MISO_INIT;
//( 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] );
/*
( spi_miso[0] & ~`ESPI_CSN(0)) |
( spi_miso[1] & ~`ESPI_CSN(1)) |
( spi_miso[2] & ~`ESPI_CSN(2)) |
( spi_miso[3] & ~`ESPI_CSN(3)) |
( spi_miso[4] & ~`ESPI_CSN(4));
*/
reg isReq = 0;
reg isBusy = 0;
reg [11:0] length;
reg [16: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
//DEV_NUM
//ALL_DEV_NUM
wire isQspi = (idx >= 0 && idx <= (`ALL_DEV_NUM - 1)) || idx >= (`ALL_DEV_NUM * 2);
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 ( idx >= (`ALL_DEV_NUM * 3) ) begin
if( &bitCnt ) begin
byteCnt <= byteCnt +1;
transCnt <= transCnt + 1;
if( (txBuf[2] & 8'h80) === 8'h80 & nextByteCnt >= 5) begin
rxBuf[byteCnt] <= exChangeRegi;
//$display("spi read out %x", exChangeRegi);
end
if( (txBuf[2] & 8'h80) === 8'h80 & nextByteCnt >= 4) 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
if( &bitCnt ) begin
byteCnt <= byteCnt +1;
transCnt <= transCnt + 1;
if( txBuf[2] === 8'h80 & nextByteCnt >= 4) begin
rxBuf[byteCnt] <= exChangeRegi;
//$display("spi read out %x", exChangeRegi);
end
if( txBuf[2] === 8'h80 & 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
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 [16:0] sidx );
begin
txBuf[0] <= saddress[15:8];
txBuf[1] <= saddress[7:0];
if (sidx >=(`ALL_DEV_NUM * 3)) begin
txBuf[2] <= (scmd | slength[12:8]);
txBuf[3] <= slength[7:0];
length <= slength + 4;
end else begin
txBuf[2] <= scmd;
length <= slength + 3;
end
idx <= sidx;
#5
@(negedge sck)
isReq <= 1;
@(posedge sck) #5
isReq <= 0;
@( negedge isBusy) #1000
begin
//$fwrite(spidata_file, "------------%5t------------\n", $realtime);
if (sidx >=(`ALL_DEV_NUM * 3)) begin
$fwrite(spidata_file, "T:%t \tdev:%4d(%4d), addr:0x%02h%02h, %s, len:%4d (0x%02h%02h)\n",
$realtime,
sidx % (`ALL_DEV_NUM), sidx,
txBuf[0],
txBuf[1],
(((txBuf[2] & 8'h80) == 0)? "Write":" Read"),
slength,
txBuf[2], txBuf[3]);
end else begin
$fwrite(spidata_file, "T:%t \tdev:%4d(%4d), addr:0x%02h%02h, %s, len:%4d\n",
$realtime,
sidx % (`ALL_DEV_NUM), sidx,
txBuf[0],
txBuf[1],
(((txBuf[2] & 8'h80) == 0)? "Write":" Read"),
slength);
end
if (sidx >=(`ALL_DEV_NUM * 3)) begin _pos = 4; end
else begin _pos = 3; end
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 == `ALL_DEV_NUM)
|| (sidx == (`ALL_DEV_NUM * 2))
|| (sidx == (`ALL_DEV_NUM * 3))
)
) begin
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 < 6; _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
begin:PRINT_PKT_COMMENT
integer dev;
integer addr_type;
integer addr;
integer cmd;
integer len;
if (scmd == 0) begin
addr_type = txBuf[_pos + 1] & 8'h3;
dev = (txBuf[_pos] * 256) >> 2;
dev = dev + ((txBuf[_pos + 1] >> 2) & 8'hff);
addr = txBuf[_pos + 2] * 256 + (txBuf[_pos + 3] & 8'hff);
cmd = (txBuf[_pos + 4] >> 4) & 8'h0f;
len = (txBuf[_pos + 4] & 8'h0f) * 256 + (txBuf[_pos + 5] & 8'hff);
end else begin
addr_type = rxBuf[_pos + 1] & 8'h3;
dev = (rxBuf[_pos] * 256) >> 2;
dev = dev + ((rxBuf[_pos + 1] >> 2) & 8'hff);
addr = rxBuf[_pos + 2] * 256 + (rxBuf[_pos + 3] & 8'hff);
cmd = (rxBuf[_pos + 4] >> 4) & 8'h0f;
len = (rxBuf[_pos + 4] & 8'h0f) * 256 + (rxBuf[_pos + 5] & 8'hff);
end
if (addr_type == 0)
$fwrite(spidata_file, "// type:%3d dev:%3d addr:0x%04x cmd:0x%1x len:%3d", addr_type, dev, addr[15:0], cmd[3:0], len);
else begin
addr = dev * 65536 + addr;
$fwrite(spidata_file, "// type:%3d addr:0x%08x cmd:0x%1x len:%3d", addr_type, addr, cmd[3:0], len);
end
end
$fwrite(spidata_file, "\n{{ ");
_pos = _pos + 6;
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;
for (integer _k = 0; _k < 2; _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
_pos = _pos + 2;
$fwrite(spidata_file, "\n");
end
end else begin
for (integer i=0; i<slength; i++) begin
if (scmd == 0) begin
$fwrite(spidata_file, "%02h ", txBuf[i + _pos]);
end else begin
$fwrite(spidata_file, "%02h ", rxBuf[i + _pos]);
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
always @(posedge _reset_deactive) begin
if (io_int_sig[0]) $fdisplay(spidata_file, "**MST INT SETUP: %t", $realtime);
if (io_int_sig[1]) $fdisplay(spidata_file, "**SLV0 INT SETUP: %t", $realtime);
if (io_int_sig[2]) $fdisplay(spidata_file, "**SLV1 INT SETUP: %t", $realtime);
if (io_int_sig[3]) $fdisplay(spidata_file, "**SLV2 INT SETUP: %t", $realtime);
if (io_int_sig[4]) $fdisplay(spidata_file, "**SLV3 INT SETUP: %t", $realtime);
end
always @(posedge io_int_sig[0]) begin
if (_reset_deactive == 1'b1)
$fdisplay(spidata_file, "**MST INT SETUP: %t", $realtime);
end
always @(posedge io_int_sig[1]) begin
if (_reset_deactive == 1'b1)
$fdisplay(spidata_file, "**SLV0 INT SETUP: %t", $realtime);
end
always @(posedge io_int_sig[2]) begin
if (_reset_deactive == 1'b1)
$fdisplay(spidata_file, "**SLV1 INT SETUP: %t", $realtime);
end
always @(posedge io_int_sig[3]) begin
if (_reset_deactive == 1'b1)
$fdisplay(spidata_file, "**SLV2 INT SETUP: %t", $realtime);
end
always @(posedge io_int_sig[4]) begin
if (_reset_deactive == 1'b1)
$fdisplay(spidata_file, "**SLV3 INT SETUP: %t", $realtime);
end
always @(negedge io_int_sig[0]) begin
if (_reset_deactive == 1'b1)
$fdisplay(spidata_file, "**MST INT CLEAR: %t", $realtime);
end
always @(negedge io_int_sig[1]) begin
if (_reset_deactive == 1'b1)
$fdisplay(spidata_file, "**SLV0 INT CLEAR: %t", $realtime);
end
always @(negedge io_int_sig[2]) begin
if (_reset_deactive == 1'b1)
$fdisplay(spidata_file, "**SLV1 INT CLEAR: %t", $realtime);
end
always @(negedge io_int_sig[3]) begin
if (_reset_deactive == 1'b1)
$fdisplay(spidata_file, "**SLV2 INT CLEAR: %t", $realtime);
end
always @(negedge io_int_sig[4]) begin
if (_reset_deactive == 1'b1)
$fdisplay(spidata_file, "**SLV3 INT CLEAR: %t", $realtime);
end
//`define USING_IQSPI
//`define USING_OSPI
//`define USING_OQSPI
//`define USING_AQSPI
`ifdef USING_IQSPI
`define INTERFACE_IDX 0//internal spi
`define ARRAY_IDX_OFF 3
`endif
`ifdef USING_OSPI
`define INTERFACE_IDX (`ALL_DEV_NUM)//internal spi
`define ARRAY_IDX_OFF 3
`endif
`ifdef USING_OQSPI
`define INTERFACE_IDX (`ALL_DEV_NUM * 2)//internal spi
`define ARRAY_IDX_OFF 3
`endif
`ifdef USING_AQSPI
`define INTERFACE_IDX (`ALL_DEV_NUM * 3)//internal spi
`define ARRAY_IDX_OFF 4
`endif
`define IF_IDX(idx) ((`INTERFACE_IDX)+(idx))
`define IF_IQSPI(idx) ((idx))
`define IF_OQSPI(idx) ((`ALL_DEV_NUM * 2) + (idx))
`define IF_AQSPI(idx) ((`ALL_DEV_NUM * 3) + (idx))
`define IF_OSPI(idx) ((`ALL_DEV_NUM) + (idx))
`define SPI_WRITE 8'h00
`define SPI_READ 8'h80
`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)
`define BEGIN_TESTCASE(filename) \
integer logh;\
logh = $fopen(filename, "w")
`define END_TESTCASE(filename) \
$fclose(logh)
`define SPI_TRANS(addr, cmd, len, iface) \
if (cmd == (`SPI_WRITE)) begin \
f_write(logh, addr, cmd, len);\
for (integer _k = 0; _k < len; _k++) begin \
$fwrite(logh, "8'h%02h ", txBuf[`ARRAY_IDX_OFF + _k]); \
end \
spi_trans(addr, cmd, len, iface); \
end else begin \
spi_trans(addr, cmd, len, iface); \
f_write(logh, addr, cmd, len);\
for (integer _k = 0; _k < len; _k++) begin \
$fwrite(logh, "8'h%02h ", rxBuf[`ARRAY_IDX_OFF + _k]); \
end \
end \
$fwrite(logh, "\n")
task f_write(input [31:0] logh, input [15:0] saddress, input [7:0] scmd, input [12:0] slength);
begin
$fwrite(logh, "16'h%04h 8'h%02h 16'h%04h ", saddress, scmd, slength);
end
endtask
task wait_comm_finished(input [16:0] dev_idx);
begin:WAIT_COMM_FINISHED_CODE
real st;
integer is_run;
st = $realtime;
is_run = 1;
while (is_run == 1) begin
txBuf[0] = 8'h00;
txBuf[1] = 8'h74;
if (dev_idx >=(`ALL_DEV_NUM * 3)) begin
txBuf[2] <= (`SPI_READ | 8'h0);
txBuf[3] <= 8'h04;
length = 8'h08;
//$display("using AQspi");
end else begin
txBuf[2] <= `SPI_READ;
length = 8'h07;
//$display("using iqspi");
end
idx = dev_idx;
#5
@(negedge sck)
isReq <= 1;
@(posedge sck) #5
isReq <= 0;
@( negedge isBusy) #1000
begin
end
#2000
//$display("%x %x", rxBuf[3], rxBuf[6]);
if ((rxBuf[`ARRAY_IDX_OFF] & 8'h02) == 8'h02)
begin
is_run = 0;
end
if ((rxBuf[`ARRAY_IDX_OFF+3] & 8'h60) != 8'h00)
begin
$display("error occur");
is_run = 0;
end
if (($realtime - st) >= 20000000.0)
begin
$display("comm timeout.");
is_run = 0;
end
end
end
endtask
initial begin
#1000
`include "tc_runlist.vh"
#1000000
$display("Testcase Finished! Time Out !!!");
$fclose(spidata_file);
//$stop;
$finish;
end
endmodule