///////////////////////////////////////////////////////////////////////
// >>>>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<
// ====================================================================
// Copyright 2002 (c) Lattice Semiconductor Corporation
// ALL RIGHTS RESERVED
//
// This confidential and proprietary software may be used only as
// authorised by a licensing agreement from Lattice Semiconductor
// Corporation.
// The entire notice above must be reproduced on all authorized
// copies and copies may only be made to the extent permitted
// by a licensing agreement from Lattice Semiconductor Corporation.
//

// ====================================================================
// File Details
// ====================================================================
// Project              :       ORSPII
// Filename             :       latspi4_df.v
// Author               :       Ben_Kerr,bkerr@latticesemi.com
// Created on           :       Thursday June 27 2002 (WW25)
// Last Modified By     :       $Author: rproudlo $
// Last Modified On     :       $Date: Wed Oct 30 03:29:41 2002 $
// Revision             :       $Revision: 1.24 $
// Status               :       Development
// Dependencies         :       latspi4_tx.v, latspi4_inc.v
//=====================================================================

//=====================================================================
// Description          :
//=====================================================================
// This module utilises the tasks in latspi4_tx.v to generate test
// patterns on the transmit SPI4 interface. Details of the tests can
// be found in ORSPII Top Level Verification Specification.doc
//
//=====================================================================

//=====================================================================
// Revision History
//=====================================================================
// $Log: latspi4_df.v.rca $
// 
//  Revision: 1.24 Wed Oct 30 03:29:41 2002 rproudlo
//  Modified Scratchpad task "dip4"
// 
//  Revision: 1.23 Fri Oct 18 11:43:53 2002 rproudlo
//  Added Idle between df00,df01 and df02
// 
//  Revision: 1.22 Fri Oct 18 06:53:53 2002 rproudlo
//  Modified dip4 task
// 
//  Revision: 1.21 Fri Oct 18 06:49:33 2002 rproudlo
//  Removed redundant df's and added dip4 task
// 
//  Revision: 1.20 Wed Oct 16 06:20:35 2002 rproudlo
//  Modified df01_df22 to comment out training gen
// 
//  Revision: 1.19 Wed Oct 16 06:00:25 2002 rproudlo
//  Added DIP-4 checking (df15)
// 
//  Revision: 1.18 Mon Oct 14 12:22:43 2002 rproudlo
//  Added DIP-4 error checking (df15)
// 
//  Revision: 1.17 Fri Oct 11 11:47:38 2002 rproudlo
//  Modified random test df03
// 
//  Revision: 1.16 Wed Oct  2 06:32:45 2002 rproudlo
//  Commented out df22
// 
//  Revision: 1.15 Tue Oct  1 05:02:50 2002 rproudlo
//  Minor modifications
// 
//  Revision: 1.14 Fri Sep 27 06:03:50 2002 rproudlo
//  Tempory checkin
// 
//  Revision: 1.13 Thu Sep 26 06:33:12 2002 rproudlo
//  Updating df' tasks to increase testing
// 
//  Revision: 1.12 Wed Sep 25 10:48:49 2002 rproudlo
//  Modified df00 task
// 
//  Revision: 1.11 Tue Sep 24 11:58:06 2002 rproudlo
//  Added random test to df00
// 
//  Revision: 1.10 Thu Sep 19 09:12:23 2002 rproudlo
//  Test dubug
// 
//  Revision: 1.9 Tue Sep 17 12:33:44 2002 rproudlo
//  Modified df00 scratch-task
// 
//  Revision: 1.8 Fri Sep 13 05:16:57 2002 rproudlo
//  Added df00 task for scratchpad verification
// 
//  Revision: 1.7 Mon Jul 29 11:33:39 2002 bkerr
//  Changed all calls to tx.burst to include dip4_invld parameter
//  Updated DF15 to insert a DIP-4 error on a continuation word
// 
//  Revision: 1.6 Tue Jul 16 12:41:15 2002 bkerr
//  Deleted ports_in_test array and referenced RX_PDM_ACTIVE_PORT_ID
//  to get port numbers to use in test
// 
//  Revision: 1.5 Wed Jul 10 12:16:45 2002 bkerr
//  Added df22 Random burst length data format test
//  Removed all local calendar variables and referenced DUT
//  configuration for calendar configuration
// 
//  Revision: 1.4 Mon Jul  8 12:05:57 2002 bkerr
//  Fixed bug introduced by minimum SOP time enforcement
//  IDLE cycles were being inserted after every short burst, which was
//    breaking the back-to-back EOP test
// 
//  Revision: 1.3 Fri Jul  5 09:44:30 2002 bkerr
//  Altered DF04-DF07 to change ports between bursts as
//  specified in ORSPII Top Level Verification specification
// 
//  Revision: 1.2 Thu Jul  4 12:15:19 2002 bkerr
//  Added minimum SOP->SOP gap time enforcement
// 
//  Revision: 1.1 Tue Jul  2 03:53:55 2002 bkerr
//  Initial creation
//=====================================================================

`timescale 1ps/1ps

module latspi4_df;

// ---------------------------------------------------------------------------
// includes
// ---------------------------------------------------------------------------
`include "latspi4_inc.v"

// ---------------------------------------------------------------------------
// df01_df22 task
// ---------------------------------------------------------------------------
// Description
// -----------
// This task performs Data Format tests DF01-DF22
//
// DF01 - Incremental length single bursts. 1->burst_size bytes
// DF02 - Incremental length multiple bursts
// DF03 - Back-to-back EOPs
// DF04 - Even-Even burst
// DF05 - Even-Odd burst
// DF06 - Odd-Even burst
// DF07 - Odd-Odd burst
// DF08 - Missing EOP
// DF09 - Missing SOP
// DF10 - Zero length burst
// DF11 - Incorrect number of training control words
// DF12 - Incorrect number of training data words
// DF13 - SOP-SOP time violation: Same port
// DF14 - SOP-SOP time violation: Different ports
// DF15 - DIP-4 error detection
// DF16 - ERR indication. Odd length burst
// DF17 - ERR indication: Even length burst
// DF18 - Invalid burst length
// DF19 - IDLE control word filtering
// DF20 - Training pattern filtering
// DF21 - Extended control word filtering
// DF22 - Random length bursts on random ports 
//
// Parameters
// ----------
// burst size     number of bytes in a payload burst
//                Must be a multiple of 16
// ---------------------------------------------------------------------------
//

task df00;
input   [31:0] burst_size;
input          first;
integer        cur_port;
integer        i,j,k,l;

reg [15:0] Pkt_Length;

begin

// Start-up
  if (toptest.EN_TRAINING == 1'b1 && first == 1'b1)  
    begin
      tx.training(10,10,5);
      tx.idle(2000);
    end
  else
    begin 
      tx.idle(100);
    end
    
$display("%t: DF00: Incremental length single bursts - Interleaved ports: 1->%0d bytes",$time,burst_size);
 
 for(i=1;i<=burst_size;i=i+1)
   begin
     for(cur_port=0;cur_port<toptest.RX_PDM_ACTIVE_PORTS;cur_port=cur_port+1)
       begin
//         $display("%t:\tPort:%0d",$time,toptest.RX_PDM_ACTIVE_PORT_ID[cur_port]);
         if(i % 2)
           tx.burst(toptest.RX_PDM_ACTIVE_PORT_ID[cur_port],i,`LATSPI4_SOP,`LATSPI4_EOPS_1VAL,1'b0,0);
         else
           tx.burst(toptest.RX_PDM_ACTIVE_PORT_ID[cur_port],i,`LATSPI4_SOP,`LATSPI4_EOPS_2VAL,1'b0,0);
       end
   end

	 tx.idle((({$random} % 16) + 1));

$display("%t: DF01: Incremental length interleaved bursts/ports: %0d->%0d bytes",$time,burst_size,burst_size*2);

for(i=burst_size;i<=(burst_size*2);i=i+1)
  begin
    j = i / burst_size; // Number of full bursts
    k = i % burst_size; // Number of bytes to send in last burst

// send j full bursts
    for(l=0;l<j;l=l+1)
      begin 
        for(cur_port=0;cur_port<toptest.RX_PDM_ACTIVE_PORTS;cur_port=cur_port+1)
        begin
//          $display("%t:\tPort:%0d",$time,toptest.RX_PDM_ACTIVE_PORT_ID[cur_port]);
	   
            tx.burst(
               toptest.RX_PDM_ACTIVE_PORT_ID[cur_port],
               burst_size,
               (l==0 ? `LATSPI4_SOP  : `LATSPI4_NSOP),                              // SOP in first burst
               (((k==0) && (l==(j-1))) ? `LATSPI4_EOPS_2VAL : `LATSPI4_EOPS_CONT),  // EOPS in last burst for n*burst_size
               1'b0,
               0                                                                    // No extended control words
               );
         end
      end

//	 tx.idle((({$random} % 16) + 1));

    for(cur_port=0;cur_port<toptest.RX_PDM_ACTIVE_PORTS;cur_port=cur_port+1)
      begin
//          $display("%t:\tPort:%0d",$time,toptest.RX_PDM_ACTIVE_PORT_ID[cur_port]);
      	 
      // last burst to send remaining bytes
         if(k != 0)
         begin
            if(k % 2)
               tx.burst(toptest.RX_PDM_ACTIVE_PORT_ID[cur_port],k,`LATSPI4_NSOP,`LATSPI4_EOPS_1VAL,1'b0,0);   // Odd
            else
               tx.burst(toptest.RX_PDM_ACTIVE_PORT_ID[cur_port],k,`LATSPI4_NSOP,`LATSPI4_EOPS_2VAL,1'b0,0);   // Even
         end
      end
      
   end

	 tx.idle((({$random} % 16) + 1));

$display("%t: DF02: Random length interleaved bursts/ports",$time);

repeat (100)
  begin
    
    Pkt_Length = (({$random} % 511) + 1);
    j = Pkt_Length / burst_size; // Number of full bursts
    k = Pkt_Length % burst_size; // Number of bytes to send in last burst

//    $display("%t:\tPort:%0d Packet Length = %d",$time,toptest.RX_PDM_ACTIVE_PORT_ID[cur_port],Pkt_Length);

// send j full bursts
    for(l=0;l<j;l=l+1)
      begin 
        for(cur_port=0;cur_port<toptest.RX_PDM_ACTIVE_PORTS;cur_port=cur_port+1)
        begin
//          $display("%t:\tPort:%0d",$time,toptest.RX_PDM_ACTIVE_PORT_ID[cur_port]);
	   
            tx.burst(
               toptest.RX_PDM_ACTIVE_PORT_ID[cur_port],
               burst_size,
               (l==0 ? `LATSPI4_SOP  : `LATSPI4_NSOP),                              // SOP in first burst
               (((k==0) && (l==(j-1))) ? `LATSPI4_EOPS_2VAL : `LATSPI4_EOPS_CONT),  // EOPS in last burst for n*burst_size
               1'b0,
               0                                                                    // No extended control words
               );
         end
      end

    for(cur_port=0;cur_port<toptest.RX_PDM_ACTIVE_PORTS;cur_port=cur_port+1)
      begin
      	 
      // last burst to send remaining bytes
       if (j == 0)
         begin
           if(k != 0)
           begin
//	    $display("%t:\tPort:%0d",$time,toptest.RX_PDM_ACTIVE_PORT_ID[cur_port]);
            if(k % 2)
               tx.burst(toptest.RX_PDM_ACTIVE_PORT_ID[cur_port],k,`LATSPI4_SOP,`LATSPI4_EOPS_1VAL,1'b0,0);   // Odd
            else
               tx.burst(toptest.RX_PDM_ACTIVE_PORT_ID[cur_port],k,`LATSPI4_SOP,`LATSPI4_EOPS_2VAL,1'b0,0);   // Even    
           end	 
	 end       
       else
         begin
           if(k != 0)
           begin
//	    $display("%t:\tPort:%0d",$time,toptest.RX_PDM_ACTIVE_PORT_ID[cur_port]);	
            if(k % 2)
               tx.burst(toptest.RX_PDM_ACTIVE_PORT_ID[cur_port],k,`LATSPI4_NSOP,`LATSPI4_EOPS_1VAL,1'b0,0);   // Odd
            else
               tx.burst(toptest.RX_PDM_ACTIVE_PORT_ID[cur_port],k,`LATSPI4_NSOP,`LATSPI4_EOPS_2VAL,1'b0,0);   // Even
           end
	 end  
      end
      
   end
   
	 tx.idle((({$random} % 16) + 1));

end
endtask

task df01_df22;
input   [31:0] burst_size;
input          first;
integer        cur_port;
integer        i,j,k,l;
begin

// Start-up
  if (toptest.EN_TRAINING == 1'b1 && first == 1'b1)  
    begin
      tx.training(10,10,5);
      tx.idle(2000);
    end
  else
    begin 
      tx.idle(100);
    end
   
// DF03 - Back-to-back EOPs
   $display("%t: DF03: Back-to-back EOPs",$time);

   for(cur_port=0;cur_port<toptest.RX_PDM_ACTIVE_PORTS;cur_port=cur_port+1)
   begin
//      $display("%t:\tPort:%0d",$time,toptest.RX_PDM_ACTIVE_PORT_ID[cur_port]);
      tx.burst(toptest.RX_PDM_ACTIVE_PORT_ID[cur_port],burst_size,`LATSPI4_SOP,`LATSPI4_EOPS_CONT,1'b0,0);
   end
   for(cur_port=0;cur_port<toptest.RX_PDM_ACTIVE_PORTS;cur_port=cur_port+1)
   begin
//      $display("%t:\tPort:%0d",$time,toptest.RX_PDM_ACTIVE_PORT_ID[cur_port]);
      tx.burst(toptest.RX_PDM_ACTIVE_PORT_ID[cur_port], 1,`LATSPI4_NSOP,`LATSPI4_EOPS_1VAL,1'b0,0);
   end

	 tx.idle((({$random} % 16) + 1));

// DF04 - Even-even burst
   $display("%t: DF04: Even-even burst",$time);

   if(toptest.RX_PDM_ACTIVE_PORTS != 1)
   begin
      for(cur_port=0;cur_port<(toptest.RX_PDM_ACTIVE_PORTS-1);cur_port=cur_port+1)
      begin
//         $display("%t:\tPorts:%0d,%0d",$time,toptest.RX_PDM_ACTIVE_PORT_ID[cur_port],toptest.RX_PDM_ACTIVE_PORT_ID[cur_port+1]);
         tx.burst(toptest.RX_PDM_ACTIVE_PORT_ID[cur_port],   burst_size    ,`LATSPI4_SOP,`LATSPI4_EOPS_2VAL,1'b0,0);
         tx.burst(toptest.RX_PDM_ACTIVE_PORT_ID[cur_port+1],(burst_size-4) ,`LATSPI4_SOP,`LATSPI4_EOPS_2VAL,1'b0,0);
      end
//       $display("%t:\tPorts:%0d,%0d",$time,toptest.RX_PDM_ACTIVE_PORT_ID[toptest.RX_PDM_ACTIVE_PORTS-1],toptest.RX_PDM_ACTIVE_PORT_ID[0]);
       tx.burst(toptest.RX_PDM_ACTIVE_PORT_ID[toptest.RX_PDM_ACTIVE_PORTS-1],   burst_size    ,`LATSPI4_SOP,`LATSPI4_EOPS_2VAL,1'b0,0);
       tx.burst(toptest.RX_PDM_ACTIVE_PORT_ID[0],(burst_size-4) ,`LATSPI4_SOP,`LATSPI4_EOPS_2VAL,1'b0,0);
   end
   else
   begin
//      $display("%t:\tPort:%0d",$time,toptest.RX_PDM_ACTIVE_PORT_ID[0]);
      tx.burst(toptest.RX_PDM_ACTIVE_PORT_ID[0], burst_size    ,`LATSPI4_SOP,`LATSPI4_EOPS_2VAL,1'b0,0);
      tx.burst(toptest.RX_PDM_ACTIVE_PORT_ID[0],(burst_size-4) ,`LATSPI4_SOP,`LATSPI4_EOPS_2VAL,1'b0,0);
   end

	 tx.idle((({$random} % 16) + 1));

         
// DF05 - Even-odd burst
   $display("%t: DF05: Even-odd burst",$time);

   if(toptest.RX_PDM_ACTIVE_PORTS != 1)
   begin
      for(cur_port=0;cur_port<(toptest.RX_PDM_ACTIVE_PORTS-1);cur_port=cur_port+1)
      begin
//         $display("%t:\tPorts:%0d,%0d",$time,toptest.RX_PDM_ACTIVE_PORT_ID[cur_port],toptest.RX_PDM_ACTIVE_PORT_ID[cur_port+1]);
         tx.burst(toptest.RX_PDM_ACTIVE_PORT_ID[cur_port],   burst_size   ,`LATSPI4_SOP,`LATSPI4_EOPS_2VAL,1'b0,0);
         tx.burst(toptest.RX_PDM_ACTIVE_PORT_ID[cur_port+1],(burst_size-3),`LATSPI4_SOP,`LATSPI4_EOPS_1VAL,1'b0,0);
      end
//         $display("%t:\tPorts:%0d,%0d",$time,toptest.RX_PDM_ACTIVE_PORT_ID[toptest.RX_PDM_ACTIVE_PORTS-1],toptest.RX_PDM_ACTIVE_PORT_ID[0]);
         tx.burst(toptest.RX_PDM_ACTIVE_PORT_ID[toptest.RX_PDM_ACTIVE_PORTS-1],   burst_size   ,`LATSPI4_SOP,`LATSPI4_EOPS_2VAL,1'b0,0);
         tx.burst(toptest.RX_PDM_ACTIVE_PORT_ID[0],(burst_size-3),`LATSPI4_SOP,`LATSPI4_EOPS_1VAL,1'b0,0);      
   end
   else
   begin
//      $display("%t:\tPort:%0d",$time,toptest.RX_PDM_ACTIVE_PORT_ID[0]);
      tx.burst(toptest.RX_PDM_ACTIVE_PORT_ID[0], burst_size   ,`LATSPI4_SOP,`LATSPI4_EOPS_2VAL,1'b0,0);
      tx.burst(toptest.RX_PDM_ACTIVE_PORT_ID[0],(burst_size-3),`LATSPI4_SOP,`LATSPI4_EOPS_1VAL,1'b0,0);
   end

	 tx.idle((({$random} % 16) + 1));

// DF06 - Odd-even burst
   $display("%t: DF06: Odd-even burst",$time);

   if(toptest.RX_PDM_ACTIVE_PORTS != 1)
   begin
      for(cur_port=0;cur_port<(toptest.RX_PDM_ACTIVE_PORTS-1);cur_port=cur_port+1)
      begin
//         $display("%t:\tPorts:%0d,%0d",$time,toptest.RX_PDM_ACTIVE_PORT_ID[cur_port],toptest.RX_PDM_ACTIVE_PORT_ID[cur_port+1]);
         tx.burst(toptest.RX_PDM_ACTIVE_PORT_ID[cur_port],  (burst_size-3),`LATSPI4_SOP,`LATSPI4_EOPS_1VAL,1'b0,0);
         tx.burst(toptest.RX_PDM_ACTIVE_PORT_ID[cur_port+1], burst_size   ,`LATSPI4_SOP,`LATSPI4_EOPS_2VAL,1'b0,0);
      end
//         $display("%t:\tPorts:%0d,%0d",$time,toptest.RX_PDM_ACTIVE_PORT_ID[toptest.RX_PDM_ACTIVE_PORTS-1],toptest.RX_PDM_ACTIVE_PORT_ID[0]);
         tx.burst(toptest.RX_PDM_ACTIVE_PORT_ID[toptest.RX_PDM_ACTIVE_PORTS-1],  (burst_size-3),`LATSPI4_SOP,`LATSPI4_EOPS_1VAL,1'b0,0);
         tx.burst(toptest.RX_PDM_ACTIVE_PORT_ID[0], burst_size   ,`LATSPI4_SOP,`LATSPI4_EOPS_2VAL,1'b0,0);
   end
   else
   begin
//      $display("%t:\tPort:%0d",$time,toptest.RX_PDM_ACTIVE_PORT_ID[0]);
      tx.burst(toptest.RX_PDM_ACTIVE_PORT_ID[0],(burst_size-3),`LATSPI4_SOP,`LATSPI4_EOPS_1VAL,1'b0,0);
      tx.burst(toptest.RX_PDM_ACTIVE_PORT_ID[0], burst_size   ,`LATSPI4_SOP,`LATSPI4_EOPS_2VAL,1'b0,0);
   end

	 tx.idle((({$random} % 16) + 1));
   
// DF07 - Odd-odd burst
   $display("%t: DF07: Odd-odd burst",$time);

   if(toptest.RX_PDM_ACTIVE_PORTS != 1)
   begin
      for(cur_port=0;cur_port<(toptest.RX_PDM_ACTIVE_PORTS-1);cur_port=cur_port+1)
      begin
//         $display("%t:\tPorts:%0d,%0d",$time,toptest.RX_PDM_ACTIVE_PORT_ID[cur_port],toptest.RX_PDM_ACTIVE_PORT_ID[cur_port+1]);
         tx.burst(toptest.RX_PDM_ACTIVE_PORT_ID[cur_port],  (burst_size-3),`LATSPI4_SOP,`LATSPI4_EOPS_1VAL,1'b0,0);
         tx.burst(toptest.RX_PDM_ACTIVE_PORT_ID[cur_port+1],(burst_size-5),`LATSPI4_SOP,`LATSPI4_EOPS_1VAL,1'b0,0);
      end
//         $display("%t:\tPorts:%0d,%0d",$time,toptest.RX_PDM_ACTIVE_PORT_ID[toptest.RX_PDM_ACTIVE_PORTS-1],toptest.RX_PDM_ACTIVE_PORT_ID[0]);
         tx.burst(toptest.RX_PDM_ACTIVE_PORT_ID[toptest.RX_PDM_ACTIVE_PORTS-1],  (burst_size-3),`LATSPI4_SOP,`LATSPI4_EOPS_1VAL,1'b0,0);
         tx.burst(toptest.RX_PDM_ACTIVE_PORT_ID[0],(burst_size-5),`LATSPI4_SOP,`LATSPI4_EOPS_1VAL,1'b0,0);
   end
   else
   begin
//      $display("%t:\tPort:%0d",$time,toptest.RX_PDM_ACTIVE_PORT_ID[0]);
      tx.burst(toptest.RX_PDM_ACTIVE_PORT_ID[0],(burst_size-3),`LATSPI4_SOP,`LATSPI4_EOPS_1VAL,1'b0,0);
      tx.burst(toptest.RX_PDM_ACTIVE_PORT_ID[0],(burst_size-5),`LATSPI4_SOP,`LATSPI4_EOPS_1VAL,1'b0,0);
   end      

	 tx.idle((({$random} % 16) + 1));
 	 
// DF15 - DIP-4 error detection
   $display("%t: DF15: DIP-4 error detection",$time);

   for(cur_port=0;cur_port<toptest.RX_PDM_ACTIVE_PORTS;cur_port=cur_port+1)
   begin
//      $display("%t:\tPort:%0d",$time,toptest.RX_PDM_ACTIVE_PORT_ID[cur_port]);
      tx.burst(toptest.RX_PDM_ACTIVE_PORT_ID[cur_port],burst_size,`LATSPI4_SOP,`LATSPI4_EOPS_2VAL,1'b0,0);  // Good - SOP & EOP
      tx.burst(toptest.RX_PDM_ACTIVE_PORT_ID[cur_port],burst_size,`LATSPI4_SOP,`LATSPI4_EOPS_2VAL,1'b1,0);  // Bad  - SOP & EOP
      tx.burst(toptest.RX_PDM_ACTIVE_PORT_ID[cur_port],burst_size,`LATSPI4_SOP,`LATSPI4_EOPS_2VAL,1'b0,0);  // Good - SOP & EOP
	
      tx.burst(toptest.RX_PDM_ACTIVE_PORT_ID[cur_port],burst_size,`LATSPI4_SOP,`LATSPI4_EOPS_CONT,1'b0,0);  // Good - SOP only
      tx.burst(toptest.RX_PDM_ACTIVE_PORT_ID[cur_port],burst_size,`LATSPI4_NSOP,`LATSPI4_EOPS_CONT,1'b1,0); // Bad  - continuation
      tx.burst(toptest.RX_PDM_ACTIVE_PORT_ID[cur_port],burst_size,`LATSPI4_NSOP,`LATSPI4_EOPS_2VAL,1'b0,0); // Good - EOP only
      tx.burst(toptest.RX_PDM_ACTIVE_PORT_ID[cur_port],burst_size,`LATSPI4_SOP,`LATSPI4_EOPS_2VAL,1'b0,0);  // Good - SOP & EOP
   end

	 tx.idle((({$random} % 16) + 1));
   
// DF16 - ERR indication. Even length burst
   $display("%t: DF16: ERR indication: Even length burst",$time);

   for(cur_port=0;cur_port<toptest.RX_PDM_ACTIVE_PORTS;cur_port=cur_port+1)
   begin
//      $display("%t:\tPort:%0d",$time,toptest.RX_PDM_ACTIVE_PORT_ID[cur_port]);
      tx.burst(toptest.RX_PDM_ACTIVE_PORT_ID[cur_port], burst_size,   `LATSPI4_SOP,`LATSPI4_EOPS_2VAL,1'b0,0);
      tx.burst(toptest.RX_PDM_ACTIVE_PORT_ID[cur_port],(burst_size-4),`LATSPI4_SOP,`LATSPI4_EOPS_ABRT,1'b0,0);
      tx.burst(toptest.RX_PDM_ACTIVE_PORT_ID[cur_port], burst_size,   `LATSPI4_SOP,`LATSPI4_EOPS_2VAL,1'b0,0);
   end

	 tx.idle((({$random} % 16) + 1));

// DF17 - ERR indication. Odd length burst
   $display("%t: DF17: ERR indication: Odd length burst",$time);

   for(cur_port=0;cur_port<toptest.RX_PDM_ACTIVE_PORTS;cur_port=cur_port+1)
   begin
//      $display("%t:\tPort:%0d",$time,toptest.RX_PDM_ACTIVE_PORT_ID[cur_port]);
      tx.burst(toptest.RX_PDM_ACTIVE_PORT_ID[cur_port], burst_size,   `LATSPI4_SOP,`LATSPI4_EOPS_2VAL,1'b0,0);
      tx.burst(toptest.RX_PDM_ACTIVE_PORT_ID[cur_port],(burst_size-3),`LATSPI4_SOP,`LATSPI4_EOPS_ABRT,1'b0,0);
//      tx.burst(toptest.RX_PDM_ACTIVE_PORT_ID[cur_port],(burst_size-3),`LATSPI4_SOP,`LATSPI4_EOPS_1VAL,1'b0,0);
      tx.burst(toptest.RX_PDM_ACTIVE_PORT_ID[cur_port], burst_size,   `LATSPI4_SOP,`LATSPI4_EOPS_2VAL,1'b0,0);
   end
   
	 tx.idle((({$random} % 16) + 1));


// DF20 - Training pattern filtering
   $display("%t: DF20: Training pattern filtering",$time);

 for(i=1;i<=burst_size;i=i+1)
   begin
     for(cur_port=0;cur_port<toptest.RX_PDM_ACTIVE_PORTS;cur_port=cur_port+1)
       begin
//         $display("%t:\tPort:%0d",$time,toptest.RX_PDM_ACTIVE_PORT_ID[cur_port]);
         if(i % 2)
           tx.burst(toptest.RX_PDM_ACTIVE_PORT_ID[cur_port],i,`LATSPI4_SOP,`LATSPI4_EOPS_1VAL,1'b0,0);
         else
           tx.burst(toptest.RX_PDM_ACTIVE_PORT_ID[cur_port],i,`LATSPI4_SOP,`LATSPI4_EOPS_2VAL,1'b0,0);
	   
       end
       
       	 tx.idle(1);
         tx.training(10,10,(({$random} % 7) + 1));

   end

	 tx.idle((({$random} % 16) + 1));

/*	 
// DF21 - Extended control word filtering
   $display("%t: DF21: Extended control word filtering",$time);

   for(cur_port=0;cur_port<toptest.RX_PDM_ACTIVE_PORTS;cur_port=cur_port+1)
   begin
//      $display("%t:\tPort:%0d",$time,toptest.RX_PDM_ACTIVE_PORT_ID[cur_port]);
      tx.burst(toptest.RX_PDM_ACTIVE_PORT_ID[cur_port],burst_size + 2,`LATSPI4_SOP,`LATSPI4_EOPS_2VAL,1'b0,0);
      tx.burst(toptest.RX_PDM_ACTIVE_PORT_ID[cur_port],burst_size + 2,`LATSPI4_SOP,`LATSPI4_EOPS_2VAL,1'b0,1);
      tx.burst(toptest.RX_PDM_ACTIVE_PORT_ID[cur_port],burst_size + 3,`LATSPI4_SOP,`LATSPI4_EOPS_1VAL,1'b0,0);
      tx.burst(toptest.RX_PDM_ACTIVE_PORT_ID[cur_port],burst_size + 3,`LATSPI4_SOP,`LATSPI4_EOPS_1VAL,1'b0,2);
      tx.burst(toptest.RX_PDM_ACTIVE_PORT_ID[cur_port],burst_size + 4,`LATSPI4_SOP,`LATSPI4_EOPS_2VAL,1'b0,0);
      tx.burst(toptest.RX_PDM_ACTIVE_PORT_ID[cur_port],burst_size + 4,`LATSPI4_SOP,`LATSPI4_EOPS_2VAL,1'b0,3);
   end

	 tx.idle((({$random} % 16) + 1));
   
/*
// DF22 - Random length bursts on random ports
   $display("%t: DF22: Random length bursts on random ports",$time);
   
   for(i=0;i<(burst_size * toptest.RX_PDM_ACTIVE_PORTS);i=i+1)
   begin
      j        = ({$random} % toptest.MAX_BURST1_RX * 16) + 1;    // Length = 1 to burst_size bytes
      k        =  {$random} % toptest.RX_PDM_ACTIVE_PORTS;
      cur_port = toptest.RX_PDM_ACTIVE_PORT_ID[k];
      if(j % 2)      
         tx.burst(cur_port,j,`LATSPI4_SOP,`LATSPI4_EOPS_1VAL,1'b0,0);
      else
         tx.burst(cur_port,j,`LATSPI4_SOP,`LATSPI4_EOPS_2VAL,1'b0,0);
	 
      tx.idle({$random} % (burst_size*2));
 
   end 
*/
  
   tx.idle(2);
   
end
endtask

task df_dip4; 
  input   [31:0] burst_size;
  input          first;
  integer        cur_port;
  integer        i,j,k,l;
    begin
    
  if (toptest.EN_TRAINING == 1'b1 && first == 1'b1)  
    begin
      tx.idle(200);
      tx.training(10,10,5);
      tx.idle(2000);
    end
  else
    begin 
      tx.idle(100);
    end

   for(cur_port=0;cur_port<toptest.RX_PDM_ACTIVE_PORTS;cur_port=cur_port+1)
   begin
//      $display("%t:\tPort:%0d",$time,toptest.RX_PDM_ACTIVE_PORT_ID[cur_port]);
//      tx.burst(toptest.RX_PDM_ACTIVE_PORT_ID[cur_port],burst_size + 2,`LATSPI4_SOP,`LATSPI4_EOPS_2VAL,1'b0,0);
//      tx.burst(toptest.RX_PDM_ACTIVE_PORT_ID[cur_port],burst_size + 2,`LATSPI4_SOP,`LATSPI4_EOPS_2VAL,1'b0,1);
//      tx.burst(toptest.RX_PDM_ACTIVE_PORT_ID[cur_port],burst_size + 3,`LATSPI4_SOP,`LATSPI4_EOPS_1VAL,1'b0,0);
//      tx.burst(toptest.RX_PDM_ACTIVE_PORT_ID[cur_port],burst_size + 3,`LATSPI4_SOP,`LATSPI4_EOPS_1VAL,1'b0,2);
//      tx.burst(toptest.RX_PDM_ACTIVE_PORT_ID[cur_port],burst_size + 4,`LATSPI4_SOP,`LATSPI4_EOPS_2VAL,1'b0,0);
//      tx.burst(toptest.RX_PDM_ACTIVE_PORT_ID[cur_port],burst_size + 4,`LATSPI4_SOP,`LATSPI4_EOPS_2VAL,1'b0,3);
   end

	 tx.idle((({$random} % 16) + 1));

   cur_port=0;
   
   repeat(toptest.LOSS_SYNC+10)
   begin
      $display("%t:\tPort:%0d",$time,toptest.RX_PDM_ACTIVE_PORT_ID[cur_port]);
      tx.burst(toptest.RX_PDM_ACTIVE_PORT_ID[cur_port],burst_size + 4,`LATSPI4_SOP,`LATSPI4_EOPS_2VAL,1'b1,0);  // Bad  - SOP & EOP
   end
   
//      tx.idle(1);
//      #1000;
//      tx.training(10,10,5);
//      tx.idle(1);

   repeat(toptest.LOSS_SYNC)
   begin
      $display("%t:\tPort:%0d",$time,toptest.RX_PDM_ACTIVE_PORT_ID[cur_port]);
      tx.burst(toptest.RX_PDM_ACTIVE_PORT_ID[cur_port],burst_size + 8,`LATSPI4_SOP,`LATSPI4_EOPS_2VAL,1'b0,0);  // Bad  - SOP & EOP
   end

      tx.burst(toptest.RX_PDM_ACTIVE_PORT_ID[cur_port],burst_size + 2,`LATSPI4_SOP,`LATSPI4_EOPS_2VAL,1'b0,0);  // Bad  - SOP & EOP

	 tx.idle((({$random} % 16) + 1));
	
    end
    
endtask

`ifdef SHOW_IDENTITY
initial
begin
   $display("%M $Id: latspi4_df.v.rca 1.24 Wed Oct 30 03:29:41 2002 rproudlo Experimental $");
end   
`endif

endmodule
