---------------------------------------------------------------------------
-- NDT Solutions Ltd. Proprietary Information
-- Company Confidential
-- Copyright 2007
--
-- Filename: NDTS2100Tb.vhd
-- Language: VHDL '93
-- Project:  NDTS2100
--
-- Design Description:
-- Board level Testbench
---------------------------------------------------------------------------

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;

use std.textio.all;

library work;
use work.LocalBusModelPkg.all;
use work.AdcModelPkg.all;

entity NDTS2100Tb is
end NDTS2100Tb;

architecture TestBench of NDTS2100Tb is

  component LocalBusModel is
    port (-- Control signals to/from main simulation module
          ToBusModel   : in  tToBusModel;
          FromBusModel : out tFromBusModel;
          -- Bus Signals
          nLRESET      : out   std_ulogic;
          LCLKA        : out   std_ulogic;
          LWnR         : out   std_logic;
          nADS         : inout std_logic;
          nBLAST       : inout std_logic;
          nREADY       : inout std_logic;
          LA           : inout std_logic_vector(31 downto 0);
          LD           : inout std_logic_vector(31 downto 0);
          LHOLD        : out   std_ulogic;
          LHOLDA       : in    std_ulogic;
          nBTERM       : inout std_logic;
          nCCS         : in    std_ulogic;
          BREQi        : in    std_ulogic;
          nLINTi       : in    std_ulogic);
  end component LocalBusModel;

  component SimCtrl
    port (ToBusModel    : out tToBusModel;
          FromBusModel  : in  tFromBusModel;
--          ToAdcModel    : out tToAdcModel;
--          FromAdcModel  : in tFromAdcModel;
          ToSysMonAdc   : out tSysMon;
          ToSysMonTemp  : out integer range -35 to +85;
          SysMonD       : in  std_logic_vector(4 downto 0);
          SysMonOK      : in  std_ulogic;
          DspShiftData  : in  std_logic_vector(39 downto 0);
          FSel          : in  std_logic_vector(3 downto 0);
          HvAdj         : in  integer range 0 to 4095;
          HvEn          : in  std_ulogic;
          HVDischarge   : in  std_ulogic;
          HVFeedback    : out std_ulogic);
  end component;

  component SystemFpgaTop
    port (-- Local bus
          nLRESET    : in    std_ulogic;
          LCLKA      : in    std_ulogic;
          LCLKB      : in    std_ulogic;
          LWnR       : inout std_logic;
          LD         : inout std_logic_vector(31 downto 0);
          DP         : inout std_logic_vector(3 downto 0);
          LA         : inout std_logic_vector(31 downto 2);
          nADS       : inout std_logic;
          nBLAST     : inout std_logic;
          nREADY     : inout std_logic;
          nWAIT      : inout std_logic;
          nBTERM     : inout std_logic;
          nLBE       : inout std_logic_vector(3 downto 0);
          BREQi      : inout std_ulogic;
          BREQo      : in    std_ulogic;
          nDREQ0     : out   std_ulogic;
          nDREQ1     : out   std_ulogic;
          nDACK0     : in    std_ulogic;
          nDACK1     : in    std_ulogic;
          nLINTi     : out   std_ulogic;
          nLINTo     : in    std_ulogic;
          nLSERR     : in    std_ulogic;
          nBIGEND    : out   std_ulogic;
          LHOLD      : in    std_ulogic;
          LHOLDA     : inout std_ulogic;
          USERi      : out   std_ulogic;
          USERo      : in    std_ulogic;
          nEOT       : in    std_ulogic;
          nCCS       : out   std_ulogic;
          nPMEIN     : out   std_ulogic;
          GPIO       : inout std_logic_vector(3 downto 0);
          -- DSP FPGA connections
          DspCClk    : out   std_ulogic;
          DspDone    : in    std_ulogic;
          nDspProg   : out   std_ulogic;
          DspDIn     : out   std_ulogic;
          nDspInit   : in    std_ulogic;
          -- EEPROM connections
          EEClk      : out   std_ulogic;
          EEOut      : in    std_ulogic;
          EEIn       : out   std_ulogic;
          nEECs      : out   std_ulogic;
          -- System Monitor
          nSysMonCs  : out   std_logic_vector(2 downto 0);
          SysMonSClk : out   std_ulogic;
          SysMonDIn  : out   std_ulogic;
          SysMonDOut : in    std_logic;
          TempSnsCe  : out   std_ulogic;
          TempSnsSClk: out   std_ulogic;
          TempSnsSDo : in    std_ulogic;
          SysMonD    : out   std_logic_vector(4 downto 0);
          SysMonOK   : out   std_ulogic;
          -- Misc IO
          SysLED     : out   std_ulogic;
          DbugD      : inout std_logic_vector(15 downto 8);
          BuzzP      : out   std_logic_vector(11 downto 0);
          BuzzN      : out   std_logic_vector(11 downto 0));
  end component;

  component ADC128C022
    port (SClk : in  std_ulogic;
          nCs  : in  std_ulogic;
          DIn  : in  std_ulogic;
          DOut : out std_logic;
          -- Testbench interface signals
          In0  : in  integer range 0 to 4095;
          In1  : in  integer range 0 to 4095;
          In2  : in  integer range 0 to 4095;
          In3  : in  integer range 0 to 4095;
          In4  : in  integer range 0 to 4095;
          In5  : in  integer range 0 to 4095;
          In6  : in  integer range 0 to 4095;
          In7  : in  integer range 0 to 4095);
  end component;

  component AD7314
    port (SClk : in  std_ulogic;
          Ce   : in  std_ulogic;
          Sdi  : in  std_ulogic;
          Sdo  : out std_ulogic;
          -- Testbench interface signals
          Temp : in  integer range -35 to +85); -- temperature in deg C
  end component;

  component HC595
    port (SH_CP : in  std_ulogic;
          ST_CP : in  std_ulogic;
          nMR   : in  std_ulogic;
          nOE   : in  std_ulogic;
          --
          DS    : in  std_ulogic;
          DCOn  : out   std_ulogic;
          Q7s   : out   std_ulogic;
          Q     : out   std_logic_vector(7 downto 0));
  end component;

  component AD5621
    port(SClk    : in  std_ulogic;
         nSync   : in  std_ulogic;
         Din     : in  std_ulogic;
         Vout    : out integer range 0 to 4095;
         VoutRdy : out std_ulogic := '0';
         TestFail: out boolean := false);
  end component;

  component AD9230
    port (CLKp  : in    std_ulogic;
          CLKn  : in    std_ulogic;
          RESET : in    std_ulogic; -- active low
          --
          DCOp  : out   std_ulogic;
          DCOn  : out   std_ulogic;
          Dp    : out   std_logic_vector(11 downto 0);
          Dn    : out   std_logic_vector(11 downto 0);
          ORp   : out   std_ulogic;
          ORn   : out   std_ulogic;
          --
          SCLK  : in    std_ulogic;
          CSB   : in    std_ulogic;
          SDIO  : inout std_logic;
          --
          VINp  : in    integer; -- analog input
          VINn  : in    integer);
  end component;

  component AdcTest
    port (Clk   : in    std_ulogic;
          nReset: in    std_ulogic;
          --
          Vp    : out   integer; -- analog output
          Vn    : out   integer);
  end component;

  component DspFpgaTop
    port (-- Local bus
          nLRESET    : in    std_ulogic;
          LCLK       : in    std_ulogic;
          LWnR       : inout std_ulogic;
          LD         : inout std_logic_vector(31 downto 0);
          DP         : inout std_logic_vector(3 downto 0);
          LA         : inout std_logic_vector(31 downto 2);
          nADS       : inout std_ulogic;
          nBLAST     : inout std_ulogic;
          nREADY     : inout std_ulogic;
          nWAIT      : inout std_ulogic;
          nBTERM     : inout std_ulogic;
          nLBE       : inout std_logic_vector(3 downto 0);
          BREQi      : out   std_ulogic;
          BREQo      : in    std_ulogic;
          nDREQ0     : out   std_ulogic;
          nDREQ1     : out   std_ulogic;
          nDACK0     : in    std_ulogic;
          nDACK1     : in    std_ulogic;
          nLINTi     : out   std_ulogic;
          nLINTo     : in    std_ulogic;
          nLSERR     : in    std_ulogic;
          nBIGEND    : out   std_ulogic;
          LHOLD      : in    std_ulogic;
          LHOLDA     : out   std_ulogic;
          USERi      : out   std_ulogic;
          USERo      : in    std_ulogic;
          nEOT       : in    std_ulogic;
          nCCS       : out   std_ulogic;
          nPMEIN     : out   std_ulogic;
          GPIO       : inout std_logic_vector(3 downto 0);
          -- A to D Signals
          AD_DcoP    : in    std_ulogic;
          AD_DcoN    : in    std_ulogic;
          AD_DP      : in    std_logic_vector(11 downto 0);
          AD_DN      : in    std_logic_vector(11 downto 0);
          AD_OrP     : in    std_ulogic;
          AD_OrN     : in    std_ulogic;
          nAD_Reset  : out   std_ulogic;
          nAD_Cs     : out   std_ulogic;
          AD_SClk    : out   std_ulogic;
          AD_SDio    : inout std_ulogic;
          -- DDS
          DdsFSync   : out   std_ulogic;
          DdsSClk    : out   std_ulogic;
          DdsSData   : out   std_ulogic;
          DdsSleep   : out   std_ulogic;
          DdsReset   : out   std_ulogic;
          DdsPSelect : out   std_ulogic;
          DdsFSelect : out   std_ulogic;
          nDdsOscInh : out   std_ulogic;
          -- Pulser and filters
          PulsePFetP : out   std_ulogic;
          PulsePFetN : out   std_ulogic;
          PulseNFetP : out   std_ulogic;
          PulseNFetN : out   std_ulogic;

          ChTxP      : out   std_logic_vector(7 downto 0);
          ChTxN      : out   std_logic_vector(7 downto 0);
          ChCkP      : out   std_logic_vector(7 downto 0);
          ChCkN      : out   std_logic_vector(7 downto 0);
          ChRxP      : out   std_logic_vector(7 downto 0);
          ChRxN      : out   std_logic_vector(7 downto 0);

          IoOutTxP   : out   std_ulogic;
          IoOutTxN   : out   std_ulogic;
          IoOutCkP   : out   std_ulogic;
          IoOutCkN   : out   std_ulogic;
          IoOutRxP   : out   std_ulogic;
          IoOutRxN   : out   std_ulogic;

          IoInTxP    : in    std_ulogic;
          IoInTxN    : in    std_ulogic;
          IoInCkP    : in    std_ulogic;
          IoInCkN    : in    std_ulogic;
          IoInRxP    : in    std_ulogic;
          IoInRxN    : in    std_ulogic;
          -- Encoder and Pulse inputs
          OpPha      : in    std_logic_vector(4 downto 1);
          OpPhb      : in    std_logic_vector(4 downto 1);
          OpIndex    : in    std_logic_vector(4 downto 1);
  
          FSerData   : out   std_ulogic;
          nFSerOE    : out   std_ulogic;
          FSerRClk   : out   std_ulogic;
          FSerClk    : out   std_ulogic;
          FSel0db    : out   std_ulogic;
          FSelN20db  : out   std_ulogic;
          FSelN40db  : out   std_ulogic;
          FSelP20db  : out   std_ulogic;
          -- HV PSU
          nHVEnable  : out   std_ulogic;
          HVFeedback : in    std_ulogic;
          nHVDisChg  : out   std_ulogic;
          nHVSync    : out   std_ulogic;
          HVSClk     : out   std_ulogic;
          HVSDIn     : out   std_ulogic;
          -- TCG RAM
          TcgDacClk  : out   std_ulogic;
          TcgDacSleep: out   std_ulogic;
          TcgDacD    : inout std_logic_vector(11 downto 0);
          TcgDacA    : out   std_logic_vector(17 downto 0);
          nTcgDacBHE : out   std_ulogic;
          nTcgDacBLE : out   std_ulogic;
          nTcgDacOe  : out   std_ulogic;
          nTcgDacCs  : out   std_ulogic;
          nTcgDacWr  : out   std_ulogic;
          -- SDRAM
          SR_Ck      : out   std_logic_vector(1 downto 0);
          nSR_Ck     : out   std_logic_vector(1 downto 0);
          SR_Cke     : out   std_logic_vector(1 downto 0);
          SR_Dq      : inout std_logic_vector(63 downto 0);
          SR_Dqs     : inout std_logic_vector(7 downto 0);
          nSR_Dqs    : inout std_logic_vector(7 downto 0);
          SR_DM      : out   std_logic_vector(7 downto 0);
          SR_A       : out   std_logic_vector(13 downto 0);
          SR_Ba      : out   std_logic_vector(2 downto 0);
          nSR_We     : out   std_ulogic;
          nSR_Ras    : out   std_ulogic;
          nSR_Cas    : out   std_ulogic;
          SR_ODT     : out   std_logic_vector(1 downto 0);
          nSR_S      : out   std_logic_vector(1 downto 0);
          SR_SCL     : out   std_ulogic;
          SR_SDA     : inout std_ulogic;
          SR_SA      : out   std_logic_vector(1 downto 0);
          SR_DqsDiv  : inout std_ulogic;  -- i/o delay equalisation pin
          -- Ethernet Phy
          PhyClkToMac: in    std_ulogic;
          nPhyReset  : out   std_ulogic;
          PhyRxCrs   : in    std_ulogic;
          PhyRxCol   : in    std_ulogic;
          PhyRxClk   : in    std_ulogic;
          PhyRxDv    : in    std_ulogic;
          PhyRxEr    : in    std_ulogic;
          PhyRxD     : in    std_logic_vector(7 downto 0);
          PhyGTxClk  : out   std_ulogic;
          PhyTxClk   : in    std_ulogic;
          PhyTxEn    : in    std_ulogic;
          PhyTxEr    : in    std_ulogic;
          PhyTxD     : out   std_logic_vector(7 downto 0);
          PhyMdc     : out   std_ulogic;
          PhyMdio    : inout std_ulogic;
          nPhyInt    : in    std_ulogic;
          PhyMdixEn  : out   std_ulogic;
          PhyMultiEn : out   std_ulogic;
          PhyAd      : out   std_logic_vector(4 downto 0);
          PhyAnEn    : out   std_ulogic;
          PhyDuplex  : out   std_ulogic;
          PhySpeed   : out   std_logic_vector(1 downto 0);
          -- MRAM
          MRamIO     : inout std_logic_vector(15 downto 0);
          MRamA      : out   std_logic_vector(17 downto 0);
          nMRamCs    : out   std_ulogic;
          nMRamWe    : out   std_ulogic;
          nMRamOe    : out   std_ulogic;
          nMRamBle   : out   std_ulogic;
          nMRamBhe   : out   std_ulogic;
          -- Misc IO
          FTrigger   : in    std_ulogic;
          FSync      : out   std_ulogic;
          Ident      : in    std_logic_vector(3 downto 0);
          nSDVterm   : out   std_ulogic;
          Relay      : out   std_ulogic;
          DBugD      : inout std_logic_vector(3 downto 0);

          BuzzP      : in    std_logic_vector(11 downto 0);
          BuzzN      : in    std_logic_vector(11 downto 0));
  end component;

  component ddr2_sodimm
    port (reset_n : in    std_ulogic;
          ck      : in    std_logic_vector(1 downto 0);
          ck_n    : in    std_logic_vector(1 downto 0);
          cke     : in    std_logic_vector(1 downto 0);
          s_n     : in    std_logic_vector(1 downto 0);
          ras_n   : in    std_ulogic;
          cas_n   : in    std_ulogic;
          we_n    : in    std_ulogic;
          ba      : in    std_logic_vector(2 downto 0);
          addr    : in    std_logic_vector(13 downto 0);
          odt     : in    std_logic_vector(1 downto 0);
          dm      : in    std_logic_vector(7 downto 0);
          dqs     : inout std_logic_vector(7 downto 0);
          dqs_n   : inout std_logic_vector(7 downto 0);
          dq      : inout std_logic_vector(63 downto 0);
          scl     : in    std_ulogic;
          sa      : in    std_logic_vector(2 downto 0);
          sda     : inout std_ulogic);
  end component;

  component SPD_EEPROM
    generic(gModuleSize : integer := 2); -- size in GBytes
	  port (SCL      : in    std_logic;
		      SDA      : inout std_logic := 'Z';
          SA       : in    std_logic_vector(2 downto 0);

    	    TestFail : out boolean := false);
  end component;

  component idt71v416s10 is
    port (data : inout std_logic_vector(15 downto 0);
          addr : in    std_logic_vector(17 downto 0);
          wen  : in    std_ulogic;
          oen  : in    std_ulogic;
          csn  : in    std_ulogic;
          blen : in    std_ulogic;
          bhen : in    std_ulogic);
  end component;

  component AD9742
    port (Clk   : in std_ulogic;
          Sleep : in std_ulogic;
          DB    : in std_logic_vector(11 downto 0);
          OutA  : out std_logic_vector(11 downto 0);
          TestFail: out boolean := false);
  end component;

  -- Signals to connect to simulation models
  signal ToBusModel: tToBusModel;
  signal FromBusModel: tFromBusModel;
--  signal ToAdcModel: tToAdcModel;
--  signal FromAdcModel: tFromAdcModel;
  signal SysMonData: tSysMon;
  signal SysMonTemp: integer range -35 to +85;

  -- Local bus
  signal nLRESET    : std_ulogic;
  signal LCLK       : std_ulogic;
  signal LWnR       : std_logic;
  signal LD         : std_logic_vector(31 downto 0);
  signal DP         : std_logic_vector(3 downto 0);
  signal LA         : std_logic_vector(31 downto 0);
  signal nADS       : std_logic;
  signal nBLAST     : std_logic;
  signal nREADY     : std_logic;
  signal nWAIT      : std_logic;
  signal nBTERM     : std_logic;
  signal nLBE       : std_logic_vector(3 downto 0);
  signal BREQi      : std_logic;
  signal BREQo      : std_ulogic;
  signal nDREQ0     : std_logic;
  signal nDREQ1     : std_logic;
  signal nDACK0     : std_ulogic;
  signal nDACK1     : std_ulogic;
  signal nLINTi     : std_logic;
  signal nLINTo     : std_ulogic;
  signal nLSERR     : std_ulogic;
  signal nBIGEND    : std_logic;
  signal LHOLD      : std_ulogic;
  signal LHOLDA     : std_logic;
  signal USERi      : std_logic;
  signal USERo      : std_ulogic;
  signal nEOT       : std_ulogic;
  signal nCCS       : std_logic;
  signal nPMEIN     : std_logic;
  signal GPIO       : std_logic_vector(3 downto 0);
  -- DSP FPGA connections
  signal DspCClk      : std_ulogic;
  signal DspDone      : std_ulogic;
  signal nDspProg     : std_ulogic;
  signal DspDIn       : std_ulogic;
  signal nDspInit     : std_ulogic;
  signal DspLoadCount : integer;
  -- EEPROM connections
  signal EEClk      : std_ulogic;
  signal EEOut      : std_ulogic;
  signal EEIn       : std_ulogic;
  signal nEECs      : std_ulogic;
  -- System Monitor
  signal nSysMonCs  : std_logic_vector(2 downto 0);
  signal SysMonSClk : std_ulogic;
  signal SysMonDIn  : std_ulogic;
  signal SysMonDOut : std_logic;
  signal TempSnsCe  : std_ulogic;
  signal TempSnsSClk: std_ulogic;
  signal TempSnsSDo : std_ulogic;
  signal SysMonD    : std_logic_vector(4 downto 0);
  signal SysMonOK   : std_ulogic;
  -- System FPGA Misc IO
  signal SysLED     : std_ulogic;
  signal SysDbugD   : std_logic_vector(15 downto 8);
  signal BuzzP      : std_logic_vector(11 downto 0);
  signal BuzzN      : std_logic_vector(11 downto 0);

  -- DSP FPGA configuration size
  constant cXC3S2000ConfigSize  : integer := (7673024 / 32); -- (bits / 32) = DWORDS
  
  signal FSerData   : std_ulogic;
  signal FSerData0  : std_ulogic;
  signal FSerData1  : std_ulogic;
  signal FSerData2  : std_ulogic;
  signal FSerData3  : std_ulogic;
  signal nFSerOE    : std_ulogic;
  signal FSerRClk   : std_ulogic;
  signal FSerClk    : std_ulogic;
  signal FSerOE     : std_ulogic;
  signal nFSerRClk  : std_ulogic;
  signal nFSerClk   : std_ulogic;
  signal SEL        : std_logic_vector(7 downto 0);
  signal AtoD       : std_logic_vector(7 downto 0);
  signal SG         : std_logic_vector(7 downto 0);
  signal BE         : std_logic_vector(7 downto 0);
  signal FE         : std_logic_vector(7 downto 0);

  signal FSel0db    : std_ulogic;
  signal FSelN20db  : std_ulogic;
  signal FSelN40db  : std_ulogic;
  signal FSelP20db  : std_ulogic;
  -- A to D Signals
  signal ClkP       : std_ulogic := '0';
  signal ClkN       : std_ulogic := '1';
  signal AD_DcoP    : std_ulogic;
  signal AD_DcoN    : std_ulogic;
  signal AD_DP      : std_logic_vector(11 downto 0);
  signal AD_DN      : std_logic_vector(11 downto 0);
  signal AD_OrP     : std_ulogic;
  signal AD_OrN     : std_ulogic;
  signal nAD_Reset  : std_ulogic;
  signal nAD_Cs     : std_ulogic;
  signal nAD_Cs01   : std_ulogic;
  signal AD_SClk    : std_ulogic;
  signal AD_SDio    : std_logic;
  signal Vp         : integer;
  signal Vn         : integer;
  -- DDS
  signal DdsFSync   : std_ulogic;
  signal DdsSClk    : std_ulogic;
  signal DdsSData   : std_ulogic;
  signal DdsSleep   : std_ulogic;
  signal DdsReset   : std_ulogic;
  signal DdsPSelect : std_ulogic;
  signal DdsFSelect : std_ulogic;
  signal nDdsOscInh : std_ulogic;
  -- Pulser and filters
  signal PulsePFetP : std_ulogic;
  signal PulsePFetN : std_ulogic;
  signal PulseNFetP : std_ulogic;
  signal PulseNFetN : std_ulogic;

  signal ChTxP      : std_logic_vector(7 downto 0);
  signal ChTxN      : std_logic_vector(7 downto 0);
  signal ChCkP      : std_logic_vector(7 downto 0);
  signal ChCkN      : std_logic_vector(7 downto 0);
  signal ChRxP      : std_logic_vector(7 downto 0);
  signal ChRxN      : std_logic_vector(7 downto 0);

  signal IoOutTxP   : std_ulogic;
  signal IoOutTxN   : std_ulogic;
  signal IoOutCkP   : std_ulogic;
  signal IoOutCkN   : std_ulogic;
  signal IoOutRxP   : std_ulogic;
  signal IoOutRxN   : std_ulogic;

  signal IoInTxP    : std_ulogic;
  signal IoInTxN    : std_ulogic;
  signal IoInCkP    : std_ulogic;
  signal IoInCkN    : std_ulogic;
  signal IoInRxP    : std_ulogic;
  signal IoInRxN    : std_ulogic;

  signal OpPha      : std_logic_vector(4 downto 1);
  signal OpPhb      : std_logic_vector(4 downto 1);
  signal OpIndex    : std_logic_vector(4 downto 1);
  -- HV PSU
  signal nHVEnable  : std_ulogic;
  signal HVFeedback : std_ulogic;
  signal nHVDisChg  : std_ulogic;
  signal nHVSync    : std_ulogic;
  signal HVSClk     : std_ulogic;
  signal HVSDIn     : std_ulogic;
  signal HvAdj      : integer range 0 to 4095;
  -- TCG
  signal TcgDacClk  : std_ulogic;
  signal TcgDacSleep: std_ulogic;
  signal TcgDacD    : std_logic_vector(15 downto 0);
  signal TcgDacA    : std_logic_vector(17 downto 0);
  signal nTcgDacBHE : std_ulogic;
  signal nTcgDacBLE : std_ulogic;
  signal nTcgDacOe  : std_ulogic;
  signal nTcgDacCs  : std_ulogic;
  signal nTcgDacWr  : std_ulogic;
  -- SDRAM
  signal SR_Ck      : std_logic_vector(1 downto 0);
  signal nSR_Ck     : std_logic_vector(1 downto 0);
  signal SR_Cke     : std_logic_vector(1 downto 0);
  signal SR_Dq      : std_logic_vector(63 downto 0);
  signal SR_Dqs     : std_logic_vector(7 downto 0);
  signal nSR_Dqs    : std_logic_vector(7 downto 0);
  signal SR_Dm      : std_logic_vector(7 downto 0);
  signal SR_A       : std_logic_vector(13 downto 0);
  signal SR_Ba      : std_logic_vector(2 downto 0);
  signal nSR_We     : std_ulogic;
  signal nSR_Ras    : std_ulogic;
  signal nSR_Cas    : std_ulogic;
  signal SR_ODT     : std_logic_vector(1 downto 0);
  signal nSR_S      : std_logic_vector(1 downto 0);
  signal SR_SCL     : std_ulogic;
  signal SR_SDA     : std_logic;
  signal SR_SA      : std_logic_vector(2 downto 0);
  signal SR_DqsDiv  : std_ulogic;

  -- Ethernet Phy
  signal PhyClkToMac: std_ulogic;
  signal nPhyReset  : std_ulogic;
  signal PhyRxCrs   : std_ulogic;
  signal PhyRxCol   : std_ulogic;
  signal PhyRxClk   : std_ulogic;
  signal PhyRxDv    : std_ulogic;
  signal PhyRxEr    : std_ulogic;
  signal PhyRxD     : std_logic_vector(7 downto 0);
  signal PhyGTxClk  : std_ulogic;
  signal PhyTxClk   : std_ulogic;
  signal PhyTxEn    : std_ulogic;
  signal PhyTxEr    : std_ulogic;
  signal PhyTxD     : std_logic_vector(7 downto 0);
  signal PhyMdc     : std_ulogic;
  signal PhyMdio    : std_ulogic;
  signal nPhyInt    : std_ulogic;
  signal PhyMdixEn  : std_ulogic;
  signal PhyMultiEn : std_ulogic;
  signal PhyAd      : std_logic_vector(4 downto 0);
  signal PhyAnEn    : std_ulogic;
  signal PhyDuplex  : std_ulogic;
  signal PhySpeed   : std_logic_vector(1 downto 0);
  -- MRAM
  signal MRamIO     : std_logic_vector(15 downto 0);
  signal MRamA      : std_logic_vector(17 downto 0);
  signal nMRamCs    : std_ulogic;
  signal nMRamWe    : std_ulogic;
  signal nMRamOe    : std_ulogic;
  signal nMRamBle   : std_ulogic;
  signal nMRamBhe   : std_ulogic;
  -- Misc IO
  signal FTrigger   : std_ulogic;
  signal FSync      : std_ulogic;
  signal Ident      : std_logic_vector(3 downto 0);
  signal nSDVterm   : std_ulogic;
  signal Relay      : std_ulogic;
  signal DspDBugD   : std_logic_vector(3 downto 0);
  signal DSPShiftData: std_logic_vector(39 downto 0);
  signal FSel       : std_logic_vector(3 downto 0);

begin
  -- Simulation control
  SimCtrl0: SimCtrl
    port map (ToBusModel    => ToBusModel,
              FromBusModel  => FromBusModel,
--               ToAdcModel    => ToAdcModel,
--               FromAdcModel  => FromAdcModel,
              ToSysMonAdc   => SysMonData,
              ToSysMonTemp  => SysMonTemp,
              SysMonD       => SysMonD,
              SysMonOK      => SysMonOK,
              DspShiftData  => DspShiftData,
              FSel          => FSel,
              HvAdj         => HvAdj,
              HvEn          => nHVEnable,
              HVDischarge   => nHVDisChg,
              HVFeedback    => HVFeedback);
  
  DSPShiftData <= FE & BE & SG & AtoD & SEL;
  FSel <= not FSelP20db & FSelN40db & FSelN20db & FSel0db;

  -- LBUS model
  U22: LocalBusModel
    port map (-- Control signals to/from main simulation module
              ToBusModel   => ToBusModel,
              FromBusModel => FromBusModel,
              -- Bus Signals
              nLRESET      => nLRESET,
              LCLKA        => LCLK,
              LWnR         => LWnR,
              nADS         => nADS,
              nBLAST       => nBLAST,
              nREADY       => nREADY,
              LA           => LA,
              LD           => LD,
              LHOLD        => LHOLD,
              LHOLDA       => LHOLDA,
              nBTERM       => nBTERM,
              nCCS         => nCCS,
              BREQi        => BREQi,
              nLINTi       => nLINTi);

  BREQi <= 'L'; -- pulldown on board

  -- System FPGA
  U81 : SystemFpgaTop
		port map (nLRESET     => nLRESET,
		          LCLKA       => LCLK,
		          LCLKB       => LCLK,
		          LWnR        => LWnR,
		          LD          => LD,
		          DP          => DP,
		          LA          => LA(31 downto 2),
		          nADS        => nADS,
		          nBLAST      => nBLAST,
		          nREADY      => nREADY,
		          nWAIT       => nWAIT,
		          nBTERM      => nBTERM,
		          nLBE        => nLBE,
		          BREQi       => BREQi,
		          BREQo       => BREQo,
		          nDREQ0      => nDREQ0,
		          nDREQ1      => nDREQ1,
		          nDACK0      => nDACK0,
		          nDACK1      => nDACK1,
		          nLINTi      => nLINTi,
		          nLINTo      => nLINTo,
		          nLSERR      => nLSERR,
		          nBIGEND     => nBIGEND,
		          LHOLD       => LHOLD,
		          LHOLDA      => LHOLDA,
		          USERi       => USERi,
		          USERo       => USERo,
		          nEOT        => nEOT,
		          nCCS        => nCCS,
		          nPMEIN      => nPMEIN,
		          GPIO        => GPIO,
		          DspCClk     => DspCClk,
		          DspDone     => DspDone,
		          nDspProg    => nDspProg,
		          DspDIn      => DspDIn,
		          nDspInit    => nDspInit,
		          EEClk       => EEClk,
		          EEOut       => EEOut,
		          EEIn        => EEIn,
		          nEECs       => nEECs,
		          nSysMonCs   => nSysMonCs,
		          SysMonSClk  => SysMonSClk,
		          SysMonDIn   => SysMonDIn,
		          SysMonDOut  => SysMonDOut,
		          TempSnsCe   => TempSnsCe,
		          TempSnsSClk => TempSnsSClk,
		          TempSnsSDo  => TempSnsSDo,
		          SysMonD     => SysMonD,
		          SysMonOK    => SysMonOK,
		          SysLED      => SysLED,
		          DbugD       => SysDbugD,
		          BuzzP       => BuzzP,
		          BuzzN       => BuzzN);

  -- System Monitor models
  U85: ADC128C022
    port map (SClk => SysMonSClk,
              nCs  => nSysMonCs(0),
              DIn  => SysMonDIn,
              DOut => SysMonDOut,
              -- Testbench interface signals
              In0  => SysMonData(0),
              In1  => SysMonData(1),
              In2  => SysMonData(2),
              In3  => SysMonData(3),
              In4  => SysMonData(4),
              In5  => SysMonData(5),
              In6  => SysMonData(6),
              In7  => SysMonData(7));

  U86: ADC128C022
    port map (SClk => SysMonSClk,
              nCs  => nSysMonCs(1),
              DIn  => SysMonDIn,
              DOut => SysMonDOut,
              -- Testbench interface signals
              In0  => SysMonData(8),
              In1  => SysMonData(9),
              In2  => SysMonData(10),
              In3  => SysMonData(11),
              In4  => SysMonData(12),
              In5  => SysMonData(13),
              In6  => SysMonData(14),
              In7  => SysMonData(15));

  U88: ADC128C022
    port map (SClk => SysMonSClk,
              nCs  => nSysMonCs(2),
              DIn  => SysMonDIn,
              DOut => SysMonDOut,
              -- Testbench interface signals
              In0  => SysMonData(16),
              In1  => SysMonData(17),
              In2  => SysMonData(18),
              In3  => SysMonData(19),
              In4  => SysMonData(20),
              In5  => SysMonData(21),
              In6  => SysMonData(22),
              In7  => SysMonData(23));

  U89: AD7314
    port map (SClk => TempSnsSClk,
              Ce   => TempSnsCe,
              Sdi  => '0',
              Sdo  => TempSnsSDo,
              -- Testbench interface signals
              Temp => SysMonTemp);

  -- Model inversion through analogue switches (U8)
  nFSerOE <= not FSerOE;
  FSerClk <= not nFSerClk;
  FSerRClk <= not nFSerRClk;

  -- Analogue/Filter controls
  U55: HC595
    port map (SH_CP => FSerClk,
              ST_CP => FSerRClk,
              nMR   => '1',
              nOE   => nFSerOE,
              --
              DS    => FSerData,
              Q7s   => FSerData0,
              Q     => SEL);

  U61: HC595
    port map (SH_CP => FSerClk,
              ST_CP => FSerRClk,
              nMR   => '1',
              nOE   => nFSerOE,
              --
              DS    => FSerData0,
              Q7s   => FSerData1,
              Q     => AtoD);

  U80: HC595
    port map (SH_CP => FSerClk,
              ST_CP => FSerRClk,
              nMR   => '1',
              nOE   => nFSerOE,
              --
              DS    => FSerData1,
              Q7s   => FSerData2,
              Q     => SG);

  U3: HC595
    port map (SH_CP => FSerClk,
              ST_CP => FSerRClk,
              nMR   => '1',
              nOE   => nFSerOE,
              --
              DS    => FSerData2,
              Q7s   => FSerData3,
              Q     => BE);

  U19: HC595
    port map (SH_CP => FSerClk,
              ST_CP => FSerRClk,
              nMR   => '1',
              nOE   => nFSerOE,
              --
              DS    => FSerData3,
              Q7s   => open,
              Q     => FE);

  -- HV controls
  U47: AD5621
    port map (SClk     => HVSClk,
              nSync    => nHVSync,
              Din      => HVSDIn,
              Vout     => HvAdj,
              VoutRdy  => open,
              TestFail => open);

  -- DDS Frequency source

  -- 200MHz oscillator
  X3 : process
  begin
    Wait for 2.5 ns;
    ClkP <= '1';
    ClkN <= '0';
    Wait for 2.5 ns;
    ClkP <= '0';
    ClkN <= '1';
  end process;    

  Analog: AdcTest
    port map (Clk    => ClkP,
              nReset => nLRESET,
              --
              Vp     => Vp,
              Vn     => Vn);

  -- Main ADC
  U67: AD9230
    port map (CLKp  => ClkP,
              CLKn  => ClkN,
              RESET => nAD_Reset,
              --
              DCOp  => AD_DcoP,
              DCOn  => AD_DcoN,
              Dp    => AD_DP,
              Dn    => AD_DN,
              ORp   => AD_OrP,
              ORn   => AD_OrN,
              --
              SCLK  => AD_SClk,
              CSB   => nAD_Cs01,
              SDIO  => AD_SDio,
              --
              VINp  => Vp,
              VINn  => Vn);

  -- cope with open-drain output 
  nAD_Cs01 <= '0' when nAD_Cs = '0' else '1';

  --DSP FPGA
  U6: DspFpgaTop
  port map (-- Local bus
            nLRESET     => nLRESET,
            LCLK        => LCLK,
            LWnR        => LWnR,
            LD          => LD,
            DP          => DP,
            LA          => LA(31 downto 2),
            nADS        => nADS,
            nBLAST      => nBLAST,
            nREADY      => nREADY,
            nWAIT       => nWAIT,
            nBTERM      => nBTERM,
            nLBE        => nLBE,
            BREQi       => BREQi,
            BREQo       => BREQo,
            nDREQ0      => nDREQ0,
            nDREQ1      => nDREQ1,
            nDACK0      => nDACK0,
            nDACK1      => nDACK1,
            nLINTi      => nLINTi,
            nLINTo      => nLINTo,
            nLSERR      => nLSERR,
            nBIGEND     => nBIGEND,
            LHOLD       => LHOLD,
            LHOLDA      => LHOLDA,
            USERi       => USERi,
            USERo       => USERo,
            nEOT        => nEOT,
            nCCS        => nCCS,
            nPMEIN      => nPMEIN,
            GPIO        => GPIO,
            -- A to D Signals
            AD_DcoP     => AD_DcoP,
            AD_DcoN     => AD_DcoN,
            AD_DP       => AD_DP,
            AD_DN       => AD_DN,
            AD_OrP      => AD_OrP,
            AD_OrN      => AD_OrN,
            nAD_Reset   => nAD_Reset,
            nAD_Cs      => nAD_Cs,
            AD_SClk     => AD_SClk,
            AD_SDio     => AD_SDio,
            -- DDS
            DdsFSync    => DdsFSync,
            DdsSClk     => DdsSClk,
            DdsSData    => DdsSData,
            DdsSleep    => DdsSleep,
            DdsReset    => DdsReset,
            DdsPSelect  => DdsPSelect,
            DdsFSelect  => DdsFSelect,
            nDdsOscInh  => nDdsOscInh,
            -- Pulser and filters
            PulsePFetP  => PulsePFetP,
            PulsePFetN  => PulsePFetN,
            PulseNFetP  => PulseNFetP,
            PulseNFetN  => PulseNFetN,

            ChTxP       => ChTxP,
            ChTxN       => ChTxN,
            ChCkP       => ChCkP,
            ChCkN       => ChCkN,
            ChRxP       => ChRxP,
            ChRxN       => ChRxN,

            IoOutTxP    => IoOutTxP,
            IoOutTxN    => IoOutTxN,
            IoOutCkP    => IoOutCkP,
            IoOutCkN    => IoOutCkN,
            IoOutRxP    => IoOutRxP,
            IoOutRxN    => IoOutRxN,

            IoInTxP     => IoInTxP,
            IoInTxN     => IoInTxN,
            IoInCkP     => IoInCkP,
            IoInCkN     => IoInCkN,
            IoInRxP     => IoInRxP,
            IoInRxN     => IoInRxN,

            OpPha       => OpPha,
            OpPhb       => OpPhb,
            OpIndex     => OpIndex,

            FSerData    => FSerData,
            nFSerOE     => FSerOE,
            FSerRClk    => nFSerRClk,
            FSerClk     => nFSerClk,
            FSel0db     => FSel0db,
            FSelN20db   => FSelN20db,
            FSelN40db   => FSelN40db,
            FSelP20db   => FSelP20db,
            -- HV PSU
            nHVEnable   => nHVEnable,
            HVFeedback  => HVFeedback,
            nHVDisChg   => nHVDisChg,
            nHVSync     => nHVSync,
            HVSClk      => HVSClk,
            HVSDIn      => HVSDIn,
            -- TCG RAM
            TcgDacClk   => TcgDacClk,
            TcgDacSleep => TcgDacSleep,
            TcgDacD     => TcgDacD(11 downto 0),
            TcgDacA     => TcgDacA,
            nTcgDacBHE  => nTcgDacBHE,
            nTcgDacBLE  => nTcgDacBLE,
            nTcgDacOe   => nTcgDacOe,
            nTcgDacCs   => nTcgDacCs,
            nTcgDacWr   => nTcgDacWr,
            -- SDRAM
            SR_Ck       => SR_Ck,
            nSR_Ck      => nSR_Ck,
            SR_Cke      => SR_Cke,
            SR_Dq       => SR_Dq,
            SR_Dqs      => SR_Dqs,
            nSR_Dqs     => nSR_Dqs,
            SR_DM       => SR_Dm,
            SR_A        => SR_A,
            SR_Ba       => SR_Ba,
            nSR_We      => nSR_We,
            nSR_Ras     => nSR_Ras,
            nSR_Cas     => nSR_Cas,
            SR_ODT      => SR_ODT,
            nSR_S       => nSR_S,
            SR_SCL      => SR_SCL,
            SR_SDA      => SR_SDA,
            SR_SA       => SR_SA(1 downto 0),
            SR_DqsDiv   => SR_DqsDiv,
            -- Ethernet Phy
            PhyClkToMac => PhyClkToMac,
            nPhyReset   => nPhyReset,
            PhyRxCrs    => PhyRxCrs,
            PhyRxCol    => PhyRxCol,
            PhyRxClk    => PhyRxClk,
            PhyRxDv     => PhyRxDv,
            PhyRxEr     => PhyRxEr,
            PhyRxD      => PhyRxD,
            PhyGTxClk   => PhyGTxClk,
            PhyTxClk    => PhyTxClk,
            PhyTxEn     => PhyTxEn,
            PhyTxEr     => PhyTxEr,
            PhyTxD      => PhyTxD,
            PhyMdc      => PhyMdc,
            PhyMdio     => PhyMdio,
            nPhyInt     => nPhyInt,
            PhyMdixEn   => PhyMdixEn,
            PhyMultiEn  => PhyMultiEn,
            PhyAd       => PhyAd,
            PhyAnEn     => PhyAnEn,
            PhyDuplex   => PhyDuplex,
            PhySpeed    => PhySpeed,
            -- MRAM
            MRamIO      => MRamIO,
            MRamA       => MRamA,
            nMRamCs     => nMRamCs,
            nMRamWe     => nMRamWe,
            nMRamOe     => nMRamOe,
            nMRamBle    => nMRamBle,
            nMRamBhe    => nMRamBhe,
            -- Misc IO
            FTrigger    => FTrigger,
            FSync       => FSync,
            Ident       => Ident,
            nSDVterm    => nSDVterm,
            Relay       => Relay,
            DBugD       => DspDBugD,

            BuzzP       => BuzzP,
            BuzzN       => BuzzN);


  -- DSP FPGA configuration checking
  process
    variable vShiftReg: std_logic_vector(31 downto 0);
    variable vShiftCount: integer;
    variable vLine: Line;
  begin
    DspDone  <= '1';
    nDspInit  <= '1';
    DspLoadCount <= 0;
    vShiftCount := 0;

    -- Wait for Program to be asserted (low) and then remove Done
    wait on nDspProg until rising_edge(nDspProg);
    wait for 300 ns;
    DspDone  <= '0';

    -- Take Init low for a time
    wait for 300 ns;
    nDspInit  <= '0';
    wait for 300 ns;
    nDspInit  <= '1';

    while DspDone = '0' loop
      wait on DspCClk until rising_edge(DspCClk);
      vShiftReg(7 downto 0) := vShiftReg(6 downto 0) & vShiftReg(15);
      vShiftReg(15 downto 8) := vShiftReg(14 downto 8) & vShiftReg(23);
      vShiftReg(23 downto 16) := vShiftReg(22 downto 16) & vShiftReg(31);
      vShiftReg(31 downto 24) := vShiftReg(30 downto 24) & DspDIn;
      if vShiftCount /= 31 then
        vShiftCount := vShiftCount + 1;
      else
        vShiftCount := 0;
        case DspLoadCount is
          when 0 =>
            if vShiftReg = X"DEADBEEF" then
              -- Skip FPGA configuration when magic word is received
              report "Testbench: FPGA configuration simulation skipped"
                severity warning;
              DspDone  <= '1';
              wait;
            else
              write (vLine, string'("Testbench: DSP FPGA configuration 0% complete"));
              writeline (OUTPUT, vLine);
            end if;
          when cXC3S2000ConfigSize*10/100 - 1 =>
              write (vLine, string'("Testbench: DSP FPGA configuration 10% complete"));
              writeline (OUTPUT, vLine);
          when cXC3S2000ConfigSize*20/100 - 1 =>
              write (vLine, string'("Testbench: DSP FPGA configuration 20% complete"));
              writeline (OUTPUT, vLine);
          when cXC3S2000ConfigSize*30/100 - 1 =>
              write (vLine, string'("Testbench: DSP FPGA configuration 30% complete"));
              writeline (OUTPUT, vLine);
          when cXC3S2000ConfigSize*40/100 - 1 =>
              write (vLine, string'("Testbench: DSP FPGA configuration 40% complete"));
              writeline (OUTPUT, vLine);
          when cXC3S2000ConfigSize*50/100 - 1 =>
              write (vLine, string'("Testbench: DSP FPGA configuration 50% complete"));
              writeline (OUTPUT, vLine);
          when cXC3S2000ConfigSize*60/100 - 1 =>
              write (vLine, string'("Testbench: DSP FPGA configuration 60% complete"));
              writeline (OUTPUT, vLine);
          when cXC3S2000ConfigSize*70/100 - 1 =>
              write (vLine, string'("Testbench: DSP FPGA configuration 70% complete"));
              writeline (OUTPUT, vLine);
          when cXC3S2000ConfigSize*80/100 - 1 =>
              write (vLine, string'("Testbench: DSP FPGA configuration 80% complete"));
              writeline (OUTPUT, vLine);
          when cXC3S2000ConfigSize*90/100 - 1 =>
              write (vLine, string'("Testbench: DSP FPGA configuration 90% complete"));
              writeline (OUTPUT, vLine);
          when cXC3S2000ConfigSize*100/100 - 1 =>
              write (vLine, string'("Testbench: DSP FPGA configuration 100% complete"));
              writeline (OUTPUT, vLine);
          when cXC3S2000ConfigSize =>
            report "Testbench: DSP FPGA has be written with too much configuration data"
              severity error;
          when others => null;
        end case;

        -- Check config data is correct (we only check first and last 10 values!)
        case DspLoadCount is
          when 0 to 9 =>
            if conv_integer(unsigned(vShiftReg(7 downto 0))) /= DspLoadCount then
              write (vLine, string'("Testbench: Error - DSP FPGA got unexpected config data at position "));
              write (vLine, DspLoadCount);
              writeline (OUTPUT, vLine);
              report "Testbench: Stop sim" severity failure;
            end if;
          when cXC3S2000ConfigSize-10 to cXC3S2000ConfigSize-1 =>
            if conv_integer(unsigned(vShiftReg(7 downto 0))) /= (DspLoadCount - (cXC3S2000ConfigSize - 80)) then
              write (vLine, string'("Testbench: Error - DSP FPGA got unexpected config data at position "));
              write (vLine, DspLoadCount);
              writeline (OUTPUT, vLine);
              report "Testbench: Stop sim" severity failure;
            end if;
          when others => null;
        end case;

        if DspLoadCount = cXC3S2000ConfigSize - 1 then
          DspDone <= '1';
        end if;

        DspLoadCount <= DspLoadCount + 1;
      end if;

    end loop;

    wait;

  end process;

  -- DDR2 RAM
  U74: ddr2_sodimm
    port map (reset_n => nLRESET,
              ck      => SR_Ck,
              ck_n    => nSR_Ck,
              cke     => SR_Cke,
              s_n     => nSR_S,
              ras_n   => nSR_Ras,
              cas_n   => nSR_Cas,
              we_n    => nSR_We,
              ba      => SR_Ba,
              addr    => SR_A,
              odt     => SR_ODT,
              dm      => SR_Dm,
              dqs     => SR_Dqs,
              dqs_n   => nSR_Dqs,
              dq      => SR_Dq,
              scl     => SR_SCL,
              sa      => SR_SA,
              sda     => SR_SDA);

  SR_SDA <= 'H';   -- pull-up
  SR_SA(2) <= '0'; -- tied low on SODMIMM module

  U74a: SPD_EEPROM
    generic map (gModuleSize => 2)
    port map (SCL      => SR_SCL,
              SDA      => SR_SDA,
              SA       => SR_SA,

              TestFail => open);

  -- Encoders

  -- TCG RAM/DAC
  TcgDacD(15 downto 12) <= (others => '0');
  
  U91: idt71v416s10   
    port map (data => TcgDacD,
              addr => TcgDacA,
              wen  => nTcgDacWr,
              oen  => nTcgDacOe,
              csn  => nTcgDacCs,
              blen => nTcgDacBLE,
              bhen => nTcgDacBHE);

  U92: AD9742
    port map (Clk      => TcgDacClk,
              Sleep    => TcgDacSleep,
              DB       => TcgDacD(11 downto 0),
              OutA     => open,
              TestFail => open);

  -- Ethernet PHY

end TestBench;
