// *** THIS FILE IS AUTOMATICALLY GENERATED *** 
// *** DO NOT EDIT AS CHANGES WILL BE LOST! *** 
`define BUILDDATE " Tue 03/16/2004" 
`define BUILDWHO "user@latticesemi.com" 
`define SF " sf03" 
`define M " m03" 
///////////////////////////////////////////////////////////////////////
// >>>>>>>>>>>>>>>>>>>>>>>>> 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             :       header.v
// Author               :       Ben_Kerr,bkerr@latticesemi.com
// Created on           :       Tuesday July 09 2002 (WW27)
// Last Modified By     :       $Author: bkerr $
// Last Modified On     :       $Date: Fri Jan  3 04:17:44 2003 $
// Revision             :       $Revision: 1.46 $
// Status               :       Development
// Dependencies         :       reg_desc.v, addr_params.v
//=====================================================================

//=====================================================================
// Description          :
//=====================================================================
// Header file used at the top of the automatically created toptest.v
//
// After running the simany_ph1 script, toptest.v is created
// This file is built from the following files:
//
//   +-----------------------------------+
//   | `defines generated by script      |  Time of day, user information & configuration feedback
//   +-----------------------------------+
//   |                                   |  top level module statement, global variables
//   |        header.v (this file)       |  module instantiations, clock & reset generation
//   |                                   |  initial ....
//   +-----------------------------------+
//   |                                   |    DUT register settings (configuration specific)
//   |     SFnn - from command line      |
//   |                                   |
//   +-----------------------------------+
//   |                                   |    DUT memory configurations (configuration specific)
//   |     Mnn - from command line       |
//   |                                   |
//   +-----------------------------------+
//   |                                   |    Task calls to configure DUT
//   |             body.v                |    Task calls to enable checkers
//   |                                   |    Task calls to perform data format tests
//   +-----------------------------------+
//   |                                   |    Report pass/fail
//   |            footer.v               |    `include common tasks
//   |                                   |  endmodule
//   +-----------------------------------+
//
//
//=====================================================================

//=====================================================================
// Revision History
//=====================================================================
// $Log: header.v.rca $
// 
//  Revision: 1.46 Fri Jan  3 04:17:44 2003 bkerr
//  Removed forces on MACLOG AR nets due to new MACLOG models
//  Added ANNOTATE `define to run SDF back-annotation
// 
//  Revision: 1.45 Tue Dec 17 13:22:48 2002 bkerr
//  Altered 2nd reset to only reset SPI4 and not do a full hard-reset
// 
//  Revision: 1.44 Fri Dec 13 11:03:16 2002 bkerr
//  Added pulldowns onto Rx_RE and Rx_A to prevent X's
//  Forced a default RX_DPRAM aggregation mode (32-bit) to prevent X's
// 
//  Revision: 1.43 Thu Dec 12 11:48:36 2002 bkerr
//  Changed TRI_IO input to 1'b1
// 
//  Revision: 1.42 Thu Dec 12 06:26:19 2002 bkerr
//  Added double reset for gate-level simulation
//  Added RAM pre-load for gate-level simulation
// 
//  Revision: 1.41 Thu Nov 21 06:33:58 2002 bkerr
//  Added new SPI_DATM and SPI_DLYTAP inputs introduced in top8 release
// 
//  Revision: 1.40 Mon Nov 11 06:10:57 2002 bkerr
//  Changed heirarchical reference to MEM_TXPDMx_INIT_DONE to
//  maintain compatibility with gate-level netlist
// 
//  Revision: 1.39 Mon Oct 21 05:10:28 2002 bkerr
//  Reduced simulation lockup timebomb to 1 second
// 
//  Revision: 1.38 Thu Oct 17 07:56:50 2002 bkerr
//  Added BS_TRESET_OUT and BS_TRESET that were incorrectly removed
// 
//  Revision: 1.37 Thu Oct 17 04:18:05 2002 bkerr
//  Modified orspii_asb instantiation for top5 I/O changes
// 
//  Revision: 1.36 Tue Oct 15 11:44:01 2002 bkerr
//  Removed force's driving HSIX and used testio_mux to get the HSIX into
//  bypass mode
// 
//  Revision: 1.35 Fri Oct 11 09:50:53 2002 bkerr
//  Disabled testio_mux and used force's to get SPI4HSIX operating in
//  bypass mode
// 
//  Revision: 1.34 Thu Oct 10 04:38:28 2002 bkerr
//  Connected up additional I/O
// 
//  Revision: 1.33 Thu Sep 26 07:09:26 2002 rproudlo
//  Added missing reg declaration
// 
//  Revision: 1.32 Thu Sep 26 06:21:51 2002 rproudlo
//  Added very basic ISR
// 
//  Revision: 1.31 Tue Sep 24 03:38:24 2002 rproudlo
//  Added FIFO_Full flow-control to fpga_bfm_rx
// 
//  Revision: 1.30 Mon Sep 23 06:44:27 2002 bkerr
//  Checked out due to neptune downtime  Added multiplexed testio connections to allow HSIX forces to be
//  removed when the I/O buffers are added to orspii_asb top-level
// 
//  Revision: 1.29 Tue Sep 17 05:33:10 2002 bkerr
//  Added 5 second simulation lock-up abort
// 
//  Revision: 1.28 Mon Sep 16 09:50:52 2002 bkerr
//  Fixed connection to HWDATA to remove warnings with NCVerilog
// 
//  Revision: 1.27 Mon Sep 16 06:54:14 2002 rproudlo
//  fixed wiring mistake on RDAT[12]
// 
//  Revision: 1.26 Mon Sep 16 05:54:49 2002 rproudlo
//  Un-connected LVDS STAT lines
// 
//  Revision: 1.25 Mon Sep 16 05:38:05 2002 rproudlo
//  DebuggingInitial testing
// 
//  Revision: 1.24 Mon Sep 16 05:05:23 2002 bkerr
//  Added force statements to get the HSIX model operating in PLL
//  bypass mode
// 
//  Revision: 1.23 Mon Sep 16 04:59:10 2002 rproudlo
//  Wired-up a number of "inputs" in attempt to progress testing
// 
//  Revision: 1.22 Mon Sep 16 04:25:29 2002 rproudlo
//  Updated orspii_asb instantiation to match new version
// 
//  Revision: 1.21 Fri Sep 13 09:46:07 2002 bkerr
//  Added call to busmaster set_retry_limit
// 
//  Revision: 1.20 Fri Sep 13 05:38:58 2002 bkerr
//  Instantiated orspii_asb and removed s4_top instantiation
//
//  Revision: 1.19 Wed Sep 11 11:23:24 2002 rproudlo
//  Added loopback Rx->Tx
//
//  Revision: 1.18 Tue Sep 10 09:28:41 2002 bkerr
//  Added variables for use in SF17
//  Removed all rldclk references
//
//  Revision: 1.17 Mon Sep  9 10:06:53 2002 bkerr
//  Corrected memory write interface for programming Rx memories
//
//  Revision: 1.16 Mon Sep  9 09:03:49 2002 bkerr
//  Connected a_rsclk to LatSPI4 instead of using rldclk
//
//  Revision: 1.15 Mon Sep  9 08:57:17 2002 bkerr
//  Added force to connect rstat
//
//  Revision: 1.14 Mon Sep  9 07:31:54 2002 bkerr
//  Replaced tx_path and s4_rx_top instantiations with s4_top
//
//  Revision: 1.13 Mon Sep  9 05:13:09 2002 rproudlo
//  Modifications to wiring of s4_rx_top
//
//  Revision: 1.12 Fri Sep  6 10:00:51 2002 rproudlo
//  Removed redundant ports from s4_rx_top
//
//  Revision: 1.11 Fri Sep  6 08:48:15 2002 bkerr
//  Added tlctl and tldat outputs to tx_path port connections
//
//  Revision: 1.10 Fri Sep  6 05:05:51 2002 rproudlo
//  Added Rx Memory interface
//
//  Revision: 1.9 Fri Sep  6 04:48:44 2002 bkerr
//  Updated tx_path port connections to reflect changes
//  Removed references to tclk
//
//  Revision: 1.8 Fri Sep  6 04:02:15 2002 rproudlo
//  Added s4_rx_top and fpga_bfm_rx modules and wired-up
//
//  Revision: 1.7 Wed Sep  4 05:44:25 2002 bkerr
//  Updated tx_path instantiation to reflect port changes
//  Removed tclk as it is now internally generated
//
//  Revision: 1.6 Fri Aug 23 10:25:51 2002 bkerr
//  Fixed BIST & TX_Dn connections to prevent "Port size mismatch"
//  warnings from simulator
//
//  Revision: 1.5 Fri Aug 23 08:04:22 2002 bkerr
//  Removed orspii_asb instantiation and replaced with tx_path
//  Added clock and reset generation
//  Added wait for reset to complete and wait for DUT to complete
//  initialisation
//
//  Revision: 1.4 Tue Aug 20 12:03:12 2002 bkerr
//  Instantiate the orspii_asb top-level module and connect up the
//  SPI4 "A" connections to the LatSPI4 and fpga BFMs
//  Instantiate the AHB bmaster model to drive the AHB bus
//
//  Revision: 1.3 Tue Jul 30 12:11:31 2002 bkerr
//  Added integer i declaration for use in mnn files
//
//  Revision: 1.2 Thu Jul 11 08:38:47 2002 rproudlo
//  Added port maps for fpga_bfm_rx/tx
//
//  Revision: 1.1 Tue Jul  9 11:59:12 2002 bkerr
//  Initial creation
//=====================================================================

`timescale 1ns/1ps

module toptest;

`include "reg_desc.v"
`include "qspi3_define.v"

parameter ports = `PORTS;
parameter num_fifo  = `NUM_FIFO;

// ---------------------------------------------------------------------------
// Variables
// ---------------------------------------------------------------------------
integer     error_count;      // Number of errors recorded during test

// Configuration variables
integer     i;                // loop variable
reg [255:0] port_used;        // Flags to indicate if a port has been used
reg [  7:0] random_port;      // A randomly selected port number


// Clocks
wire        trefclk;          // Tx reference clock
reg         trefclk_2x;       // 2x trefclk (for SPI4HSIX)
reg   [2:0] trefclk_div;      // Counter to divide trefclk_2x by 8
reg         rfclk;
wire        rfclk_out;

// Reset
reg         dut_reset;        // main DUT reset (active high)
wire        dut_reset_n;      // main DUT reset (active low)
reg         spi4_reset;       // SPI4 reset (active high)
reg         reset_done;       // reset_done indication
reg         sys_resetn;       // FPGA reset
reg         sys_rst_n;        // FPSC ASB reset

reg         FPGA_LB;
reg         test_go;

event       preload_ram;      // trigger to preload RAM in gate-level sim


// Signals from ORSPI_ASB SPI-4 interface to LATSPI4 driver/monitor
wire        a_tdclk;
wire [15:0] a_tdat;
wire        a_tctl;
wire        a_tsclk;
wire [ 1:0] a_tstat;

wire        a_rdclk;
wire [15:0] a_rdat;
wire        a_rctl;
wire        a_rsclk;
wire [ 1:0] a_rstat;


// module processor interface (MPI)
// wire [1:0]  mpi_tsz;
// wire mpi_rw;
// wire mpi_burstn;
// wire mpi_bdipn;
// wire mpi_strbn;
// wire mpi_cs0n;
// wire mpi_cs1;
// wire [17:0] mpi_a;
// tri  [31:0] mpi_d;
// tri  [0:7] mpi_d_temp;
// tri  [3:0] mpi_dp;
// wire mpi_ackn;
// wire mpi_tean;
// wire mpi_irqn;
// wire mpi_retryn;

// reg mpi_clk;

// Signals to orspi_qspi3 device under test

// SPI-3 Interface 0

wire		renb0;
wire		rsx0;
wire		rsop0;
wire		reop0;
wire		rprty0;
wire		rval0;
wire		rerr0;
wire [1:0]	rmod0;
wire [31:0]	rdat0;

wire		tenb0;
wire		tsx0;
wire		tsop0;
wire		teop0;
wire		tprty0;
wire		terr0;
wire [1:0]	tmod0;
wire [31:0]	tdat0;
wire [5:0]	tadr0;
wire [ports-1:0]	dtpa0;

`ifdef NUMINT2

// SPI-3 Interface 1

wire		renb1;
wire		rsx1;
wire		rsop1;
wire		reop1;
wire		rprty1;
wire		rval1;
wire		rerr1;
wire [1:0]	rmod1;
wire [31:0]	rdat1;

wire		tenb1;
wire		tsx1;
wire		tsop1;
wire		teop1;
wire		tprty1;
wire		terr1;
wire [1:0]	tmod1;
wire [31:0]	tdat1;
wire [5:0]	tadr1;
wire [ports-1:0]	dtpa1;

`endif

`ifdef NUMINT3

// SPI-3 Interface 2

wire		renb2;
wire		rsx2;
wire		rsop2;
wire		reop2;
wire		rprty2;
wire		rval2;
wire		rerr2;
wire [1:0]	rmod2;
wire [31:0]	rdat2;

wire		tenb2;
wire		tsx2;
wire		tsop2;
wire		teop2;
wire		tprty2;
wire		terr2;
wire [1:0]	tmod2;
wire [31:0]	tdat2;
wire [5:0]	tadr2;
wire [ports-1:0]	dtpa2;

`endif

`ifdef NUMINT4

// SPI-3 Interface 3

wire		renb3;
wire		rsx3;
wire		rsop3;
wire		reop3;
wire		rprty3;
wire		rval3;
wire		rerr3;
wire [1:0]	rmod3;
wire [31:0]	rdat3;

wire		tenb3;
wire		tsx3;
wire		tsop3;
wire		teop3;
wire		tprty3;
wire		terr3;
wire [1:0]	tmod3;
wire [31:0]	tdat3;
wire [5:0]	tadr3;
wire [ports-1:0]	dtpa3;

`endif


// AHB master
wire        HCLK;
wire        HREADY;
wire  [1:0] HRESP;
wire [35:0] HRDATA;
wire        HWRITE;
wire        HBURST;
wire [ 1:0] HTRANS;
wire [17:0] HADDR;
wire  [1:0] HSIZE;
wire [35:0] HWDATA;

// Memory controller/test_io mux
wire [35:0] PMID;
wire [17:0] PMIA;

wire [35:0] mem_D;
wire [17:0] mem_SA;


reg  [ 1:0] TESTMD;

//Interrupt line
wire        ASB_IRQ_SLI;

// MPI interface signals from bmaster driver
wire   		mpi_clk;
wire [1:0]	mpi_tsz;
wire   		mpi_rdwr_n;
wire   		mpi_burst;
wire   		mpi_bdip;
wire   		mpi_strbn;
wire   		cs0n;
wire   		cs1;
wire [17:0]	mpi_addr;
tri [7:0]	mpi_data;
wire   		mpi_ta;
wire   		mpi_tea;
wire   		mpi_irq;
wire   		mpi_retry;

reg [7:0]   read_reg;
reg [7:0]   rx_pe;
reg [7:0]   rx_pf;
reg [7:0]   tx_pf;

initial
   TESTMD = 2'b00;   // Enable SPI4 testio_mux to get the HSIX into bypass mode


// Test mode multiplexor
assign PMIA[17] =                                  mem_SA[17];
assign PMIA[16] = (TESTMD == 2'b00) ? 1'b0 :       mem_SA[16];    // spi4_sel
assign PMIA[15] =                                  mem_SA[15];
assign PMIA[14] =                                  mem_SA[14];
assign PMIA[13] =                                  mem_SA[13];
assign PMIA[12] = (TESTMD == 2'b00) ? 1'b0 :       mem_SA[12];    // spi4_sel
assign PMIA[11] =                                  mem_SA[11];
assign PMIA[10] = (TESTMD == 2'b00) ? 1'b0 :       mem_SA[10];    // TSTLOOPBK
assign PMIA[ 9] =                                  mem_SA[ 9];
assign PMIA[ 8] =                                  mem_SA[ 8];
assign PMIA[ 7] =                                  mem_SA[ 7];
assign PMIA[ 6] =                                  mem_SA[ 6];
assign PMIA[ 5] =                                  mem_SA[ 5];
assign PMIA[ 4] =                                  mem_SA[ 4];
assign PMIA[ 3] = (TESTMD == 2'b00) ? 1'b1 :       mem_SA[ 3];    // BYPASS
assign PMIA[ 2] =                                  mem_SA[ 2];
assign PMIA[ 1] = (TESTMD == 2'b00) ? dut_reset :  mem_SA[ 1];    // RESETIX
assign PMIA[ 0] =                                  mem_SA[ 0];

assign PMID[35] =                                  mem_D [35];
assign PMID[34] =                                  mem_D [34];
assign PMID[33] =                                  mem_D [33];
assign PMID[32] = (TESTMD == 2'b00) ? 1'b0 :       mem_D [32];    // TSTMODE
assign PMID[31] =                                  mem_D [31];
assign PMID[30] = (TESTMD == 2'b00) ? 1'b0 :       mem_D [30];    // TSTSHFTLD
assign PMID[29] =                                  mem_D [29];
assign PMID[28] =                                  mem_D [28];
assign PMID[27] =                                  mem_D [27];
assign PMID[26] = (TESTMD == 2'b00) ? 1'b0 :       mem_D [26];    // ECSEL
assign PMID[25] =                                  mem_D [25];
assign PMID[24] = (TESTMD == 2'b00) ? 1'b0 :       mem_D [24];    // ECTOGGLE
assign PMID[23] =                                  mem_D [23];
assign PMID[22] = (TESTMD == 2'b00) ? 1'b0 :       mem_D [22];    // EXDNUP
assign PMID[21] =                                  mem_D [21];
assign PMID[20] =                                  mem_D [20];
assign PMID[19] =                                  mem_D [19];
assign PMID[18] = (TESTMD == 2'b00) ? dut_reset :  mem_D [18];    // TESTRST
assign PMID[17] =                                  mem_D [17];
assign PMID[16] =                                  mem_D [16];
assign PMID[15] =                                  mem_D [15];
assign PMID[14] =                                  mem_D [14];
assign PMID[13] =                                  mem_D [13];
assign PMID[12] =                                  mem_D [12];
assign PMID[11] =                                  mem_D [11];
assign PMID[10] =                                  mem_D [10];
assign PMID[ 9] =                                  mem_D [ 9];
assign PMID[ 8] =                                  mem_D [ 8];
assign PMID[ 7] =                                  mem_D [ 7];
assign PMID[ 6] =                                  mem_D [ 6];
assign PMID[ 5] =                                  mem_D [ 5];
assign PMID[ 4] =                                  mem_D [ 4];
assign PMID[ 3] =                                  mem_D [ 3];
assign PMID[ 2] =                                  mem_D [ 2];
assign PMID[ 1] =                                  mem_D [ 1];
assign PMID[ 0] =                                  mem_D [ 0];

// -------------------------------------------------------------------------
// Module instantiations
// -------------------------------------------------------------------------

orspi_qspi3 orspi_qspi3 (


// FPGA external interface io

   .sys_resetn    (sys_resetn),         // system reset (active low)
   .sys_rst_n     (sys_rst_n),         

// ------------------------------------
// SPI-3 INTERFACE NUMBER 0 I/O SIGNALS
// ------------------------------------

   // receive side I/O
   .rfclk0        (rfclk),
   .renb0         (renb0),
   .renb_a0       (renb0),
   .renb_b0       (renb0),
        
   .rsx0          (rsx0),
   .rsop0         (rsop0),
   .reop0         (reop0),
   .rprty0        (rprty0),
   .rval0         (rval0),
   .rerr0         (rerr0),
   .rmod0         (rmod0[1:0]),
   .rdat0         (rdat0[31:0]),
   
   // transmit side I/O
   .tenb0         (tenb0),
   .tdat0         (tdat0[31:0]),
   .tmod0         (tmod0[1:0]),
   .tprty0        (tprty0),
   .tsop0         (tsop0),
   .teop0         (teop0),
   .terr0         (terr0),
   .tsx0          (tsx0),
   .dtpa0         (dtpa0[ports-1:0]),
   .stpa0         (stpa0),
   .ptpa0         (ptpa0),
   .tadr0         (tadr0[5:0]),

`ifdef NUMINT2

// ------------------------------------
// SPI-3 INTERFACE NUMBER 1 I/O SIGNALS
// ------------------------------------

   // receive side I/O
   .rfclk1        (rfclk),
   .renb1         (renb1),
   .renb_a1       (renb1),
   .renb_b1       (renb1),
        
   .rsx1          (rsx1),
   .rsop1         (rsop1),
   .reop1         (reop1),
   .rprty1        (rprty1),
   .rval1         (rval1),
   .rerr1         (rerr1),
   .rmod1         (rmod1[1:0]),
   .rdat1         (rdat1[31:0]),
   
   // transmit side I/O
   .tenb1         (tenb1),
   .tdat1         (tdat1[31:0]),
   .tmod1         (tmod1[1:0]),
   .tprty1        (tprty1),
   .tsop1         (tsop1),
   .teop1         (teop1),
   .terr1         (terr1),
   .tsx1          (tsx1),
   .dtpa1         (dtpa1[ports-1:0]),
   .stpa1         (stpa1),
   .ptpa1         (ptpa1),
   .tadr1         (tadr1[5:0]),

`endif

`ifdef NUMINT3

// ------------------------------------
// SPI-3 INTERFACE NUMBER 2 I/O SIGNALS
// ------------------------------------

   // receive side I/O
   .rfclk2        (rfclk),
   .renb2         (renb2),
   .renb_a2       (renb2),
   .renb_b2       (renb2),
        
   .rsx2          (rsx2),
   .rsop2         (rsop2),
   .reop2         (reop2),
   .rprty2        (rprty2),
   .rval2         (rval2),
   .rerr2         (rerr2),
   .rmod2         (rmod2[1:0]),
   .rdat2         (rdat2[31:0]),
   
   // transmit side I/O
   .tenb2         (tenb2),
   .tdat2         (tdat2[31:0]),
   .tmod2         (tmod2[1:0]),
   .tprty2        (tprty2),
   .tsop2         (tsop2),
   .teop2         (teop2),
   .terr2         (terr2),
   .tsx2          (tsx2),
   .dtpa2         (dtpa2[ports-1:0]),
   .stpa2         (stpa2),
   .ptpa2         (ptpa2),
   .tadr2         (tadr2[5:0]),

`endif 

`ifdef NUMINT4

// ------------------------------------
// SPI-3 INTERFACE NUMBER 3 I/O SIGNALS
// ------------------------------------

   // receive side I/O
   .rfclk3        (rfclk),
   .renb3         (renb3),
   .renb_a3       (renb3),
   .renb_b3       (renb3),
        
   .rsx3          (rsx3),
   .rsop3         (rsop3),
   .reop3         (reop3),
   .rprty3        (rprty3),
   .rval3         (rval3),
   .rerr3         (rerr3),
   .rmod3         (rmod3[1:0]),
   .rdat3         (rdat3[31:0]),
   
   // transmit side I/O
   .tenb3         (tenb3),
   .tdat3         (tdat3[31:0]),
   .tmod3         (tmod3[1:0]),
   .tprty3        (tprty3),
   .tsop3         (tsop3),
   .teop3         (teop3),
   .terr3         (terr3),
   .tsx3          (tsx3),
   .dtpa3         (dtpa3[ports-1:0]),
   .stpa3         (stpa3),
   .ptpa3         (ptpa3),
   .tadr3         (tadr3[5:0]),

`endif 

//ASIC side pins for the orspi.  These pins must exist for the embedded core.

  .ARDATN     (~a_rdat),  	
  .ARDATP     (a_rdat),  	
  .ARCTLN     (~a_rctl),  	
  .ARCTLP     (a_rctl),  	
  .ARDCLKN    (~a_rdclk),  	
  .ARDCLKP    (a_rdclk),  	
  .RSCLKA     (a_rsclk),		
  .RSTATA     (a_rstat),		
  .ARSCLKN    (),	
  .ARSCLKP    (),	
  .ARSTATN    (),	
  .ARSTATP    (),	
  .BRDATN     (),  	
  .BRDATP     (),  	
  .BRCTLN     (),  	
  .BRCTLP     (),  	
  .BRDCLKN    (),  	
  .BRDCLKP    (),  	
  .RSCLKB     (),		
  .RSTATB     (),		
  .BRSCLKN    (),	
  .BRSCLKP    (),	
  .BRSTATN    (),	
  .BRSTATP    (),	
  .TSCLKA     (a_tsclk),		
  .TSTATA     (a_tstat), 	
  .ATSCLKN    (),	
  .ATSCLKP    (),	
  .ATSTATN    (),	
  .ATSTATP    (),	
  .ATDATN     (),		
  .ATDATP     (a_tdat[15:0]),		
  .ATCTLN     (),		
  .ATCTLP     (a_tctl),		
  .ATDCLKN    (),	
  .ATDCLKP    (a_tdclk),	
  .ATREFCLK   (trefclk),	
  .TSCLKB     (),		// unconnected
  .TSTATB     (), 		// unconnected
  .BTSCLKN    (),		// unconnected
  .BTSCLKP    (),		// unconnected
  .BTSTATN    (),		// unconnected
  .BTSTATP    (),		// unconnected
  .BTDATN     (),		// unconnected
  .BTDATP     (),		// unconnected
  .BTCTLN     (),		
  .BTCTLP     (),		
  .BTDCLKN    (),	
  .BTDCLKP    (),	
  .BTREFCLK   (1'b0),	

  .MCREFCLK   (),	
  .PDN        (1'b1),		
  .PMIA       (PMIA[17:0]),		
  .PMIC       (),		
  .PMICN      (), 		
  .PMID       (PMID[35:0]),		
  .PMIK       (),		// unconnected
  .PMIKN      (),		// unconnected
  .PMIQ       (),		// unconnected
  .PMIRN      (),       	// unconnected
  .PMIWN      (),		// unconnected
  
  .REF10      (1'b0),		
  .REF14      (1'b1),		
  .EXT_1K     (1'b0),		

  .RESLO      (1'b0),		
  .RESHI      (1'b1),		

  .ALVCTAP1   (),	
  .ALVCTAP2   (),	
  .ALVCTAP3   (),	
  .ALVCTAP4   (),	
  .ALVCTAP5   (),	
  .BLVCTAP1   (),	
  .BLVCTAP2   (),	
  .BLVCTAP3   (),	
  .BLVCTAP4   (),	
  .BLVCTAP5   (),	

  .REFCLKN    (),	
  .REFCLKP    (),	

  .RESETN     (dut_reset_n),		

  .REXT(),		
  .REXTN(),		

  .TESTCLK    (1'b0),	

  .TESTMDN    (TESTMD[1:0]), 	
  .TRISTN     (1'b1),		

  .HDINN_A    (),	
  .HDINN_B    (),	
  .HDINN_C    (),	
  .HDINN_D    (),	
  .HDINP_A    (),	
  .HDINP_B    (),	
  .HDINP_C    (),	
  .HDINP_D    (),	

  .HDOUTN_A   (),	
  .HDOUTN_B   (),	
  .HDOUTN_C   (),	
  .HDOUTN_D   (),	
  .HDOUTP_A   (),	
  .HDOUTP_B   (),	
  .HDOUTP_C   (),	
  .HDOUTP_D   (),	


//--MPI pins from the system bus 

//  .MPI_CLK    (mpi_clk),
//  .MPI_RDWR_N (mpi_rw),
//  .MPI_STRBN  (mpi_strbn),
//  .MPI_TSZ    (mpi_tsz), 
//  .MPI_BURST  (mpi_burstn),
//  .MPI_BDIP   (mpi_bdipn),
//  .CS0N       (mpi_cs0n),
//  .CS1        (mpi_cs1),
//  .USR_CLK    (usr_clk),
//  .USR_IRQ_GENERAL(usr_irq_general),
//  .MPI_ADDR   (mpi_a), 
//  .MPI_TA     (mpi_ackn),
//  .MPI_RETRY  (mpi_retryn), 
//  .MPI_TEA    (mpi_tean),
//  .MPI_IRQ    (mpi_irqn),
//  .USR_IRQ    (usr_irq),
//  .MPI_DATA   (mpi_d_temp),
//  .MPI_PARITY (mpi_dp[0])
//
  .MPI_CLK    (mpi_clk),
  .MPI_RDWR_N (mpi_rdwr_n),
  .MPI_STRBN  (mpi_strbn),
  .MPI_TSZ    (mpi_tsz), 
  .MPI_BURST  (mpi_burst),
  .MPI_BDIP   (mpi_bdip),
  .CS0N       (cs0n),
  .CS1        (cs1),
  .USR_CLK    (mpi_clk),
  .USR_IRQ_GENERAL(1'b0),
  .MPI_ADDR   (mpi_addr), 
  .MPI_TA     (mpi_ta),
  .MPI_RETRY  (mpi_retry), 
  .MPI_TEA    (mpi_tea),
  .MPI_IRQ    (mpi_irq),
  .USR_IRQ    (),
  .MPI_DATA   (mpi_data)
//  .MPI_PARITY ()
);

// assign mpi_d_temp = mpi_d[7:0];

//
// SPI-3 LOOPBACK CIRCUITS FOR SIMULATION 
//

rfclk_pll rfclk_pll_o(

    .clk              (rfclk),
    .mclk             (rfclk_out),
    .nclk             (),
    .lock             ()
);

defparam loop_0.num_fifo = num_fifo;
loop loop_0(

	.rfclk		(rfclk_out),
	.sys_resetn	(sys_resetn),	// system reset (active low)

	.renb		(renb0),
	.rsx		(rsx0),
	.rsop		(rsop0),
	.reop		(reop0),
	.rprty		(rprty0),
	.rmod		(rmod0),
        .rdat		(rdat0),
	.rval		(rval0),
	.rerr		(rerr0),

	.tenb		(tenb0),
	.tsx		(tsx0),
	.tsop		(tsop0),
	.teop		(teop0),
	.tprty		(tprty0),
	.tadr		(tadr0),
	.tmod		(tmod0),
        .tdat		(tdat0),
	.terr		(terr0),

	.dtpa		(dtpa0),
	.port_id_int	(4'd0)
);


`ifdef NUMINT2

defparam loop_1.num_fifo = num_fifo;
loop loop_1(

	.rfclk		(rfclk_out),
	.sys_resetn	(sys_resetn),	// system reset (active low)

	.renb		(renb1),
	.rsx		(rsx1),
	.rsop		(rsop1),
	.reop		(reop1),
	.rprty		(rprty1),
	.rmod		(rmod1),
        .rdat		(rdat1),
        .rval		(rval1),
	.rerr		(rerr1),

	.tenb		(tenb1),
	.tsx		(tsx1),
	.tsop		(tsop1),
	.teop		(teop1),
	.tprty		(tprty1),
	.tadr		(tadr1),
	.tmod		(tmod1),
        .tdat		(tdat1),
	.terr		(terr1),

	.dtpa		(dtpa1),
	.port_id_int	(4'd0)
);

`endif

`ifdef NUMINT3

defparam loop_2.num_fifo = num_fifo;
loop loop_2(

	.rfclk		(rfclk_out),
	.sys_resetn	(sys_resetn),	// system reset (active low)

	.renb		(renb2),
	.rsx		(rsx2),
	.rsop		(rsop2),
	.reop		(reop2),
	.rprty		(rprty2),
	.rmod		(rmod2),
        .rdat		(rdat2),
	.rval		(rval2),
	.rerr		(rerr2),

	.tenb		(tenb2),
	.tsx		(tsx2),
	.tsop		(tsop2),
	.teop		(teop2),
	.tprty		(tprty2),
	.tadr		(tadr2),
	.tmod		(tmod2),
        .tdat		(tdat2),
	.terr		(terr2),

	.dtpa		(dtpa2),
	.port_id_int	(4'd0)
);

`endif

`ifdef NUMINT4

defparam loop_3.num_fifo = num_fifo;
loop loop_3(

	.rfclk		(rfclk_out),
	.sys_resetn	(sys_resetn),	// system reset (active low)

	.renb		(renb3),
	.rsx		(rsx3),
	.rsop		(rsop3),
	.reop		(reop3),
	.rprty		(rprty3),
	.rmod		(rmod3),
        .rdat		(rdat3),
	.rval		(rval3),
	.rerr		(rerr3),

	.tenb		(tenb3),
	.tsx		(tsx3),
	.tsop		(tsop3),
	.teop		(teop3),
	.tprty		(tprty3),
	.tadr		(tadr3),
	.tmod		(tmod3),
        .tdat		(tdat3),
	.terr		(terr3),

	.dtpa		(dtpa3),
	.port_id_int	(4'd0)
);

`endif

spi3mon spimon0 (
	
	.rfclk(rfclk_out),
	.renb(renb0),
	.rxdat(rdat0),
	.rmod(rmod0),
	.rprty(rprty0),
	.rval(rval0),
	.rsop(rsop0),
	.reop(reop0),
	.rerr(rerr0),
	.rsx(rsx0),
	.reset(sys_resetn),
	.bankid(2'b00)
);

`ifdef NUMINT2

spi3mon spimon1 (
	
	.rfclk(rfclk_out),
	.renb(renb1),
	.rxdat(rdat1),
	.rmod(rmod1),
	.rprty(rprty1),
	.rval(rval1),
	.rsop(rsop1),
	.reop(reop1),
	.rerr(rerr1),
	.rsx(rsx1),
	.reset(sys_resetn),
	.bankid(2'b00)
);

`endif

`ifdef NUMINT3

spi3mon spimon2 (
	
	.rfclk(rfclk_out),
	.renb(renb2),
	.rxdat(rdat2),
	.rmod(rmod2),
	.rprty(rprty2),
	.rval(rval2),
	.rsop(rsop2),
	.reop(reop2),
	.rerr(rerr2),
	.rsx(rsx2),
	.reset(sys_resetn),
	.bankid(2'b00)
);

`endif

`ifdef NUMINT4

spi3mon spimon3 (
	
	.rfclk(rfclk_out),
	.renb(renb3),
	.rxdat(rdat3),
	.rmod(rmod3),
	.rprty(rprty3),
	.rval(rval3),
	.rsop(rsop3),
	.reop(reop3),
	.rerr(rerr3),
	.rsx(rsx3),
	.reset(sys_resetn),
	.bankid(2'b00)
);

`endif

// AHB clock generation (33MHz)
//tbclk #(30.0) ahb_clk (1'b1, HCLK);
tbclk #(30.0) ahb_clk (1'b1, mpi_clk);


// AHB Master instantiation
//bmaster bmaster (
//      .HCLK       (HCLK),
//      .HRESET_N   (dut_reset_n),
//      .HGRANT     (1'b1),
//      .HREADY     (toptest.orspi_qspi3.mycore_inst.HREADY_OUT),
//      .HRESP      (toptest.orspi_qspi3.mycore_inst.HRESP),
//      .HRDATA     (toptest.orspi_qspi3.mycore_inst.HRDATA),
//      .HBUSREQ    (),
//      .HLOCK      (),
//      .HWRITE     (toptest.orspi_qspi3.mycore_inst.HWRITE),
//      .HBURST     (toptest.orspi_qspi3.mycore_inst.HBURST),
//      .HTRANS     (toptest.orspi_qspi3.mycore_inst.HTRANS),
//      .HADDR      (toptest.orspi_qspi3.mycore_inst.HADDR),
//      .HSIZE      (toptest.orspi_qspi3.mycore_inst.HSIZE),
//      .HWDATA     (toptest.orspi_qspi3.mycore_inst.HWDATA)
//      );

bmaster bmaster(
   .mpi_clk	(mpi_clk),
   .mpi_tsz	(mpi_tsz),
   .mpi_rdwr_n	(mpi_rdwr_n),
   .mpi_burst	(mpi_burst),
   .mpi_bdip	(mpi_bdip),
   .mpi_strbn	(mpi_strbn),
   .cs0n	(cs0n),
   .cs1		(cs1),
   .mpi_addr	(mpi_addr),
   .mpi_data	(mpi_data),
   .mpi_ta	(mpi_ta),
   .mpi_tea	(mpi_tea),
   .mpi_irq	(mpi_irq),
   .mpi_retry   (mpi_retry)
);



//
//LatSPI
//

latspi4 a_latspi4 (
                 .tdclk(a_rdclk),
                 .tdat(a_rdat),
                 .tctl(a_rctl),
                 .tsclk(a_rsclk),
                 .tstat(a_rstat),

                 .rdclk(a_tdclk),
                 .rdat(a_tdat),
                 .rctl(a_tctl),
                 .rsclk(a_tsclk),
                 .rstat(a_tstat)
                 );

// ---------------------------------------------------------------------------
// Clocks
// ---------------------------------------------------------------------------
initial
begin
   trefclk_2x  = 1'b0;
   trefclk_div = 3'b000;
   rfclk = 1'b0;
end

// POS-PHY clocks

// 2x DDR clock for SPI4HSIX model operating in PLL bypass mode
always #(0.625) trefclk_2x = ~trefclk_2x;    // 800MHz
always #(4.808) rfclk = ~rfclk;    		// 104MHz

// Divide trefclk_2x by 8 to get trefclk
always @(posedge trefclk_2x)
   trefclk_div = trefclk_div + 3'b001;

assign trefclk = trefclk_div[2];

// ---------------------------------------------------------------------------
// Reset
// ---------------------------------------------------------------------------
initial
begin
   reset_done = 1'b0;
   
   // First reset
   // Hard-reset & SPI4 reset
   dut_reset  = 1'b0;
   sys_rst_n  = 1'b0;
   spi4_reset = 1'b0;
   sys_resetn = 1'b0;
   FPGA_LB    = 1'b0;
   #(1);
   dut_reset  = 1'b1;
   sys_rst_n  = 1'b1;
   spi4_reset = 1'b1;

   #(100);
   sys_resetn = 1'b1;

				// delay reset to asb
   #(400);			// mph
   dut_reset  = 1'b0;		// mph
   spi4_reset = 1'b0;		// mph
   
   // Second reset
   // SPI4 reset only
   #(500);
   spi4_reset = 1'b1;
   -> preload_ram;
   #(100);
   spi4_reset = 1'b0;
   
   reset_done = 1'b1;
end

assign      dut_reset_n = ~dut_reset;

// ---------------------------------------------------------------------------
// output from spi3mon
// ---------------------------------------------------------------------------
integer log_file;

initial begin

   log_file = $fopen ("sim.log");

   #10000000

   $fclose(log_file);

end



// ---------------------------------------------------------------------------
// SDF annotation  
// ---------------------------------------------------------------------------
`ifdef ANNOTATE
initial
begin
   $sdf_annotate("../primetime/report_sdf/orspii_asb.sdfRC",
                  orspii_asb,
                  ,
                  "sdf_annotate.log",
                  "MAXIMUM"
                 );
end
`endif

// ---------------------------------------------------------------------------
// Gate-level RAM pre-load to prevent X propagation  
// ---------------------------------------------------------------------------
`ifdef GATELEVEL
always @(preload_ram)
begin
   // While in this second reset, initialize control memories to randomly set data (see rand_init.pl)
//   toptest.orspii_asb.s4a.t.tx_ls_inst.tsp_top.port_status_mem.mem_array.U_BIST_BINT0_M.BR.M.load("port_status.init");
//   toptest.orspii_asb.s4a.t.tx_cf_inst.pws_inst.pws_cr_inst.credit_inst.SW_MPSRAM0_M.BR.M.load("credit.init");
//   toptest.orspii_asb.s4a.t.tx_cf_inst.pws_inst.pws_pdm_inst.pdm_inst.SW_MPSRAM0_M.BR.M.load("pdm_main.init");
//   toptest.orspii_asb.s4a.t.tx_cf_inst.pws_inst.pws_stat_inst.status_inst.SW_MPSRAM0_M.BR.M.load("pdm_stat.init");
//   toptest.orspii_asb.s4a.t.tx_cf_inst.pws_inst.pws_spt_inst.spt_inst.SW_MPSRAM0_M.BR.M.load("mpcal.init");

   toptest.orspi_qspi3.mycore_inst.orspi_core_inst.asb_inst.s4a.t.tx_ls_inst.tsp_top.port_status_mem.mem_array.U_BIST_BINT0_M.BR.M.load("port_status.init");
   toptest.orspi_qspi3.mycore_inst.orspi_core_inst.asb_inst.s4a.t.tx_cf_inst.pws_inst.pws_cr_inst.credit_inst.SW_MPSRAM0_M.BR.M.load("credit.init");
   toptest.orspi_qspi3.mycore_inst.orspi_core_inst.asb_inst.s4a.t.tx_cf_inst.pws_inst.pws_pdm_inst.pdm_inst.SW_MPSRAM0_M.BR.M.load("pdm_main.init");
   toptest.orspi_qspi3.mycore_inst.orspi_core_inst.asb_inst.s4a.t.tx_cf_inst.pws_inst.pws_stat_inst.status_inst.SW_MPSRAM0_M.BR.M.load("pdm_stat.init");
   toptest.orspi_qspi3.mycore_inst.orspi_core_inst.asb_inst.s4a.t.tx_cf_inst.pws_inst.pws_spt_inst.spt_inst.SW_MPSRAM0_M.BR.M.load("mpcal.init");
end
`endif

// ---------------------------------------------------------------------------
// Simulation lock-up termination
// ---------------------------------------------------------------------------
initial
begin
//  sec  msec   usec   nsec
   #(1 * 1000 * 1000 * 1000);      // 1 second timebomb
   $display("%t: ERROR: Simulation lock-up. Terminating after 1 second...",$time);
   $display("%t: *******************************************************",$time);
   $display("%t: ****               T E S T   F A I L E D",$time);
   $display("%t: *******************************************************",$time);
   $finish(2);
end

// ---------------------------------------------------------------------------
// Main initial block to run test
// ---------------------------------------------------------------------------

initial
begin // end is contained in footer.v

   RX_DPRAM_0_AGGR_MODE = 2'b00;
   RX_DPRAM_1_AGGR_MODE = 2'b00;
   RX_DPRAM_2_AGGR_MODE = 2'b00;
   RX_DPRAM_3_AGGR_MODE = 2'b00;
   
 
 
   test_go = 1'b0;
      
   // HSIX requires 2x clock when operating in bypass mode (set by testio_mux)
   // the TSTCLK connects to the scan clock. Simulation speed will be greatly
   // affected if all the test logic is run @ 800MHz, so this force probes
   // down into the design to force the high-speed clock into the HSIX model 
//   force  orspii_asb.s4a.r.rdi.TSTCLK           = trefclk_2x;  
//   force  orspii_asb.s4a.t.tx_hs_inst.TSTCLK    = trefclk_2x;
      
   force  toptest.orspi_qspi3.mycore_inst.orspi_core_inst.asb_inst.s4a.r.rdi.TSTCLK           = trefclk_2x;  
   force  toptest.orspi_qspi3.mycore_inst.orspi_core_inst.asb_inst.s4a.t.tx_hs_inst.TSTCLK    = trefclk_2x;
      
   $timeformat(-9,0," ns",10);

   $display("**************************************************************");
   $display("****                                                          ");
   $display("****              LATTICE SEMICONDUCTOR, INC.                 ");
   $display("****                     O R S P I I                          ");
   $display("****        Top Level Verification - Phase 1 - S4A            ");
   $display("****                                                          ");
   $display("**** =========================================================");
   $display("****");
   $display("****    Build date: %s",`BUILDDATE);
   $display("****    Built by:   %s",`BUILDWHO);
   $display("****");
   $display("****    SF: %s",`SF);
   $display("****     M: %s",`M);
   $display("****");
   $display("**************************************************************");

   error_count = 0;

// Wait for reset to be deasserted before continuing
   wait (reset_done == 1'b1);

   $display("%t: DUT out of reset",$time);
   
// commented out - does not exist in new bmaster - mph
//   bmaster.set_retry_limit(10);

// Wait for DUT to initialise RAMs before continuing
//   wait (orspii_asb.s4a.t.MEM_TXPDMC_INIT_DONE == 1'b1 &&
//         orspii_asb.s4a.t.MEM_TXPDMM_INIT_DONE == 1'b1 &&
//         orspii_asb.s4a.t.MEM_TXPDMU_INIT_DONE == 1'b1 );

// add a delay as a substitute for the following wait
// determined by watching an older simulation (3 usec)
// also added additional delay because circuit was not responding to first MPI read 
 #9000;
 #11000;

//   wait (toptest.orspi_qspi3.mycore_inst.orspi_core_inst.asb_inst.s4a.t.MEM_TXPDMC_INIT_DONE == 1'b1 &&
//         toptest.orspi_qspi3.mycore_inst.orspi_core_inst.asb_inst.s4a.t.MEM_TXPDMM_INIT_DONE == 1'b1 &&
//         toptest.orspi_qspi3.mycore_inst.orspi_core_inst.asb_inst.s4a.t.MEM_TXPDMU_INIT_DONE == 1'b1 );

// Short delay to let everything settle down..
   #200;

   test_go = 1'b1;
   

//Register (SPI/O and FIFO) configuration file 03

//Calendar configuration 

CALENDAR_M_RX           = 8'd7;
CALENDAR_LEN_RX         = 10'd16;

CALENDAR_M_RX_SHDW      = 8'd7;
CALENDAR_LEN_RX_SHDW    = 10'd16;

CALENDAR_SW_EN_RX       = 1'b0;
CALENDAR_SW_SEL_RX      = 1'b0;

CALENDAR_M_TX           = 8'd7;
CALENDAR_LEN_TX         = 10'd16;

CALENDAR_M_TX           = 8'd7;
CALENDAR_LEN_TX         = 10'd16;

CALENDAR_SW_EN_TX       = 1'b0;

TX_BURST_TERMINATION    = 1'b0;

//RX Async FIFO Threshold 

FIFO_THRESHOLD_H_RX = 8'd120;
FIFO_THRESHOLD_H_TX = 5'h17;

//Maxburst 1 and 2 values

MAX_BURST1 = 10'd16; 
MAX_BURST2 = 10'd8; 

// MAX_BURST1_RX = 512/RX_PDM_ACTIVE_PORTS * 0.4; 
// MAX_BURST2_RX = 512/RX_PDM_ACTIVE_PORTS * 0.2; 

//Limit 64byte bursts, Loss Sync count value
//Enable training detection (RX) and Baseline (?)

DISABLE_STATUS = 1'b0;
MASK_DIP4 = 1'b0;
LOSS_SYNC = 3'd7;
EN_TRAINING = 1'b0;
EN_BASELINE = 1'b0;
DIP2_ERR_TH = 3'd4;

//Training configuration (TX)

DATA_MAX_T = 32'd300;
ALPHA = 16'd2;

// Interrupt Enables

RDI_PLL_LOL_INT_EN   = 1'b0;
RDI_BAS_DONE_INT_EN  = 1'b0;
RDI_BAS_ERR_INT_EN   = 1'b0;
RDI_DSKW_DONE_INT_EN = 1'b0;
RDI_DSKW_ERR_INT_EN  = 1'b0;
RDI_TRN_DET_INT_EN   = 1'b0;
ALGN_OFF_INT_EN      = 1'b0;
TX_STATUS_LOF_INT_EN = 1'b0;

RDI_INT_EN = {RDI_PLL_LOL_INT_EN, 
              RDI_BAS_DONE_INT_EN,
	      RDI_BAS_ERR_INT_EN,
	      RDI_DSKW_DONE_INT_EN,
	      RDI_DSKW_ERR_INT_EN,
	      RDI_TRN_DET_INT_EN,
	      ALGN_OFF_INT_EN,
	      TX_STATUS_LOF_INT_EN};

ILLEGAL_CTL_EN = 1'b0;
RX_SOP_ALIGN_ERR_INT_EN = 1'b0;
TX_SOP_ALIGN_ERR_INT_EN = 1'b0;
DIP4_ERR_INT_EN = 1'b0;
DIP2_ERR_INT_EN = 1'b0;
ASYNC_FIFO_RX_OVRRUN_INT_EN = 1'b1;

SOP_DIP_ASF_INT_EN = {ILLEGAL_CTL_EN,
                      RX_SOP_ALIGN_ERR_INT_EN,
                      TX_SOP_ALIGN_ERR_INT_EN,
		      DIP4_ERR_INT_EN,
		      DIP2_ERR_INT_EN,
		      ASYNC_FIFO_RX_OVRRUN_INT_EN};
  
  
//RX FIFO Overrun Interrupt Enables

DPRAM_0_RXFIFO_OVERRUN_INT_EN = 1'b1;
DPRAM_1_RXFIFO_OVERRUN_INT_EN = 1'b1;
DPRAM_2_RXFIFO_OVERRUN_INT_EN = 1'b1;
DPRAM_3_RXFIFO_OVERRUN_INT_EN = 1'b1;

//TX FIFO Overrun Interrupt Enables

DPRAM_0_TXFIFO_OVERRUN_INT_EN = 1'b1;
DPRAM_1_TXFIFO_OVERRUN_INT_EN = 1'b1;
DPRAM_2_TXFIFO_OVERRUN_INT_EN = 1'b1;
DPRAM_3_TXFIFO_OVERRUN_INT_EN = 1'b1;

//RX FIFO Underrun Interrupt Enables

DPRAM_0_RXFIFO_URRUN_INT_EN = 1'b0;
DPRAM_1_RXFIFO_URRUN_INT_EN = 1'b0;
DPRAM_2_RXFIFO_URRUN_INT_EN = 1'b0;
DPRAM_3_RXFIFO_URRUN_INT_EN = 1'b0;

//TX FIFO Underrun Interrupt Enables

DPRAM_0_TXFIFO_URRUN_INT_EN = 1'b0;
DPRAM_1_TXFIFO_URRUN_INT_EN = 1'b0;
DPRAM_2_TXFIFO_URRUN_INT_EN = 1'b0;
DPRAM_3_TXFIFO_URRUN_INT_EN = 1'b0;

DPRAM_RX_FIFO_OVER_UR_RUN_INT_EN = {DPRAM_0_RXFIFO_OVERRUN_INT_EN,
                                    DPRAM_1_RXFIFO_OVERRUN_INT_EN,
				    DPRAM_2_RXFIFO_OVERRUN_INT_EN,
				    DPRAM_3_RXFIFO_OVERRUN_INT_EN,
				    DPRAM_0_RXFIFO_URRUN_INT_EN,
				    DPRAM_1_RXFIFO_URRUN_INT_EN,
				    DPRAM_2_RXFIFO_URRUN_INT_EN,
				    DPRAM_3_RXFIFO_URRUN_INT_EN
                                    };

DPRAM_TX_FIFO_OVER_UR_RUN_INT_EN = {DPRAM_0_TXFIFO_OVERRUN_INT_EN,
                                    DPRAM_1_TXFIFO_OVERRUN_INT_EN,
				    DPRAM_2_TXFIFO_OVERRUN_INT_EN,
				    DPRAM_3_TXFIFO_OVERRUN_INT_EN,
				    DPRAM_0_TXFIFO_URRUN_INT_EN,
				    DPRAM_1_TXFIFO_URRUN_INT_EN,
				    DPRAM_2_TXFIFO_URRUN_INT_EN,
				    DPRAM_3_TXFIFO_URRUN_INT_EN
                                    };
				    
//FIFO Aggregation and Partition

RX_DPRAM_0_PART_SIZE = 2'b10;
RX_DPRAM_1_PART_SIZE = 2'b10;
RX_DPRAM_2_PART_SIZE = 2'b10;
RX_DPRAM_3_PART_SIZE = 2'b10;

RX_DPRAM_PART_SIZE = {RX_DPRAM_0_PART_SIZE,
                      RX_DPRAM_1_PART_SIZE,
		      RX_DPRAM_2_PART_SIZE,
		      RX_DPRAM_3_PART_SIZE};

RX_DPRAM_0_AGGR_MODE = 2'b00;
RX_DPRAM_1_AGGR_MODE = 2'b00;
RX_DPRAM_2_AGGR_MODE = 2'b00;
RX_DPRAM_3_AGGR_MODE = 2'b00;

RX_DPRAM_AGGR_MODE = {RX_DPRAM_0_AGGR_MODE,
                      RX_DPRAM_1_AGGR_MODE,
		      RX_DPRAM_2_AGGR_MODE,
		      RX_DPRAM_3_AGGR_MODE};

TX_DPRAM_0_PART_SIZE = 2'b10;
TX_DPRAM_1_PART_SIZE = 2'b10;
TX_DPRAM_2_PART_SIZE = 2'b10;
TX_DPRAM_3_PART_SIZE = 2'b10;

TX_DPRAM_PART_SIZE = {TX_DPRAM_0_PART_SIZE,
                      TX_DPRAM_1_PART_SIZE,
		      TX_DPRAM_2_PART_SIZE,
		      TX_DPRAM_3_PART_SIZE};

TX_DPRAM_0_AGGR_MODE = 2'b00;
TX_DPRAM_1_AGGR_MODE = 2'b00;
TX_DPRAM_2_AGGR_MODE = 2'b00;
TX_DPRAM_3_AGGR_MODE = 2'b00;

TX_DPRAM_AGGR_MODE = {TX_DPRAM_0_AGGR_MODE,
                      TX_DPRAM_1_AGGR_MODE,
		      TX_DPRAM_2_AGGR_MODE,
		      TX_DPRAM_3_AGGR_MODE};

//Full and Empty Fill Level Selects

TX_DPRAM_0_FULL_TYPE_SEL = 1'b1;
TX_DPRAM_1_FULL_TYPE_SEL = 1'b1;
TX_DPRAM_2_FULL_TYPE_SEL = 1'b1;
TX_DPRAM_3_FULL_TYPE_SEL = 1'b1;

RX_DPRAM_0_EMPTY_TYPE_SEL = 1'b0;
RX_DPRAM_1_EMPTY_TYPE_SEL = 1'b0;
RX_DPRAM_2_EMPTY_TYPE_SEL = 1'b0;
RX_DPRAM_3_EMPTY_TYPE_SEL = 1'b0;

DPRAM_FULL_EMPTY_SEL = {TX_DPRAM_0_FULL_TYPE_SEL,
                        TX_DPRAM_1_FULL_TYPE_SEL,
			TX_DPRAM_2_FULL_TYPE_SEL,
			TX_DPRAM_3_FULL_TYPE_SEL,
			RX_DPRAM_0_EMPTY_TYPE_SEL,
			RX_DPRAM_1_EMPTY_TYPE_SEL,
			RX_DPRAM_2_EMPTY_TYPE_SEL,
			RX_DPRAM_3_EMPTY_TYPE_SEL};

//SPI4.2 Speed, Status I/O, Loopback and Error Insert

LOW_SPEED_DATA_SEL = 1'b1;
LOOPBACK_FE = 1'b0;
STATUS_IO_SEL = 1'b0;
LOOPBACK_HS = 1'b0;
LOOPBACK_LS = 1'b0;
FORCE_DIP4_ERR = 1'b0;
FORCE_DIP2_ERR = 1'b0;

LS_STIO_LB_FERR = {LOOPBACK_FE,
LOW_SPEED_DATA_SEL,
                   STATUS_IO_SEL,
		   LOOPBACK_HS,
		   LOOPBACK_LS,
		   FORCE_DIP4_ERR,
		   FORCE_DIP2_ERR};

RX_EXT_STAT_EN = 1'b0;

//Memory configuration file 03

for (i=0;i<=(CALENDAR_LEN_TX-1'd1);i=i+1)
  begin
    TX_MAIN_CAL_SEQ[i]  = i[7:0];
  end
  
TX_SHADOW_CAL_SEQ[0]  = 8'dx;

for (i=0;i<=(CALENDAR_LEN_RX-1'd1);i=i+1)
  begin
    RX_MAIN_CAL_SEQ[i]  = i[7:0];
  end

RX_SHADOW_CAL_SEQ[0]  = 8'dx;

//

TX_PDM_ACTIVE_PORTS = 16;

for (i=0;i<=(TX_PDM_ACTIVE_PORTS-1'd1);i=i+1)
  begin
    TX_PDM_ACTIVE_PORT_ID[i]  = i[7:0];
    TX_PDM_MBEN[i]            = 1'b1;
    TX_PDM_M_BIT[i]           = 1'b0;
    TX_PDM_BVAL[i]            = 5'd4;
    TX_PDM_PORT_ID[i]         = i[7:0];
    TX_PDM_BANK_ID[i]         = i[3:2];
    TX_PDM_PA[i]              = {1'b0,i[1:0]};    
  end

//

RX_PDM_ACTIVE_PORTS = 16;

for (i=0;i<=(RX_PDM_ACTIVE_PORTS-1'd1);i=i+1)
  begin
    RX_PDM_ACTIVE_PORT_ID[i]  = i[7:0];
    RX_PDM_BANK_ID[i]         = i[3:2];
    RX_PDM_PA[i]              = {1'b0,i[1:0]};    
  end

// MAX_BURST1_RX = 512/RX_PDM_ACTIVE_PORTS * 0.4; 
// MAX_BURST2_RX = 512/RX_PDM_ACTIVE_PORTS * 0.2; 

MAX_BURST1_RX = 512/RX_PDM_ACTIVE_PORTS * 0.2;  // mph
MAX_BURST2_RX = 512/RX_PDM_ACTIVE_PORTS * 0.1;  // mph

MAX_BURST1    = MAX_BURST1_RX; 
MAX_BURST2    = MAX_BURST2_RX; 
///////////////////////////////////////////////////////////////////////
// >>>>>>>>>>>>>>>>>>>>>>>>> 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             :       body.v
// Author               :       Ben_Kerr,bkerr@latticesemi.com
// Created on           :       Tuesday July 09 2002 (WW27)
// Last Modified By     :       $Author: bkerr $
// Last Modified On     :       $Date: Mon Jan  6 11:12:14 2003 $
// Revision             :       $Revision: 1.34 $
// Status               :       Development
// Dependencies         :       None
//=====================================================================

//=====================================================================
// Description          :
//=====================================================================
// Body file used in the middle of the automatically created toptest.v
//
// After running the simany_ph1 script, toptest.v is created
// This file is built from the following files:
//
//   +-----------------------------------+
//   | `defines generated by script      |  Time of day, user information & configuration feedback
//   +-----------------------------------+
//   |                                   |  top level module statement, global variables
//   |            header.v               |  module instantiations, clock & reset generation
//   |                                   |  initial ....
//   +-----------------------------------+
//   |                                   |    DUT register settings (configuration specific)
//   |     SFnn - from command line      |
//   |                                   |
//   +-----------------------------------+
//   |                                   |    DUT memory configurations (configuration specific)
//   |     Mnn - from command line       |
//   |                                   |
//   +-----------------------------------+
//   |                                   |    Task calls to configure DUT
//   |       body.v (this file)          |    Task calls to enable checkers
//   |                                   |    Task calls to perform data format tests
//   +-----------------------------------+
//   |                                   |    Report pass/fail. Terminate simulation
//   |            footer.v               |    `include common tasks
//   |                                   |  endmodule
//   +-----------------------------------+
//
//
//=====================================================================

//=====================================================================
// Revision History
//=====================================================================
// $Log: body.v.rca $
// 
//  Revision: 1.34 Mon Jan  6 11:12:14 2003 bkerr
//  Added additional spi4_reset after register configuration to
//  reset DPRAM control logic after changing partition mode
// 
//  Revision: 1.33 Thu Nov 21 09:19:14 2002 bkerr
//  Added LOOPBACK_FE register bit
// 
//  Revision: 1.32 Fri Nov 15 10:01:55 2002 bkerr
//  Increased delays when running DF18-DF21 due to extra time required
//  to synchronise to long calendar sequence
// 
//  Revision: 1.31 Fri Nov  8 03:32:21 2002 bkerr
//  More delay after enableing HS & LS loopback to prevent packet
//  loss in testcase 17.
//  Added dummy write to prime the AHB slave
// 
//  Revision: 1.30 Thu Nov  7 12:10:28 2002 bkerr
//  Changed start-up order of BFMs. tx_cal should be started first to
//  allow the DUT to synchronise to the calendar and stop sending
//  training
// 
//  Revision: 1.29 Tue Nov  5 12:52:53 2002 bkerr
//  Enabled all tests
//  Increased delay following write to enable HS and LS loopback to prevent
//  packet loss
// 
//  Revision: 1.28 Fri Nov  1 05:14:41 2002 bkerr
//  Increased delay after changing loopback mode
// 
//  Revision: 1.27 Wed Oct 23 12:19:38 2002 bkerr
//  Increased delay after enabling loopback to allow the write to be completed
// 
//  Revision: 1.26 Tue Oct 22 08:50:00 2002 bkerr
//  Moved LatSPI4 Tx calendar Rx start control to Rx tests, as the TSTAT
//  output is not stable when switching into LS and HS loopback
// 
//  Revision: 1.25 Tue Oct 22 06:46:56 2002 bkerr
//  Brought in changes from branch
// 
//  Revision: 1.24.1.1 Tue Oct 22 06:34:57 2002 bkerr
//  Moved start of Rx fpga_bfm's to top of file
//  Turned off credit checking for 18,19,20 & 21 as DUT will not
//  obey credit in this mode
// 
//  Revision: 1.24 Mon Oct 21 05:52:51 2002 bkerr
//  Reordered tests to do RX test after all Tx tests
//  Increased delays to allow data to propogate through DUT
//  Increased delay to wait for calendar synchronisation
// 
//  Revision: 1.23 Fri Oct 18 09:30:44 2002 bkerr
//  Moved all BFM start-up to one place. All BFMs are enabled throughout
//  the test
// 
//  Revision: 1.22 Thu Oct 17 07:52:18 2002 bkerr
//  Don't do Rx or FPGA loopback tests for tests 18,19,20 & 21 as they
//  currently do not work correctly
//  Removed force to fix issue #43
// 
//  Revision: 1.21 Wed Oct 16 11:28:24 2002 bkerr
//  Added `defines to allow individual tests to be disabled easily
//  Incorporated latest changes to FPGA loopback test
// 
//  Revision: 1.20 Tue Oct 15 11:03:39 2002 bkerr
//  Uncommented low-speed and high-speed loopback tests as this
//  function is useable in top4 release
// 
//  Revision: 1.19 Fri Oct 11 09:49:31 2002 bkerr
//  Corrected calendar_tx stop after Tx tests.
// 
//  Revision: 1.18 Wed Oct  9 03:51:24 2002 bkerr
//  Modified tx tests to only run df05 for testcases 18,19,20 & 21
// 
//  Revision: 1.17 Wed Oct  2 06:26:38 2002 rproudlo
//  commented out FPGA_LB phase
// 
//  Revision: 1.16 Wed Oct  2 06:03:12 2002 rproudlo
//  Added FPGA_LB suite of tests
// 
//  Revision: 1.15 Tue Oct  1 11:51:18 2002 bkerr
//  Added call to df04 (ERR bit testing)
//  Renamed previous df04 call to df05
// 
//  Revision: 1.14 Mon Sep 30 12:35:46 2002 bkerr
//  Added $display of FPSC_ID register
// 
//  Revision: 1.13 Wed Sep 25 11:07:05 2002 bkerr
//  Increased time-delay at end of test to allow all data to flush out
//  Changed check_stats task call to check_stats_tx
// 
//  Revision: 1.12 Wed Sep 18 12:49:50 2002 bkerr
//  Increased delay at end of test due to increase in FPGA clock
//  frequency
// 
//  Revision: 1.11 Mon Sep 16 05:38:03 2002 rproudlo
//  DebuggingInitial testing
// 
//  Revision: 1.10 Fri Sep 13 11:49:42 2002 rproudlo
//  debugginginitial debugging
// 
//  Revision: 1.9 Fri Sep 13 09:12:13 2002 rproudlo
//  Added verify tasks
// 
//  Revision: 1.8 Wed Sep 11 03:47:25 2002 bkerr
//  Run DF04 for SF19-SF21
// 
//  Revision: 1.7 Tue Sep 10 09:27:45 2002 bkerr
//  Added call to df04 when running SF18
// 
//  Revision: 1.6 Mon Sep  9 05:02:41 2002 bkerr
//  Pass max_length/num_times parameter to fpga_bfm_tx_df task calls
// 
//  Revision: 1.5 Wed Sep  4 05:51:34 2002 bkerr
//  Removed fpga_bfm_tx.df00 call
//  Added call to check_stats
// 
//  Revision: 1.4 Fri Aug 23 08:05:44 2002 bkerr
//  Commented out Rx path tests as only Tx is currently instantiated
// 
//  Revision: 1.3 Tue Aug 20 12:04:27 2002 bkerr
//  Grouped the FPGA Tx -> LatSPI4 Rx and LatSPI4 Tx -> FPGA Rx tasks
//  together. Forked these two tasks to allow both directions to be
//  tested simulataneously
//
//  Revision: 1.2 Wed Jul 10 11:43:16 2002 bkerr
//  Changed name of df task call as df22 was added
//
//  Revision: 1.1 Tue Jul  9 11:59:12 2002 bkerr
//  Initial creation
//=====================================================================

// Test control - use to control which tests are run
// Comment out `define to prevent test from running
`define DO_TX
`define DO_LS_LB
`define DO_HS_LB
`define DO_RX
`define DO_FPGA_LB

// Comment out to prevent registers & memory from being verified
`define DO_VERIFY

`include "qspi3_define.v"

// ---------------------------------------------------------------------------
// DUT version
// ---------------------------------------------------------------------------
   MPI_Read( 18'h30b28,read_reg );   
   $display("%t: ASB Version: FPSC_ID(30b28)=%h (%b)",$time,read_reg,read_reg); 

   // Dummy write to prime the AHB slave
   MPI_Write( 18'h30b28,read_reg );   
 
// ---------------------------------------------------------------------------
// Read/Write FPGA Registers
// ---------------------------------------------------------------------------

   MPI_Read( 18'h08000,read_reg );   
   $display("%t: Address(08000)=%h (%b)",$time,read_reg,read_reg); 

   MPI_Read( 18'h08001,read_reg );   
   $display("%t: Address(08001)=%h (%b)",$time,read_reg,read_reg);
    
   MPI_Read( 18'h08002,read_reg );   
   $display("%t: Address(08002)=%h (%b)",$time,read_reg,read_reg);
    
   MPI_Read( 18'h08003,read_reg );   
   $display("%t: Address(08003)=%h (%b)",$time,read_reg,read_reg);
    
   MPI_Read( 18'h08004,read_reg );   
   $display("%t: Address(08004)=%h (%b)",$time,read_reg,read_reg);
    
   MPI_Read( 18'h08005,read_reg );   
   $display("%t: Address(08005)=%h (%b)",$time,read_reg,read_reg);
    
   MPI_Read( 18'h08006,read_reg );   
   $display("%t: Address(08006)=%h (%b)",$time,read_reg,read_reg);
    
   MPI_Read( 18'h08007,read_reg );   
   $display("%t: Address(08007)=%h (%b)",$time,read_reg,read_reg);
    
   MPI_Read( 18'h08008,read_reg );   
   $display("%t: Address(08008)=%h (%b)",$time,read_reg,read_reg);
    
   MPI_Write( 18'h08001,8'h3c );   
   MPI_Write( 18'h08003,8'hf0 );   
   MPI_Write( 18'h08004,8'h1e );   
   MPI_Write( 18'h08005,8'h2d );   
   MPI_Write( 18'h08006,8'h4b );   
   MPI_Write( 18'h08007,8'h5a );   

   MPI_Read( 18'h08000,read_reg );   
   $display("%t: Address(08000)=%h (%b)",$time,read_reg,read_reg); 

   MPI_Read( 18'h08001,read_reg );   
   $display("%t: Address(08001)=%h (%b)",$time,read_reg,read_reg);
    
   MPI_Read( 18'h08003,read_reg );   
   $display("%t: Address(08003)=%h (%b)",$time,read_reg,read_reg);
    
   MPI_Read( 18'h08004,read_reg );   
   $display("%t: Address(08004)=%h (%b)",$time,read_reg,read_reg);
    
   MPI_Read( 18'h08005,read_reg );   
   $display("%t: Address(08005)=%h (%b)",$time,read_reg,read_reg);
    
   MPI_Read( 18'h08006,read_reg );   
   $display("%t: Address(08006)=%h (%b)",$time,read_reg,read_reg);
    
   MPI_Read( 18'h08007,read_reg );   
   $display("%t: Address(08007)=%h (%b)",$time,read_reg,read_reg);
    
   MPI_Write( 18'h08004,8'h00 );   

   rx_pe = `BURST_LEN/8;
   rx_pf = (2048/`NUM_FIFO * 0.75)/8;
   tx_pf = (2048/`NUM_FIFO - `BURST_LEN)/8;

   MPI_Write( 18'h08005,rx_pf);   
   MPI_Write( 18'h08006,tx_pf);   
   MPI_Write( 18'h08007,rx_pe);   
    
   MPI_Read( 18'h08004,read_reg );   
   $display("%t: Address(08004)=%h (%b)",$time,read_reg,read_reg);

   MPI_Read( 18'h08005,read_reg );   
   $display("%t: Address(08005)=%h (%b)",$time,read_reg,read_reg);
    
   MPI_Read( 18'h08006,read_reg );   
   $display("%t: Address(08006)=%h (%b)",$time,read_reg,read_reg);
    
   MPI_Read( 18'h08007,read_reg );   
   $display("%t: Address(08007)=%h (%b)",$time,read_reg,read_reg);
    
   MPI_Write( 18'h0800c,8'h00);   
   MPI_Write( 18'h0800d,8'h01);   
   MPI_Write( 18'h0800e,8'h02);   
   MPI_Write( 18'h0800f,8'h03);   
   MPI_Write( 18'h08010,8'h00);   
   MPI_Write( 18'h08011,8'h00);   
   MPI_Write( 18'h08012,8'h01);   
   MPI_Write( 18'h08013,8'h01);   
   MPI_Write( 18'h08014,8'h02);   
   MPI_Write( 18'h08015,8'h02);   
   MPI_Write( 18'h08016,8'h02);   
   MPI_Write( 18'h08017,8'h03);   
   MPI_Write( 18'h08018,8'h03);   
   MPI_Write( 18'h08019,8'h03);   
   MPI_Write( 18'h0801a,8'h03);   
   MPI_Write( 18'h0801b,8'h00);   
// ---------------------------------------------------------------------------
// DUT register configuration
// ---------------------------------------------------------------------------
   $display("%t: DUT register configuration",$time);
   config_regs;

// Additional SPI-4 reset to reset DPRAM control logic
// All MPIF register values will not be affected
   spi4_reset = 1'b1;
   #(100);
   spi4_reset = 1'b0;
   
   $display("%t: DUT memory configuration",$time);
   config_mem;
   
   #1000;

`ifdef DO_VERIFY   
   $display("%t: DUT register verification",$time);
   verify_regs;
   
   $display("%t: DUT memory verification",$time);   
   verify_mem;
   
   #1000;
`endif
   
   $display("%t: DUT register & memory configuration complete",$time);

// ---------------------------------------------------------------------------
// Start-up all the BFMs
// ---------------------------------------------------------------------------
   a_latspi4.tx.idle(10);
   a_latspi4.rx.cal_tx(1'b1,1'b0,1'b0,2'b00);   // start sending the calendar
   wait(a_tdat === 16'h000f);                   // wait for DUT to send IDLE
   a_latspi4.rx.rx(1'b1,1'b0);                  // start-up the Rx data process
//   a_fpga_bfm_tx.start;                         // Start up the Tx FPGA BFM      
//
//   fork   
//      a_fpga_bfm_rx.fpga_bfm_rx32_0.start; 
//      a_fpga_bfm_rx.fpga_bfm_rx32_1.start; 
//      a_fpga_bfm_rx.fpga_bfm_rx32_2.start; 
//      a_fpga_bfm_rx.fpga_bfm_rx32_3.start; 
//      a_fpga_bfm_rx.fpga_bfm_rx64_0.start;
//      a_fpga_bfm_rx.fpga_bfm_rx64_2.start;  
//      a_fpga_bfm_rx.fpga_bfm_rx128_0.start;      
//   join


/* 

// ---------------------------------------------------------------------------
// Transmit
//    FPGA Tx -> LatSPI4 Rx
// ---------------------------------------------------------------------------

`ifdef DO_TX

   $display("%t: *******************************************************",$time);
   $display("%t: ****                     Transmit                  ****",$time);
   $display("%t: ****               FPGA Tx -> LatSPI4 Rx           ****",$time);
   $display("%t: *******************************************************",$time);
   
   #6000;                                      // wait for calendar to synchronise

   if(`SF != "sf18" &&
      `SF != "sf19" &&
      `SF != "sf20" &&
      `SF != "sf21")
   begin
      a_fpga_bfm_tx.df01(400);                 // Do the FPGA data formats
      a_fpga_bfm_tx.df02(400);
      a_fpga_bfm_tx.df03(400);
      a_fpga_bfm_tx.df04(400);
   end

   if(`SF == "sf18" ||
      `SF == "sf19" ||
      `SF == "sf20" ||
      `SF == "sf21")
   begin
      a_latspi4.rx.check_credit = 1'b0;        // Disable credit checking for these tests
      a_fpga_bfm_tx.df05(1000);
   end

   #14000;                                     // Wait for all data to flush out

   check_stats_tx;
   clear_stats;
   
   a_latspi4.rx.check_credit = 1'b1;           // turn on credit checking
  
`endif
   
// ---------------------------------------------------------------------------
// Low-speed loopback
//    FPGA Tx -> FPGA Rx
// ---------------------------------------------------------------------------

`ifdef DO_LS_LB

   $display("%t: *******************************************************",$time);
   $display("%t: ****    Low-speed loopback - FPGA Tx -> FPGA Rx    ****",$time);
   $display("%t: *******************************************************",$time);

   LOOPBACK_LS = 1'b1;
   
   LS_STIO_LB_FERR = {LOOPBACK_FE,
                      LOW_SPEED_DATA_SEL,
                      STATUS_IO_SEL,
	                   LOOPBACK_HS,
		                LOOPBACK_LS,
		                FORCE_DIP4_ERR,
		                FORCE_DIP2_ERR};
                      
   MPI_Write (18'h30915, {1'b0,LS_STIO_LB_FERR});
   MPI_Write (18'h30a15, {1'b0,LS_STIO_LB_FERR});
                                    
   a_latspi4.rx.check_credit = 1'b0;           // turn off credit checking
   if(`SF != "sf18" &&
      `SF != "sf19" &&
      `SF != "sf20" &&
      `SF != "sf21")
   begin
      #30000;                                  // Wait for MPI writes to take effect & calendar to synchronise
      a_fpga_bfm_tx.df01(400);                 // Do the FPGA data formats
      a_fpga_bfm_tx.df02(400);
      a_fpga_bfm_tx.df03(400);
   end

   if(`SF == "sf18" ||
      `SF == "sf19" ||
      `SF == "sf20" ||
      `SF == "sf21")
   begin      
      #50000;                                 // Wait for MPI writes to take effect & calendar to synchroise
      a_latspi4.rx.rx(1'b0,1'b1);             // stop the Rx data process
      a_fpga_bfm_tx.df05(1000);
   end
   
   #30000;                                    // Wait for all data to flush out            

   check_stats_tx;
   clear_stats;
  
   LOOPBACK_LS = 1'b0;
   
   LS_STIO_LB_FERR = {LOOPBACK_FE,
                      LOW_SPEED_DATA_SEL,
                      STATUS_IO_SEL,
	                   LOOPBACK_HS,
		                LOOPBACK_LS,
		                FORCE_DIP4_ERR,
		                FORCE_DIP2_ERR};
                      
   MPI_Write (18'h30915, {1'b0,LS_STIO_LB_FERR});
   MPI_Write (18'h30a15, {1'b0,LS_STIO_LB_FERR});
   
   a_latspi4.rx.check_credit = 1'b1;           // turn on credit checking
   
`endif
  
// ---------------------------------------------------------------------------
// High-speed loopback
//    FPGA Tx -> FPGA Rx
// ---------------------------------------------------------------------------

`ifdef DO_HS_LB

   $display("%t: *******************************************************",$time);
   $display("%t: ****    High-speed loopback - FPGA Tx -> FPGA Rx   ****",$time);
   $display("%t: *******************************************************",$time);

   LOOPBACK_HS = 1'b1;
   
   LS_STIO_LB_FERR = {LOOPBACK_FE,
                      LOW_SPEED_DATA_SEL,
                      STATUS_IO_SEL,
	                   LOOPBACK_HS,
		                LOOPBACK_LS,
		                FORCE_DIP4_ERR,
		                FORCE_DIP2_ERR};
                      
   MPI_Write (18'h30915, {1'b0,LS_STIO_LB_FERR});
   MPI_Write (18'h30a15, {1'b0,LS_STIO_LB_FERR});
                                    
   a_latspi4.rx.check_credit = 1'b0;           // turn off credit checking      
   if(`SF != "sf18" &&
      `SF != "sf19" &&
      `SF != "sf20" &&
      `SF != "sf21")
   begin               
      #30000;                                  // Wait for MPI writes to take effect & calendar to synchronise
      a_fpga_bfm_tx.df01(400);                 // Do the FPGA data formats
      a_fpga_bfm_tx.df02(400);
      a_fpga_bfm_tx.df03(400);
   end

   if(`SF == "sf18" ||
      `SF == "sf19" ||
      `SF == "sf20" ||
      `SF == "sf21")
   begin
      #50000;                                 // Wait for MPI writes to take effect & calendar to synchronise
      a_latspi4.rx.rx(1'b0,1'b1);             // stop the Rx data process
      a_fpga_bfm_tx.df05(1000);
   end

   #30000;                                     // Wait for all data to flush out            

   check_stats_tx;
   clear_stats;
  
   LOOPBACK_HS = 1'b0;
   
   LS_STIO_LB_FERR = {LOOPBACK_FE,
                      LOW_SPEED_DATA_SEL,
                      STATUS_IO_SEL,
	                   LOOPBACK_HS,
		                LOOPBACK_LS,
		                FORCE_DIP4_ERR,
		                FORCE_DIP2_ERR};
                      
   MPI_Write (18'h30915, {1'b0,LS_STIO_LB_FERR});
   MPI_Write (18'h30a15, {1'b0,LS_STIO_LB_FERR});
  
   a_latspi4.rx.check_credit = 1'b1;           // turn on credit checking
 
`endif

// ---------------------------------------------------------------------------
// Receive
//    LatSPI4 Tx -> FPGA Rx  
// ---------------------------------------------------------------------------

`ifdef DO_RX

   // Don't do Rx test for 18,19,20 or 21
   if(`SF != "sf18" &&
      `SF != "sf19" &&
      `SF != "sf20" &&
      `SF != "sf21")
      begin
         $display("%t: *******************************************************",$time);
         $display("%t: ****                     Receive                   ****",$time);
         $display("%t: ****             LatSPI4 Tx -> FPGA BFM Rx         ****",$time);
         $display("%t: *******************************************************",$time);

         wait(a_rstat == 2'b11);                      // wait for SYNC before starting to receive calendar 
         a_latspi4.tx.cal_rx(1'b1,1'b0);              // start up the Rx calendar process

         #10000;                                        // wait for calendar synchronisation
         a_latspi4.df.df00(16,1);                      // transmit the Data Formats
         a_latspi4.df.df01_df22(16,0);                 // transmit the Data Formats

         a_latspi4.df.df00(64,0);                      // transmit the Data Formats
         a_latspi4.df.df01_df22(64,0);                 // transmit the Data Formats

         #16000;                                                                              

         check_stats_rx;
         clear_stats;
      end

`endif

*/
  
// ---------------------------------------------------------------------------
// FPGA loopback
//    LatSPI Tx -> LatSPI Rx
// ---------------------------------------------------------------------------

`ifdef DO_FPGA_LB

   // Don't do FPGA loopback test for 18,19,20 or 21
   if(`SF != "sf18" &&
      `SF != "sf19" &&
      `SF != "sf20" &&
      `SF != "sf21")
      begin
         $display("%t: ******************************************************",$time);
         $display("%t: ****    FPGA loopback - LatSPI Tx -> LatSPI Rx   ****",$time);
         $display("%t: ******************************************************",$time);

         FPGA_LB   = 1'b1;

         wait(a_rstat == 2'b11);                      // wait for SYNC before starting to receive calendar 
         a_latspi4.tx.cal_rx(1'b1,1'b0);              // start up the Rx calendar process

         #10000;                                        
         a_latspi4.df.df00(16,1);                        
         a_latspi4.df.df01_df22(16,0);

         a_latspi4.df.df00(64,0);                        
         a_latspi4.df.df01_df22(64,0);

         #16000; 

         check_stats_rx;
         
         FPGA_LB   = 1'b0;
      end

`endif
///////////////////////////////////////////////////////////////////////
// >>>>>>>>>>>>>>>>>>>>>>>>> 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             :       footer.v
// Author               :       Ben_Kerr,bkerr@latticesemi.com
// Created on           :       Tuesday July 09 2002 (WW27)
// Last Modified By     :       $Author: bkerr $
// Last Modified On     :       $Date: Tue Oct 22 07:35:05 2002 $ 
// Revision             :       $Revision: 1.19 $
// Status               :       Development
// Dependencies         :       reg_desc.v, addr_params.v
//=====================================================================

//=====================================================================
// Description          :
//=====================================================================
// Footer file used at the bottom of the automatically created toptest.v
//
// After running the simany_ph1 script, toptest.v is created
// This file is built from the following files:
//
//   +-----------------------------------+
//   | `defines generated by script      |  Time of day, user information & configuration feedback
//   +-----------------------------------+
//   |                                   |  top level module statement, global variables
//   |             header.v              |  module instantiations, clock & reset generation
//   |                                   |  initial ....
//   +-----------------------------------+
//   |                                   |    DUT register settings (configuration specific)
//   |     SFnn - from command line      |
//   |                                   |
//   +-----------------------------------+
//   |                                   |    DUT memory configurations (configuration specific)
//   |     Mnn - from command line       |
//   |                                   |
//   +-----------------------------------+
//   |                                   |    Task calls to configure DUT
//   |             body.v                |    Task calls to enable checkers
//   |                                   |    Task calls to perform data format tests
//   +-----------------------------------+
//   |                                   |    Report pass/fail
//   |       footer.v (this file)        |    `include common tasks
//   |                                   |  endmodule
//   +-----------------------------------+
//
//
//=====================================================================

//=====================================================================
// Revision History
//=====================================================================
// $Log: footer.v.rca $
// 
//  Revision: 1.19 Tue Oct 22 07:35:05 2002 bkerr
//  Changed clear_stats task to clear rx_fpga_bfm Rx eop counters that were missed
// 
//  Revision: 1.18 Tue Oct 15 11:35:46 2002 rproudlo
//  Reversed SPI4_CORE Associated Registers
// 
//  Revision: 1.17 Tue Oct  1 07:39:06 2002 bkerr
//  Corrected typo in ISR $display
// 
//  Revision: 1.16 Tue Oct  1 04:02:14 2002 bkerr
//  Enhanced ISR to provide full decode of interrupt registers
// 
//  Revision: 1.15 Thu Sep 26 06:21:47 2002 rproudlo
//  Added very basic ISR
// 
//  Revision: 1.14 Thu Sep 26 05:44:49 2002 bkerr
//  Added clear_stat task to clear all SPO and EOP counters
// 
//  Revision: 1.13 Wed Sep 25 11:04:35 2002 bkerr
//  Altered check_stats task to verify correct counters when performing
//  high-speed loopback
// 
//  Revision: 1.12 Tue Sep 24 08:11:52 2002 rproudlo
//  Modified check_stats_rx for FPGA_LB mode
// 
//  Revision: 1.11 Mon Sep 23 12:36:28 2002 rproudlo
//  Modified check_stats_rx for loopback
// 
//  Revision: 1.10 Tue Sep 17 12:32:18 2002 rproudlo
//  Added check_stats_rx task
// 
//  Revision: 1.9 Mon Sep 16 05:13:52 2002 bkerr
//  Added Write_Norm and Read_Norm tasks as memory read and writes
//  do not require "bit-flipping"
// 
//  Revision: 1.8 Fri Sep 13 10:31:04 2002 bkerr
//  Added "bit-flipper" to move bit[7]MSB to the bit[0] position
//  as all the registers are specified LSB-MSB, but the bmaster is
//  writing MSB-LSB
// 
//  Revision: 1.7 Fri Sep 13 09:43:30 2002 bkerr
//  Debugging MPI_Read task
// 
//  Revision: 1.6 Fri Sep 13 08:25:31 2002 rproudlo
//  Added 'include "verify_task.v"
// 
//  Revision: 1.5 Fri Sep 13 05:40:07 2002 bkerr
//  Updated MPI_Write and MPI_Read tasks to call singe_read and
//  single_write tasks in AHB bmaster
// 
//  Revision: 1.4 Wed Sep  4 05:45:22 2002 bkerr
//  Added check_stats task to verify correct number of SOPs and EOPs
//  were received
// 
//  Revision: 1.3 Fri Aug 23 08:10:42 2002 bkerr
//  Commented out bmaster task calls as the bmaster is no longer present
//  They are kept in as the bmaster will return when the orspii_asb
//  is updated and access to the MPIF is possible.
// 
//  Revision: 1.2 Tue Aug 20 12:00:42 2002 bkerr
//  Added MPI_Write and MPI_Read wrapper tasks to call read & write tasks
//  in the AHB bus master model instantiated in top.v
// 
//  Revision: 1.1 Tue Jul  9 11:59:12 2002 bkerr
//  Initial creation
//=====================================================================

// ---------------------------------------------------------------------------
// Report PASS/FAIL  
// ---------------------------------------------------------------------------

   if(error_count == 0)
   begin
      $display("%t: *******************************************************",$time);
      $display("%t: ****               T E S T   P A S S E D",$time);
      $display("%t: *******************************************************",$time);
   end
   else
   begin
      $display("%t: *******************************************************",$time);
      $display("%t: ****               T E S T   F A I L E D",$time);
      $display("%t: ****        Number of errors:%0d",$time,error_count);
      $display("%t: *******************************************************",$time);
   end
   
// ---------------------------------------------------------------------------
// Simulation termination 
// ---------------------------------------------------------------------------
   if($test$plusargs("STOP"))
      $stop(2);
   else
      $finish(2);

end // initial - begin in header.v
  

// ---------------------------------------------------------------------------
// Interrupt Service Routine
// ---------------------------------------------------------------------------  
always @(posedge ASB_IRQ_SLI)
begin : ISR
  
    reg [7:0]  csr_30b29;
    reg [7:0]  csr_30b2a;
    reg [7:0]  status_reg;
    reg [7:0]  count_reg;
    reg [17:0] int_addr;
    integer    i;
      
    if (test_go == 1'b1)
    begin
      $display("%t: *******************************************************",$time);
      $display("%t: ****        ASB_IRQ_SLI Interrupt positive edge",$time);
      $display("%t: *******************************************************",$time);
      
      MPI_Read  (18'h30b29, csr_30b29);
      $display("%t: Status Register 1 (%h) read %b", $time,18'h30b29,csr_30b29);
                        
      if(csr_30b29[0])
      begin
         $display("%t: \tSPI_A_COR2_INT",$time);
         MPI_Read (18'h3091c, status_reg);
         $display("%t: \t\tSPI4 A Status Register 2 (%h) read %b", $time,18'h3091c,status_reg);
         if(status_reg[0])
            $display("%t: \t\t\tTX_STATUS_LOF_STS_A",$time);
         if(status_reg[1])
            $display("%t: \t\t\tALGN_OFF_STS_A",$time);
         if(status_reg[2])
            $display("%t: \t\t\tRDI_TRN_DET_STS_A",$time);
         if(status_reg[3])
            $display("%t: \t\t\tRDI_DSKW_ERR_STS_A",$time);
         if(status_reg[4])
            $display("%t: \t\t\tRDI_DSKW_DONE_STS_A",$time);
         if(status_reg[5])
            $display("%t: \t\t\tRDI_BAS_ERR_STS_A",$time);
         if(status_reg[6])
            $display("%t: \t\t\tRDI_BAS_DONE_STS_A",$time);
         if(status_reg[7])
            $display("%t: \t\t\tRDI_PLL_LOL_STS_A",$time);
      end
 
       if(csr_30b29[1])
      begin     
         $display("%t: \tSPI_A_COR1_INT",$time);
         MPI_Read (18'h3091d, status_reg);
         $display("%t: \t\tSPI4 A Status Register 1 (%h) read %b", $time,18'h3091d,status_reg);
         if(status_reg[0])
            $display("%t: \t\t\tASYNC_FIFO_RX_OVERRUN_STS_A",$time);
         if(status_reg[1])
            $display("%t: \t\t\tDIP2_ERR_STS_A",$time);
         if(status_reg[2])
	   begin
             $display("%t: \t\t\tDIP4_ERR_STS_A",$time);
//	       MPI_Read (18'h3090a, count_reg);
//               $display("%t: \t\tSPI4 A DIP4_ERR_CNT (%h) read %d", $time,18'h3090a,count_reg);
	   end 
         if(status_reg[3])
            $display("%t: \t\t\tTX_SOP_ALIGN_ERR_STS_A",$time);
         if(status_reg[4])
            $display("%t: \t\t\tRX_SOP_ALIGN_ERR_STS_A",$time);
      end
                                   
      if(csr_30b29[2])
      begin
         $display("%t: \tSPI_B_COR2_INT",$time);
         MPI_Read (18'h30a1c, status_reg);
         $display("%t: \t\tSPI4 B Status Register 2 (%h) read %b", $time,18'h30a1c,status_reg);
         if(status_reg[0])
            $display("%t: \t\t\tTX_STATUS_LOF_STS_B",$time);
         if(status_reg[1])
            $display("%t: \t\t\tALGN_OFF_STS_B",$time);
         if(status_reg[2])
            $display("%t: \t\t\tRDI_TRN_DET_STS_B",$time);
         if(status_reg[3])
            $display("%t: \t\t\tRDI_DSKW_ERR_STS_B",$time);
         if(status_reg[4])
            $display("%t: \t\t\tRDI_DSKW_DONE_STS_B",$time);
         if(status_reg[5])
            $display("%t: \t\t\tRDI_BAS_ERR_STS_B",$time);
         if(status_reg[6])
            $display("%t: \t\t\tRDI_BAS_DONE_STS_B",$time);
         if(status_reg[7])
            $display("%t: \t\t\tRDI_PLL_LOL_STS_B",$time);
      end

      if(csr_30b29[3])
      begin     
         $display("%t: \tSPI_B_COR1_INT",$time);
         MPI_Read (18'h30a1d, status_reg);
         $display("%t: \t\tSPI4 B Status Register 1 (%h) read %b", $time,18'h30a1d,status_reg);
         if(status_reg[0])
            $display("%t: \t\t\tASYNC_FIFO_RX_OVERRUN_STS_B",$time);
         if(status_reg[1])
            $display("%t: \t\t\tDIP2_ERR_STS_B",$time);
         if(status_reg[2])
            $display("%t: \t\t\tDIP4_ERR_STS_B",$time);
         if(status_reg[3])
            $display("%t: \t\t\tTX_SOP_ALIGN_ERR_STS_B",$time);
         if(status_reg[4])
            $display("%t: \t\t\tRX_SOP_ALIGN_ERR_STS_B",$time);
      end
 
      if(csr_30b29[4])
      begin
         $display("%t: \tDPRAM_INT",$time);
         MPI_Read (18'h30b2a, csr_30b2a);
         $display("%t: \tStatus Register 2 (%h) read %b", $time,18'h30b2a,csr_30b2a);
         
         if(csr_30b2a[7])
         begin
            $display("%t: \t\tTX_INT_B",$time);
            int_addr = 18'h30a28;
         end
         if(csr_30b2a[6])
         begin
            $display("%t: \t\tRX_INT_B",$time);
            int_addr = 18'h30a0c;
         end
         if(csr_30b2a[5])
         begin
            $display("%t: \t\tTX_INT_A",$time);
            int_addr = 18'h30928;
         end
         if(csr_30b2a[4])
         begin
            $display("%t: \t\tRX_INT_A",$time);
            int_addr = 18'h3090c;
         end
         
         if(csr_30b2a[3])
         begin
            $display("%t: \t\tBANK_3_INT",$time);
            int_addr = int_addr + 18'h00003;
            MPI_Read(int_addr, status_reg);
            $display("%t: \t\t\tOVERRUN_STS @ %h read %b",$time,int_addr,status_reg);
            for(i=0;i<8;i=i+1)
            begin
               if(status_reg[i])
                  $display("%t: \t\t\t\tOVERRUN_STS[%0d]",$time,i);
            end
                  
            int_addr = int_addr + 18'h00004;
            $display("%t: \t\t\tURRUN_STS @ %h read %b",$time,int_addr,status_reg);
            for(i=0;i<8;i=i+1)
            begin
               if(status_reg[i])
                  $display("%t: \t\t\t\tURRUN_STS[%0d]",$time,i);
            end
         end
         
         if(csr_30b2a[2])
         begin
            $display("%t: \t\tBANK_2_INT",$time);
            int_addr = int_addr + 18'h00002;
            MPI_Read(int_addr, status_reg);
            $display("%t: \t\t\tOVERRUN_STS @ %h read %b",$time,int_addr,status_reg);
            for(i=0;i<8;i=i+1)
            begin
               if(status_reg[i])
                  $display("%t: \t\t\t\tOVERRUN_STS[%0d]",$time,i);
            end
                  
            int_addr = int_addr + 18'h00004;
            $display("%t: \t\t\tURRUN_STS @ %h read %b",$time,int_addr,status_reg);
            for(i=0;i<8;i=i+1)
            begin
               if(status_reg[i])
                  $display("%t: \t\t\t\tURRUN_STS[%0d]",$time,i);
            end
         end
         
         if(csr_30b2a[1])
         begin
            $display("%t: \t\tBANK_1_INT",$time);
            int_addr = int_addr + 18'h00001;
            MPI_Read(int_addr, status_reg);
            $display("%t: \t\t\tOVERRUN_STS @ %h read %b",$time,int_addr,status_reg);
            for(i=0;i<8;i=i+1)
            begin
               if(status_reg[i])
                  $display("%t: \t\t\t\tOVERRUN_STS[%0d]",$time,i);
            end
                  
            int_addr = int_addr + 18'h00004;
            $display("%t: \t\t\tURRUN_STS @ %h read %b",$time,int_addr,status_reg);
            for(i=0;i<8;i=i+1)
            begin
               if(status_reg[i])
                  $display("%t: \t\t\t\tURRUN_STS[%0d]",$time,i);
            end
         end
         
         if(csr_30b2a[0])
         begin
            $display("%t: \t\tBANK_0_INT",$time);
            int_addr = int_addr + 18'h00000;
            MPI_Read(int_addr, status_reg);
            $display("%t: \t\t\tOVERRUN_STS @ %h read %b",$time,int_addr,status_reg);
            for(i=0;i<8;i=i+1)
            begin
               if(status_reg[i])
                  $display("%t: \t\t\t\tOVERRUN_STS[%0d]",$time,i);
            end
                  
            int_addr = int_addr + 18'h00004;
            $display("%t: \t\t\tURRUN_STS @ %h read %b",$time,int_addr,status_reg);
            for(i=0;i<8;i=i+1)
            begin
               if(status_reg[i])
                  $display("%t: \t\t\t\tURRUN_STS[%0d]",$time,i);
            end
         end         
      end
         
      if(csr_30b29[5])
      begin
         $display("%t: \tMEM_CTRL1_INT",$time);
         MPI_Read (18'h30b09, status_reg);
         $display("%t: \t\tMemory Controller Status Register 1 (%h) read %b", $time,18'h30b09,status_reg);
         if(status_reg[0])
            $display("%t: \t\t\tMC_ID_ERR_STS",$time);
      end
         
      if(csr_30b29[6])
      begin
         $display("%t: \tMEM_CTRL2_INT",$time);
         MPI_Read (18'h30b08, status_reg);
         $display("%t: \t\tMemory Controller Status Register 2 (%h) read %b", $time,18'h30b08,status_reg);
         if(status_reg[0])
            $display("%t: \t\t\tMC_WR_DFIFO_OVERRUN_STS",$time);
         if(status_reg[1])
            $display("%t: \t\t\tMC_WR_IFIFO_OVERRUN_STS",$time);
         if(status_reg[2])
            $display("%t: \t\t\tMC_RD_IFIFO_OVERRUN_STS",$time);
         if(status_reg[3])
            $display("%t: \t\t\tMC_RD_DFIFO_OVERRUN_STS",$time);
         if(status_reg[4])
            $display("%t: \t\t\tMC_WR_DFIFO_URRUN_STS",$time);
         if(status_reg[5])
            $display("%t: \t\t\tMC_WR_IFIFO_URRUN_STS",$time);
         if(status_reg[6])
            $display("%t: \t\t\tMC_RD_IFIFO_URRUN_STS",$time);
         if(status_reg[7])
            $display("%t: \t\t\tMC_RD_DFIFO_URRUN_STS",$time);
      end
         
      if(csr_30b29[7])
         $display("%t: \tSERDES_INT",$time);                                       

      $display("%t: *******************************************************",$time);
         
   end // if(test_go...)
end // always
    
//
// Common Tasks
//

`include "config_task.v"
`include "verify_task.v"

// Bit flipped write (for registers)
task MPI_Write;
input [17:0]   address;
input [ 7:0]   data;
reg            ret_status;
begin
bmaster.single_write(address,3'b000,{data[0],data[1],data[2],data[3],data[4],data[5],data[6],data[7]},ret_status);
end
endtask

// Non bit flipped write (for memories)
task MPI_Write_Norm;
input [17:0]   address;
input [ 7:0]   data;
reg            ret_status;
begin
bmaster.single_write(address,3'b000,data,ret_status);
end
endtask

// Bit-flipped read (for registers)
task MPI_Read;
input  [17:0]  address;
output [ 7:0]  data;
reg            ret_status;
reg   [35:0]   read_data;
begin
bmaster.single_read(address,3'b000,read_data,ret_status);
data[7] = read_data[0];
data[6] = read_data[1];
data[5] = read_data[2];
data[4] = read_data[3];
data[3] = read_data[4];
data[2] = read_data[5];
data[1] = read_data[6];
data[0] = read_data[7];   
end
endtask

// Non bit-flipped read (for memories)
task MPI_Read_Norm;
input  [17:0]  address;
output [ 7:0]  data;
reg            ret_status;
reg   [35:0]   read_data;
begin
bmaster.single_read(address,3'b000,read_data,ret_status);
data = read_data[7:0];
end
endtask


task check_stats_tx;
integer i;
integer sop_count_rx;
integer eop_count_rx;
begin
   $display("%t: *******************************************************",$time);
   $display("%t: ****            Port SOP and EOP counters",$time);
   $display("%t: *******************************************************",$time);
   $display("%t: Port   Tx SOP    Tx EOP      Rx SOP   Rx EOP",$time);
         
   for(i=0;i<TX_PDM_ACTIVE_PORTS;i=i+1)
   begin
      if(LOOPBACK_HS || LOOPBACK_LS)
      begin
//         sop_count_rx = a_fpga_bfm_rx.fpga_bfm_rx32_0.rx_sop_count[TX_PDM_PORT_ID[i]] +
//                        a_fpga_bfm_rx.fpga_bfm_rx32_1.rx_sop_count[TX_PDM_PORT_ID[i]] +
//				            a_fpga_bfm_rx.fpga_bfm_rx32_2.rx_sop_count[TX_PDM_PORT_ID[i]] +
//				            a_fpga_bfm_rx.fpga_bfm_rx32_3.rx_sop_count[TX_PDM_PORT_ID[i]] +
//				            a_fpga_bfm_rx.fpga_bfm_rx64_0.rx_sop_count[TX_PDM_PORT_ID[i]] +
//				            a_fpga_bfm_rx.fpga_bfm_rx64_2.rx_sop_count[TX_PDM_PORT_ID[i]] +
//				            a_fpga_bfm_rx.fpga_bfm_rx128_0.rx_sop_count[TX_PDM_PORT_ID[i]];
//         eop_count_rx = a_fpga_bfm_rx.fpga_bfm_rx32_0.rx_eop_count[TX_PDM_PORT_ID[i]] +
//                        a_fpga_bfm_rx.fpga_bfm_rx32_1.rx_eop_count[TX_PDM_PORT_ID[i]] +
//				            a_fpga_bfm_rx.fpga_bfm_rx32_2.rx_eop_count[TX_PDM_PORT_ID[i]] +
//				            a_fpga_bfm_rx.fpga_bfm_rx32_3.rx_eop_count[TX_PDM_PORT_ID[i]] +
//				            a_fpga_bfm_rx.fpga_bfm_rx64_0.rx_eop_count[TX_PDM_PORT_ID[i]] +
//				            a_fpga_bfm_rx.fpga_bfm_rx64_2.rx_eop_count[TX_PDM_PORT_ID[i]] +
//				            a_fpga_bfm_rx.fpga_bfm_rx128_0.rx_sop_count[TX_PDM_PORT_ID[i]];
      end
      else
      begin
         sop_count_rx = a_latspi4.rx_sop_count[TX_PDM_PORT_ID[i]];
         eop_count_rx = a_latspi4.rx_eop_count[TX_PDM_PORT_ID[i]];
      end
   
//      $display("%t: [%0d]    %0d        %0d          %0d       %0d",
//            $time,
//            TX_PDM_PORT_ID[i],
//            a_fpga_bfm_tx.tx_sop_count[TX_PDM_PORT_ID[i]],
//            a_fpga_bfm_tx.tx_eop_count[TX_PDM_PORT_ID[i]],
//            sop_count_rx,
//            eop_count_rx);
            
//      if(a_fpga_bfm_tx.tx_sop_count[TX_PDM_PORT_ID[i]] != sop_count_rx)
//      begin
//         $display("%t: ERROR: Incorrect number of SOPs received for port [%0d]",$time,TX_PDM_PORT_ID[i]);
//         error_count = error_count + 1;
//      end
//      if(a_fpga_bfm_tx.tx_eop_count[TX_PDM_PORT_ID[i]] != eop_count_rx)
//      begin
//         $display("%t: ERROR: Incorrect number of EOPs received for port [%0d]",$time,TX_PDM_PORT_ID[i]);
//         error_count = error_count + 1;
//      end      
   end
   
   $display("%t: *******************************************************",$time);
end
endtask
        

task check_stats_rx;
integer i;

reg [15:0] a_fpga_bfm_rx_sop_count [0:255];
reg [15:0] a_fpga_bfm_rx_eop_count [0:255];

begin
   $display("%t: *******************************************************",$time);
   $display("%t: ****            Port SOP and EOP counters          ****",$time);
   $display("%t: *******************************************************",$time);
   $display("%t:       LATSPI    LATSPI        FPGA       FPGA         LATSPI     LATSPI",$time);
   $display("%t: Port  Tx SOP    Tx EOP       Rx SOP     Rx EOP        Rx SOP     Rx EOP",$time);

//for (i=0;i<=255;i=i+1)
//  begin   
//    a_fpga_bfm_rx_sop_count[i] = (a_fpga_bfm_rx.fpga_bfm_rx32_0.rx_sop_count[i] +
//                                  a_fpga_bfm_rx.fpga_bfm_rx32_1.rx_sop_count[i] +
//				  a_fpga_bfm_rx.fpga_bfm_rx32_2.rx_sop_count[i] +
//				  a_fpga_bfm_rx.fpga_bfm_rx32_3.rx_sop_count[i] +
//				  a_fpga_bfm_rx.fpga_bfm_rx64_0.rx_sop_count[i] +
//				  a_fpga_bfm_rx.fpga_bfm_rx64_2.rx_sop_count[i] +
//				  a_fpga_bfm_rx.fpga_bfm_rx128_0.rx_sop_count[i]);
//  end
//
//for (i=0;i<=255;i=i+1)
//  begin   
//    a_fpga_bfm_rx_eop_count[i] = (a_fpga_bfm_rx.fpga_bfm_rx32_0.rx_eop_count[i] +
//                                  a_fpga_bfm_rx.fpga_bfm_rx32_1.rx_eop_count[i] +
//				  a_fpga_bfm_rx.fpga_bfm_rx32_2.rx_eop_count[i] +
//				  a_fpga_bfm_rx.fpga_bfm_rx32_3.rx_eop_count[i] +
//				  a_fpga_bfm_rx.fpga_bfm_rx64_0.rx_eop_count[i] +
//				  a_fpga_bfm_rx.fpga_bfm_rx64_2.rx_eop_count[i] +
//				  a_fpga_bfm_rx.fpga_bfm_rx128_0.rx_eop_count[i]);
//  end
    
   for(i=0;i<RX_PDM_ACTIVE_PORTS;i=i+1)
   begin
      $display("%t: [%0d]    %0d        %0d          %0d       %0d          %0d       %0d",
            $time,
            RX_PDM_ACTIVE_PORT_ID[i],
            a_latspi4.tx_sop_count[RX_PDM_ACTIVE_PORT_ID[i]],
            a_latspi4.tx_eop_count[RX_PDM_ACTIVE_PORT_ID[i]],
	         a_fpga_bfm_rx_sop_count[RX_PDM_ACTIVE_PORT_ID[i]],
            a_fpga_bfm_rx_eop_count[RX_PDM_ACTIVE_PORT_ID[i]],
	         a_latspi4.rx_sop_count[RX_PDM_ACTIVE_PORT_ID[i]],
            a_latspi4.rx_eop_count[RX_PDM_ACTIVE_PORT_ID[i]]);
            
      if(a_latspi4.tx_sop_count[RX_PDM_ACTIVE_PORT_ID[i]] != a_fpga_bfm_rx_sop_count[RX_PDM_ACTIVE_PORT_ID[i]])
      begin
         $display("%t: ERROR: Incorrect number of SOPs received (FPGA) for port [%0d]",$time,RX_PDM_ACTIVE_PORT_ID[i]);
         error_count = error_count + 1;
      end
      if(a_latspi4.tx_eop_count[RX_PDM_ACTIVE_PORT_ID[i]] != a_fpga_bfm_rx_eop_count[RX_PDM_ACTIVE_PORT_ID[i]])
      begin
         $display("%t: ERROR: Incorrect number of EOPs received (FPGA) for port [%0d]",$time,RX_PDM_ACTIVE_PORT_ID[i]);
         error_count = error_count + 1;
      end

  if (FPGA_LB == 1'b1)
    begin
      if(a_latspi4.tx_sop_count[RX_PDM_ACTIVE_PORT_ID[i]] != a_latspi4.rx_sop_count[RX_PDM_ACTIVE_PORT_ID[i]])
      begin
         $display("%t: ERROR: Incorrect number of SOPs received (LATSPI) for port [%0d]",$time,RX_PDM_ACTIVE_PORT_ID[i]);
         error_count = error_count + 1;
      end
      if(a_latspi4.tx_eop_count[RX_PDM_ACTIVE_PORT_ID[i]] != a_latspi4.rx_eop_count[RX_PDM_ACTIVE_PORT_ID[i]])
      begin
         $display("%t: ERROR: Incorrect number of EOPs received (LATSPI) for port [%0d]",$time,RX_PDM_ACTIVE_PORT_ID[i]);
         error_count = error_count + 1;
      end
    end
      
   end
   
   $display("%t: *******************************************************",$time);
   
end
endtask
	    
task clear_stats;
integer i;
begin
   for(i=0;i<256;i=i+1)
   begin
   
   // LatSPI4
      a_latspi4.tx_sop_count[i] = 0;            
      a_latspi4.tx_eop_count[i] = 0;            
      a_latspi4.rx_sop_count[i] = 0;            
      a_latspi4.rx_eop_count[i] = 0;            

//   // FPGA BFM Tx
//      a_fpga_bfm_tx.tx_sop_count[i] = 0;
//      a_fpga_bfm_tx.tx_eop_count[i] = 0;
//      
//   // FPGA BFM Rx      
//      a_fpga_bfm_rx.fpga_bfm_rx32_0.rx_sop_count[i] = 0;
//      a_fpga_bfm_rx.fpga_bfm_rx32_1.rx_sop_count[i] = 0;
//      a_fpga_bfm_rx.fpga_bfm_rx32_2.rx_sop_count[i] = 0;
//      a_fpga_bfm_rx.fpga_bfm_rx32_3.rx_sop_count[i] = 0;
//      a_fpga_bfm_rx.fpga_bfm_rx64_0.rx_sop_count[i] = 0;
//      a_fpga_bfm_rx.fpga_bfm_rx64_2.rx_sop_count[i] = 0;
//      a_fpga_bfm_rx.fpga_bfm_rx128_0.rx_sop_count[i]= 0;
//      
//      a_fpga_bfm_rx.fpga_bfm_rx32_0.rx_eop_count[i] = 0;
//      a_fpga_bfm_rx.fpga_bfm_rx32_1.rx_eop_count[i] = 0;
//      a_fpga_bfm_rx.fpga_bfm_rx32_2.rx_eop_count[i] = 0;
//      a_fpga_bfm_rx.fpga_bfm_rx32_3.rx_eop_count[i] = 0;
//      a_fpga_bfm_rx.fpga_bfm_rx64_0.rx_eop_count[i] = 0;
//      a_fpga_bfm_rx.fpga_bfm_rx64_2.rx_eop_count[i] = 0;
//      a_fpga_bfm_rx.fpga_bfm_rx128_0.rx_eop_count[i]= 0;      
   end
   
   $display("%t: Cleared all SOP & EOP Counters",$time);
end
endtask                         

endmodule
