class spi_monitor; virtual sysreg_if vif; virtual spi_if wif; virtual sram_if xif; //collect MOSI(din) & MISO(dout) bit din[$]; bit[31:0] dout[$]; int pktnum; int pkt_i; function new(); endfunction extern task write_monitor(); extern task read_monitor(); extern task do_mon(); endclass : spi_monitor task spi_monitor::do_mon(); fork while(1) begin if(pkt_i==pktnum) break; write_monitor(); end while(1) begin if(pkt_i==pktnum) break; read_monitor(); end repeat(pktnum) begin: kill_progress @(negedge wif.csn); pkt_i++; end join endtask: do_mon //monitor1: write_monitor(mosi) task spi_monitor::write_monitor(); bit write_temp[$]; @(negedge wif.csn); while(1) begin //Sample miso data @(posedge sclk) as DUT does. @(posedge wif.sclk or posedge wif.csn); if(wif.error_check | wif.csn) break; write_temp.push_back(wif.mosi); end //Keep the write-cycle data until anothor one occurs if(write_temp[0]==1'b0) din = write_temp; din[0] = write_temp[0]; write_temp.delete(); endtask: write_monitor //monitor2: read_monitor(miso) task spi_monitor::read_monitor(); bit[31:0] read_temp; int size; int i=0; @(negedge wif.csn); for(i=0;i<32;i++) begin @(posedge wif.sclk or posedge wif.csn) if(wif.error_check | wif.csn) break; read_temp[i] = wif.mosi; end size = read_temp[0] ? (read_temp[1] ? 16 : 1) : 0; read_temp = 32'b0; dout.delete(); repeat(size) begin //One 32bit-word is sampled everytime a for-circulation runs for(i=0;i<32;i++) begin //Sample miso data @(negedge sclk) for stability. @(negedge wif.sclk or posedge wif.csn); if(wif.csn) break; read_temp[31-i] = wif.miso; end if(!wif.csn) begin dout.push_back(read_temp); $display("miso:\t\t%b\t\t **",read_temp); end end if(!wif.csn) @(posedge wif.csn); endtask: read_monitor