---------------------------------------------------------------------------
-- NDT Solutions Ltd. Proprietary Information
-- Company Confidential
-- Copyright 2005
--
-- Filename: SimCtrl001.vhd
-- Language: VHDL '93
-- Project:  Pulse Receive Card FPGAs
--
-- Design Description:
-- Simulation Control file (001) for pulse receive card 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;


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#;

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

  constant cSysGlobalConfigReg:  integer := 16#005000f0#;
  constant cSysSeqTableBase:     integer := 16#00700000#;

begin

  -- Main Simulation Control process
  Main: process
    variable vAddr: integer;
    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;
    pHighVoltageOK <= '0';

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

    -- Write description of test to output
    write (vLine, string'("Testbench: Testing System Check Register"));
    writeline (OUTPUT, vLine);

    LBusRead(cSysCheckReg, vRData, ToBusModel, FromBusModel);
    if vRData /= 16#FFFFFFFF# then
      write (vLine, string'("Testbench: Error - Expected 0xFFFFFFFF from System Check register"));
      writeline (OUTPUT, vLine);
      vTestFail := true;
    end if;

    LBusWrite(cSysCheckReg, 16#5555AAAA#, ToBusModel, FromBusModel);
    LBusRead(cSysCheckReg, vRData, ToBusModel, FromBusModel);
    if vRData /= 16#AAAA5555# then
      write (vLine, string'("Testbench: Error - Expected 0xAAAA5555 from System Check register"));
      writeline (OUTPUT, vLine);
      vTestFail := true;
    end if;

    LBusWrite(cSysCheckReg, 16#00000001#, ToBusModel, FromBusModel);
    LBusRead(cSysStatusReg, vRData, ToBusModel, FromBusModel);
    LBusRead(cSysCheckReg, vRData, ToBusModel, FromBusModel);
    if vRData /= 16#FFFFFFFE# then
      write (vLine, string'("Testbench: Error - Expected 0xFFFFFFFE from System Check register"));
      writeline (OUTPUT, vLine);
      vTestFail := true;
    end if;

    write (vLine, string'("Testbench: System Check Register tests complete"));
    writeline (OUTPUT, vLine);

    -- Write description of test to output
    write (vLine, string'("Testbench: Testing Accesses to System SRAM"));
    writeline (OUTPUT, vLine);

    -- Write  a test pattern to the System SRAM
    for Offset in 0 to 16#50# loop
      vWData := 16#FFFFFFFF# - Offset;
      LBusWrite(cSysSramBase + (Offset*4), vWData, ToBusModel, FromBusModel);
    end loop;

    for Offset in 0 to 16#50# loop
      LBusRead(cSysSramBase + (Offset*4), vRData, ToBusModel, FromBusModel);
      if vRData /= 16#FFFFFFFF# - Offset then
        write (vLine, string'("Testbench: Error - Unexpected data read from System SRAM"));
        writeline (OUTPUT, vLine);
        vTestFail := true;
      end if;
    end loop;

    -- Test burst write and read from System SRAM
    -- not required for PRx 
--    vBurstData(1) := 16#01010101#;
--    vBurstData(2) := 16#02020202#;
--    vBurstData(3) := 16#03030303#;
--    vBurstData(4) := 16#04040404#;
--    vBurstData(5) := 16#05050505#;
--    vBurstData(6) := 16#06060606#;
--    vBurstData(7) := 16#07070707#;
--    vBurstData(8) := 16#08080808#;
--
--    LBusBurstWrite(cSysSramBase, vBurstData, 8, ToBusModel, FromBusModel);
--    LBusBurstRead(cSysSramBase, vReadBurstData, 8, ToBusModel, FromBusModel);
--
--    for Count in 1 to 8 loop
--      if vReadBurstData(Count) /= vBurstData(Count) then
--        write (vLine, string'("Testbench: Error - Unexpected data read from System SRAM (Burst access)"));
--        writeline (OUTPUT, vLine);
--        vTestFail := true;
--      end if;
--    end loop;

    write (vLine, string'("Testbench: System SRAM access tests complete"));
    writeline (OUTPUT, vLine);

--    LBusRead(16#00500004#, vRData, ToBusModel, FromBusModel);

    write (vLine, string'("Testbench: Testing Block RAM Buffer operation"));
    writeline (OUTPUT, vLine);
    -- Write to the System EEPROM Buffer
    LBusWrite(16#00600004#, 16#01234567#, ToBusModel, FromBusModel);

    wait for 100 ns;
    LBusRead(16#00600004#, vRData, ToBusModel, FromBusModel);
    if vRData /= 16#01234567# then
        write (vLine, string'("Testbench: Error - Unexpected data read from EEPROM Block RAM"));
        writeline (OUTPUT, vLine);
        vTestFail := true;
    end if;

    wait for 100 ns;
    vAddr := 16#00600000#;
    for Count in 1 to 8 loop
      vWData := 16#01010101# * Count;
      LBusWrite(vAddr, vWData, ToBusModel, FromBusModel);
      vAddr := vAddr + 4;
    end loop;
--    LBusBurstWrite(16#00600000#, vBurstData, 8, ToBusModel, FromBusModel);

    wait for 100 ns;
--    LBusBurstRead(16#00600000#, vReadBurstData, 8, ToBusModel, FromBusModel);
    vAddr := 16#00600000#;

    for Count in 1 to 8 loop
      LBusRead(vAddr, vRData, ToBusModel, FromBusModel);
--      if vBurstData(Count) /= vReadBurstData(Count) then
      if vRData /= (16#01010101# * Count) then
        write (vLine, string'("Testbench: Error - Unexpected data read from EEPROM Block RAM"));
        writeline (OUTPUT, vLine);
        vTestFail := true;
      end if;
      vAddr := vAddr + 4;
    end loop;

    wait for 100 ns;
    -- Load data from EEPROM to EEPROM Block RAM Buffer
    write (vLine, string'("Testbench: Testing EEPROM to EEPROM Block RAM Buffer operation"));
    writeline (OUTPUT, vLine);
    LBusWrite(cSysCommandReg, 16#00000004#, ToBusModel, FromBusModel);

    wait for 100 ns;
    vRData := 16#00000002#;
    while (conv_std_logic_vector(vRData, 32) and X"00000002") /= X"00000000" loop
      LBusRead(cSysStatusReg, vRData, ToBusModel, FromBusModel);
      wait for 100 us;
    end loop;

    wait for 300 ns;
    LBusRead(16#00600000#, vRData, ToBusModel, FromBusModel);
    if vRData /= 16#12345678# then
      write (vLine, string'("Testbench: Error - Expected 0x12345678 from EEPROM Block RAM Buffer"));
      writeline (OUTPUT, vLine);
      vTestFail := true;
    end if;
    LBusRead(16#00600004#, vRData, ToBusModel, FromBusModel);
    if vRData /= 16#DEADBEEF# then
      write (vLine, string'("Testbench: Error - Expected 0xDEADBEEF from EEPROM Block RAM Buffer"));
      writeline (OUTPUT, vLine);
      vTestFail := true;
    end if;
    LBusRead(16#00600008#, vRData, ToBusModel, FromBusModel);
    if vRData /= 16#FEEDB00B# then
      write (vLine, string'("Testbench: Error - Expected 0xFEEDBOOB from EEPROM Block RAM Buffer"));
      writeline (OUTPUT, vLine);
      vTestFail := true;
    end if;
    LBusRead(16#0060000C#, vRData, ToBusModel, FromBusModel);
    if vRData /= 16#FEDCBA98# then
      write (vLine, string'("Testbench: Error - Expected 0xFEDCBA98 from EEPROM Block RAM Buffer"));
      writeline (OUTPUT, vLine);
      vTestFail := true;
    end if;
    wait for 300 ns;

    -- Save data in EEPROM Block RAM Buffer to EEPROM
    write (vLine, string'("Testbench: Testing EEPROM Block RAM Buffer to EEPROM operation"));
    writeline (OUTPUT, vLine);
    LBusWrite(cSysCommandReg, 16#00000002#, ToBusModel, FromBusModel);

    wait for 100 ns;
    vRData := 16#00000002#;
    while (conv_std_logic_vector(vRData, 32) and X"00000002") /= X"00000000" loop
      LBusRead(cSysStatusReg, vRData, ToBusModel, FromBusModel);
      wait for 100 us;
    end loop;

    -- Write description of test to output
    write (vLine, string'("Testbench: Testing HV Status Register bit"));
    writeline (OUTPUT, vLine);

    LBusRead(cSysStatusReg, vRData, ToBusModel, FromBusModel);
    if (conv_std_logic_vector(vRData, 32) and X"00000008") /= X"00000000" then
      write (vLine, string'("Testbench: Error - Expected 0 from HV Status Read"));
      writeline (OUTPUT, vLine);
      vTestFail := true;
    end if;
    pHighVoltageOK <= '1';
    wait for 100 us;
    LBusRead(cSysStatusReg, vRData, ToBusModel, FromBusModel);
    if (conv_std_logic_vector(vRData, 32) and X"00000008") /= X"00000008" then
      write (vLine, string'("Testbench: Error - Expected 1 from HV Status Read"));
      writeline (OUTPUT, vLine);
      vTestFail := true;
    end if;
    pHighVoltageOK <= '0';
    wait for 100 us;
    LBusRead(cSysStatusReg, vRData, ToBusModel, FromBusModel);
    if (conv_std_logic_vector(vRData, 32) and X"00000008") /= X"00000000" then
      write (vLine, string'("Testbench: Error - Expected 0 from HV Status Read"));
      writeline (OUTPUT, vLine);
      vTestFail := true;
    end if;

    wait for 100 ns;

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

    wait;

  end process main;


end architecture Test;