---------------------------------------------------------------------------
-- NDT Solutions Ltd. Proprietary Information
-- Company Confidential
-- Copyright 2004
--
-- Filename: SimCtrlSeq2.vhd
-- Language: VHDL '93
-- Project:  Digitiser Card FPGAs
--
-- Design Description:
--Simulation Control file (002) for Digitiser card testbench - with sequence table
---------------------------------------------------------------------------


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 SimCtrl is
  port(ToBusModel   : out tToBusModel;
       FromBusModel : in tFromBusModel;
       ToAdcModel   : out tToAdcModel;
       FromAdcModel : in tFromAdcModel;
       Trigger      : in std_ulogic;
       Ack          : out std_ulogic);
end entity SimCtrl;


architecture Test of SimCtrl is

  -- Define some system register addresses
  constant cSysCheckReg:   integer := 16#00500000#;
  constant cSysCommandReg: integer := 16#00500014#;
  constant cSysStatusReg:  integer := 16#00500014#;

  constant cPerCheckReg:   integer := 16#00500400#;
  constant cTriggerCtrl:   integer := 16#00500404#;

  constant cGateStartStop:  integer := 16#00500438#;
  constant cGateAttributes: integer := 16#0050043C#;
  constant cGateSetup:      integer := 16#00500440#;

  constant cPerSequenceStep: integer := 16#0050045C#;
  constant cPerSequenceCtrl: integer := 16#00500460#;

  constant cDspSramCtrl:        integer := 16#00500258#;
  constant cDspSramCtrlNoScans: integer := 16#0050026C#;

  constant cDspSequenceStep: integer := 16#00500274#;
  constant cDspSequenceCtrl: integer := 16#00500278#;

  -- Define the base of the system SRAM
  constant cSysSramBase:     integer := 16#00400000#;

  -- Define the base of the sample SRAM
  constant cSampleSramBase:  integer := 16#00000000#;


begin

  -- Main Simulation Control process
  Main: process
    variable vRData: integer;
    variable vWData: integer;
    variable vTestFail: boolean;
    variable vLine: Line;
    variable vDone: boolean;
    variable vBurstData: tBurstData;
    variable vReadBurstData: tBurstData;

  begin

    -- Initialise the test fail flag
    vTestFail := false;

    -- Initialise the Bus Model (bus clock = 66 MHz)
    BusInit(15 ns, ToBusModel, FromBusModel);

    -- Write description of test to output
    write (vLine, string'("Testbench: Peripheral FPGA Sequence Step register test"));
    writeline (OUTPUT, vLine);

    -- Write to the Trigger Control registers for Steps 0,1
    LBusWrite(cPerSequenceStep, 16#00000000#, ToBusModel, FromBusModel);
    LBusWrite(cTriggerCtrl, 16#00A0BEEF#, ToBusModel, FromBusModel);

    LBusWrite(cPerSequenceStep, 16#00000001#, ToBusModel, FromBusModel);
    LBusWrite(cTriggerCtrl, 16#00204567#, ToBusModel, FromBusModel);

    -- Read the Trigger Control register values back
    LBusWrite(cPerSequenceStep, 16#00000000#, ToBusModel, FromBusModel);
    LBusRead(cTriggerCtrl, vRData, ToBusModel, FromBusModel);
    if vRData /= 16#00A0BEEF# then
      write (vLine, string'("Testbench: Error - Expected 0x00A0BEEF from Trigger Control reg for step 0"));
      writeline (OUTPUT, vLine);
      vTestFail := true;
    end if;

    LBusWrite(cPerSequenceStep, 16#00000001#, ToBusModel, FromBusModel);
    LBusRead(cTriggerCtrl, vRData, ToBusModel, FromBusModel);
    if vRData /= 16#00204567# then
      write (vLine, string'("Testbench: Error - Expected 0x00204567 from Trigger Control reg for step 1"));
      writeline (OUTPUT, vLine);
      vTestFail := true;
    end if;

    -- Setup Sequence length and start sequence
    LBusWrite(cPerSequenceCtrl, 16#80000001#, ToBusModel, FromBusModel);

    -- Read back sequence length
    LBusRead(cPerSequenceCtrl, vRData, ToBusModel, FromBusModel);
    if vRData /= 16#80000001# and vRData /= 16#C0000001# then
      write (vLine, string'("Testbench: Error - Expected 0x80000001 from Peripheral FPGA Sequence Control register"));
      writeline (OUTPUT, vLine);
      vTestFail := true;
    end if;

    -- Write description of test to output
    write (vLine, string'("Testbench: DSP FPGA Sequence Step register test"));
    writeline (OUTPUT, vLine);

    -- Write to the SRAM Control registers for Steps 0,1
    LBusWrite(cDspSequenceStep, 16#00000000#, ToBusModel, FromBusModel);
    LBusWrite(cDspSramCtrl, 16#00032ABC#, ToBusModel, FromBusModel);

    LBusWrite(cDspSequenceStep, 16#00000001#, ToBusModel, FromBusModel);
    LBusWrite(cDspSramCtrl, 16#000A0567#, ToBusModel, FromBusModel);

    -- Read the Gate Start/Stop register values back
    LBusWrite(cDspSequenceStep, 16#00000000#, ToBusModel, FromBusModel);
    LBusRead(cDspSramCtrl, vRData, ToBusModel, FromBusModel);
    if vRData /= 16#000A2ABC# then
      write (vLine, string'("Testbench: Error - Expected 0x000A2ABC from SRAM control reg for step 0"));
      writeline (OUTPUT, vLine);
      vTestFail := true;
    end if;

    LBusWrite(cDspSequenceStep, 16#00000001#, ToBusModel, FromBusModel);
    LBusRead(cDspSramCtrl, vRData, ToBusModel, FromBusModel);
    if vRData /= 16#000A0567# then
      write (vLine, string'("Testbench: Error - Expected 0x000A0567 from SRAM control reg for step 1"));
      writeline (OUTPUT, vLine);
      vTestFail := true;
    end if;

    -- Setup Sequence length and start sequence
    LBusWrite(cDspSequenceCtrl, 16#0000001#, ToBusModel, FromBusModel);

    -- Read back sequence length
    LBusRead(cDspSequenceCtrl, vRData, ToBusModel, FromBusModel);
    if vRData /= 16#00000001# then
      write (vLine, string'("Testbench: Error - Expected 0x00000001 from DSP FPGA Sequence Control register"));
      writeline (OUTPUT, vLine);
      vTestFail := true;
    end if;

    -- Write description of test to output
    write (vLine, string'("Testbench: Gate transfer between FPGAs test"));
    writeline (OUTPUT, vLine);

    -- Write to the Gate Start/Stop registers for Steps 0,1
    LBusWrite(cPerSequenceStep, 16#00000000#, ToBusModel, FromBusModel);
    LBusWrite(cGateStartStop, 16#DEADBEEF#, ToBusModel, FromBusModel);
    LBusWrite(cGateAttributes, 16#56700234#, ToBusModel, FromBusModel);

    LBusWrite(cPerSequenceStep, 16#00000001#, ToBusModel, FromBusModel);
    LBusWrite(cGateStartStop, 16#01234567#, ToBusModel, FromBusModel);
    LBusWrite(cGateAttributes, 16#ABC00256#, ToBusModel, FromBusModel);

    -- start interface gate transfer
    LBusWrite(cGateSetup, 16#00000000#, ToBusModel, FromBusModel);

    -- wait for transfer to complete
    vRData := 16#80000000#;
    while (conv_std_logic_vector(vRData, 32) and X"80000000") /= X"00000000" loop
      wait for 10 us;
      LBusRead(cGateSetup, vRData, ToBusModel, FromBusModel);
    end loop;

    -- start gate 7 transfer
    LBusWrite(cGateSetup, 16#00000007#, ToBusModel, FromBusModel);

    -- wait for transfer to complete
    vRData := 16#80000000#;
    while (conv_std_logic_vector(vRData, 32) and X"80000000") /= X"00000000" loop
      wait for 10 us;
      LBusRead(cGateSetup, vRData, ToBusModel, FromBusModel);
    end loop;

    -- Stop the simulation and report pass/fail
    if vTestFail then
      report "Testbench: Simulation completed - FAIL"
      severity failure;
    else
      report "Testbench: Simulation completed - PASS"
      severity failure;
    end if;

    wait;

  end process main;


end architecture Test;