---------------------------------------------------------------------------
-- NDT Solutions Ltd. Proprietary Information
-- Company Confidential
-- Copyright 2004
--
-- Filename: LocalBusModelPkg.vhd
-- Language: VHDL '93
-- Project:  Digitiser Card FPGAs
--
-- Design Description:
-- Package for Local Bus Model
---------------------------------------------------------------------------


library IEEE;
use IEEE.Std_Logic_1164.all;
use IEEE.Std_Logic_Arith.all;
use std.textio.all;


package LocalBusModelPkg is


  type tBurstData is array (1 to 256) of integer;

  -- Type holding signals to Bus Model
  type tToBusModel is
    record
      ClkPeriod         : time;
      NoOfWords         : integer;
      Write_nRead       : std_logic;
      Addr              : std_logic_vector(31 downto 0);
      Data              : std_logic_vector(31 downto 0);
      BurstData         : tBurstData;
      BurstMode         : std_ulogic;
      Start             : std_logic;
    end record;

  -- Type holding signals from Bus Model
  type tFromBusModel is
    record
      nLRESET           : std_ulogic;
      LCLKA             : std_ulogic;
      Data              : std_logic_vector(31 downto 0);
      BurstData         : tBurstData;
      Done              : std_ulogic;
    end record;

  -- Procedure to initialise the Bus Model
  procedure BusInit(ClkPeriod:           in  time;
                    signal ToBusModel:   out tToBusModel;
                    signal FromBusModel: in  tFromBusModel);

  -- Procedure to do a 32-bit read
  procedure LBusRead (Addr:                in  integer;
                      Data:                out integer;
                      signal ToBusModel:   out tToBusModel;
                      signal FromBusModel: in  tFromBusModel);

  -- Procedure to do a 32-bit write
  procedure LBusWrite (Addr:                in  integer;
                       Data:                in  integer;
                       signal ToBusModel:   out tToBusModel;
                       signal FromBusModel: in  tFromBusModel);

  procedure LBusBurstWrite (Addr:                in  integer;
                            BurstData:           in  tBurstData;
                            NoOfWords:           in  integer;
                            signal ToBusModel:   out tToBusModel;
                            signal FromBusModel: in  tFromBusModel);

  procedure LBusBurstRead (Addr:                in  integer;
                           BurstData:           out tBurstData;
                           NoOfWords:           in  integer;
                           signal ToBusModel:   out tToBusModel;
                           signal FromBusModel: in  tFromBusModel);


end package LocalBusModelPkg;



package body LocalBusModelPkg is

  -- Procedure to initialise the Bus Model
  procedure BusInit (ClkPeriod:              in  time;
                     signal ToBusModel:      out tToBusModel;
                     signal FromBusModel:    in  tFromBusModel) is
  begin
    ToBusModel.BurstMode   <= '0';
    ToBusModel.Write_nRead <= 'Z';
    ToBusModel.Addr        <= (others => 'Z');
    ToBusModel.Data        <= (others => 'Z');
    ToBusModel.ClkPeriod   <= ClkPeriod;
    ToBusModel.Start       <= 'L';
    ToBusModel.NoOfWords   <= 1;
    -- Wait until reset has completed + a couple of clock cycles
    wait on FromBusModel.nLRESET until rising_edge(FromBusModel.nLRESET);
    wait on FromBusModel.LCLKA until rising_edge(FromBusModel.LCLKA);
    wait on FromBusModel.LCLKA until rising_edge(FromBusModel.LCLKA);
  end procedure BusInit;


 -- Procedure to do a 32-bit read
 procedure LBusRead (Addr:                in  integer;
                     Data:                out integer;
                     signal ToBusModel:   out tToBusModel;
                     signal FromBusModel: in  tFromBusModel) is
 begin
   ToBusModel.BurstMode    <= '0';
   ToBusModel.NoOfWords    <= 1;
   ToBusModel.Write_nRead  <= '0';
   ToBusModel.Addr         <= conv_std_logic_vector(Addr, 32);
   ToBusModel.Start        <= '1';
   wait for 1 ns;
   ToBusModel.Start        <= 'L';
   wait until rising_edge(FromBusModel.Done);
   Data := conv_integer(unsigned(FromBusModel.Data));
   ToBusModel.Write_nRead  <= 'Z';
   ToBusModel.Addr         <= (others => 'Z');
 end procedure LBusRead;


 -- Procedure to do a 32-bit burst read
 procedure LBusBurstRead (Addr:                in  integer;
                          BurstData:           out tBurstData;
                          NoOfWords:           in  integer;
                          signal ToBusModel:   out tToBusModel;
                          signal FromBusModel: in  tFromBusModel) is
 begin
   ToBusModel.BurstMode    <= '1';
   ToBusModel.NoOfWords    <= NoOfWords;
   ToBusModel.Write_nRead  <= '0';
   ToBusModel.Addr         <= conv_std_logic_vector(Addr, 32);
   ToBusModel.Start        <= '1';
   wait for 1 ns;
   ToBusModel.Start        <= 'L';
   wait until rising_edge(FromBusModel.Done);
   BurstData := FromBusModel.BurstData;
   ToBusModel.Write_nRead  <= 'Z';
   ToBusModel.Addr         <= (others => 'Z');
 end procedure LBusBurstRead;


 -- Procedure to do a 32-bit write
 procedure LBusWrite (Addr:                in  integer;
                      Data:                in  integer;
                      signal ToBusModel:   out tToBusModel;
                      signal FromBusModel: in  tFromBusModel) is
 begin
   ToBusModel.BurstMode    <= '0';
   ToBusModel.NoOfWords    <= 1;
   ToBusModel.Write_nRead  <= '1';
   ToBusModel.Addr         <= conv_std_logic_vector(Addr, 32);
   ToBusModel.Data         <= conv_std_logic_vector(Data, 32);
   ToBusModel.Start        <= '1';
   wait for 1 ps;
   ToBusModel.Start        <= 'L';
   wait until rising_edge(FromBusModel.Done);
   ToBusModel.Write_nRead  <= 'Z';
   ToBusModel.Addr         <= (others => 'Z');
   ToBusModel.Data         <= (others => 'Z');
 end procedure LBusWrite;


 -- Procedure to do a 32-bit burst write
 procedure LBusBurstWrite (Addr:                in  integer;
                           BurstData:           in  tBurstData;
                           NoOfWords:           in  integer;
                           signal ToBusModel:   out tToBusModel;
                           signal FromBusModel: in  tFromBusModel) is
 begin
   ToBusModel.BurstMode    <= '1';
   ToBusModel.NoOfWords    <= NoOfWords;
   ToBusModel.Write_nRead  <= '1';
   ToBusModel.Addr         <= conv_std_logic_vector(Addr, 32);
   ToBusModel.BurstData    <= BurstData;
   ToBusModel.Start        <= '1';
   wait for 1 ps;
   ToBusModel.Start        <= 'L';
   wait until rising_edge(FromBusModel.Done);
   ToBusModel.Write_nRead  <= 'Z';
   ToBusModel.Addr         <= (others => 'Z');
   ToBusModel.Data         <= (others => 'Z');
 end procedure LBusBurstWrite;


end package body LocalBusModelPkg ;