//----------------------------------------------------------------------
//   Copyright 2007-2011 Mentor Graphics Corporation
//   Copyright 2007-2011 Cadence Design Systems, Inc. 
//   Copyright 2010 Synopsys, Inc.
//   All Rights Reserved Worldwide
//
//   Licensed under the Apache License, Version 2.0 (the
//   "License"); you may not use this file except in
//   compliance with the License.  You may obtain a copy of
//   the License at
//
//       http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in
//   writing, software distributed under the License is
//   distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
//   CONDITIONS OF ANY KIND, either express or implied.  See
//   the License for the specific language governing
//   permissions and limitations under the License.
//----------------------------------------------------------------------


//------------------------------------------------------------------------------
//
// CLASS: uvm_sequencer #(REQ,RSP)
//
//------------------------------------------------------------------------------

class uvm_sequencer #(type REQ=uvm_sequence_item, RSP=REQ)
                                   extends uvm_sequencer_param_base #(REQ, RSP);

  typedef uvm_sequencer #( REQ , RSP) this_type;

  bit sequence_item_requested;
  bit get_next_item_called;

  `uvm_component_param_utils(this_type)

  // Variable: seq_item_export
  //
  // This export provides access to this sequencer's implementation of the
  // sequencer interface, <uvm_sqr_if_base #(REQ,RSP)>, which defines the following
  // methods:
  //
  //| Requests:
  //|  virtual task          get_next_item      (output REQ request);
  //|  virtual task          try_next_item      (output REQ request);
  //|  virtual task          get                (output REQ request);
  //|  virtual task          peek               (output REQ request);
  //| Responses:
  //|  virtual function void item_done          (input RSP response=null);
  //|  virtual task          put                (input RSP response);
  //| Sync Control:
  //|  virtual task          wait_for_sequences ();
  //|  virtual function bit  has_do_available   ();
  //
  // See <uvm_sqr_if_base #(REQ,RSP)> for information about this interface.

  uvm_seq_item_pull_imp #(REQ, RSP, this_type) seq_item_export;



  // Function: new
  //
  // Standard component constructor that creates an instance of this class
  // using the given ~name~ and ~parent~, if any.
  //
  extern function new (string name, uvm_component parent=null);
  

  // Function: stop_sequences
  //
  // Tells the sequencer to kill all sequences and child sequences currently
  // operating on the sequencer, and remove all requests, locks and responses
  // that are currently queued.  This essentially resets the sequencer to an
  // idle state.
  //
  extern virtual function void stop_sequences();


  extern virtual function string get_type_name();

  
  //-----------------
  // Internal Methods
  //-----------------
  // Do not use directly; not part of standard

  // Access to following internal methods provided via seq_item_export
  extern virtual task          get_next_item (output REQ t);
  extern virtual task          try_next_item (output REQ t);
  extern virtual function void item_done     (RSP item = null);
  extern virtual task          put           (RSP t);
  extern task                  get           (output REQ t);
  extern task                  peek          (output REQ t);
  extern function void         item_done_trigger(RSP item = null);
  function RSP                 item_done_get_trigger_data();
    return last_rsp(0);
  endfunction

  extern protected virtual function int m_find_number_driver_connections();

endclass  


typedef uvm_sequencer #(uvm_sequence_item) uvm_virtual_sequencer;



//------------------------------------------------------------------------------
// IMPLEMENTATION
//------------------------------------------------------------------------------

function uvm_sequencer::new (string name, uvm_component parent=null);
  super.new(name, parent);
  seq_item_export = new ("seq_item_export", this);
endfunction


// Function- stop_sequences
//
// Tells the sequencer to kill all sequences and child sequences currently
// operating on the sequencer, and remove all requests, locks and responses
// that are currently queued.  This essentially resets the sequencer to an
// idle state.
//
function void uvm_sequencer::stop_sequences();
  REQ t;
  super.stop_sequences();
  sequence_item_requested  = 0;
  get_next_item_called     = 0;
  // Empty the request fifo
  if (m_req_fifo.used()) begin
    uvm_report_info(get_full_name(), "Sequences stopped.  Removing request from sequencer fifo");
    while (m_req_fifo.try_get(t));
  end
endfunction


function string uvm_sequencer::get_type_name();
  return "uvm_sequencer";
endfunction 


//-----------------
// Internal Methods
//-----------------

// m_find_number_driver_connections
// --------------------------------
// Counting the number of of connections is done at end of
// elaboration and the start of run.  If the user neglects to
// call super in one or the other, the sequencer will still
// have the correct value

function int uvm_sequencer::m_find_number_driver_connections();
  uvm_port_component_base provided_to_port_list[string];
  uvm_port_component_base seq_port_base;
  
  // Check that the seq_item_pull_port is connected
  seq_port_base = seq_item_export.get_comp();
  seq_port_base.get_provided_to(provided_to_port_list);
  return provided_to_port_list.num();
endfunction


// get_next_item
// -------------

task uvm_sequencer::get_next_item(output REQ t);
  REQ req_item;

  // If a sequence_item has already been requested, then get_next_item()
  // should not be called again until item_done() has been called.

  if (get_next_item_called == 1)
    uvm_report_error(get_full_name(),
      "Get_next_item called twice without item_done or get in between", UVM_NONE);
  
  if (!sequence_item_requested)
    m_select_sequence();

  // Set flag indicating that the item has been requested to ensure that item_done or get
  // is called between requests
  sequence_item_requested = 1;
  get_next_item_called = 1;
  m_req_fifo.peek(t);
endtask


// try_next_item
// -------------

task uvm_sequencer::try_next_item(output REQ t);
  int selected_sequence;
  time arb_time;
  uvm_sequence_base seq;

  if (get_next_item_called == 1) begin
    uvm_report_error(get_full_name(), "get_next_item/try_next_item called twice without item_done or get in between", UVM_NONE);
    return;
  end
    
  // allow state from last transaction to settle such that sequences'
  // relevancy can be determined with up-to-date information
  wait_for_sequences();

  // choose the sequence based on relevancy
  selected_sequence = m_choose_next_request();

  // return if none available
  if (selected_sequence == -1) begin
    t = null;
    return;
  end

  // now, allow chosen sequence to resume
  m_set_arbitration_completed(arb_sequence_q[selected_sequence].request_id);
  seq = arb_sequence_q[selected_sequence].sequence_ptr;
  arb_sequence_q.delete(selected_sequence);
  m_update_lists();
  sequence_item_requested = 1;
  get_next_item_called = 1;

  // give it one NBA to put a new item in the fifo
  wait_for_sequences();

  // attempt to get the item; if it fails, produce an error and return
  if (!m_req_fifo.try_peek(t))
    uvm_report_error("TRY_NEXT_BLOCKED", {"try_next_item: the selected sequence '",
      seq.get_full_name(), "' did not produce an item within an NBA delay. ",
      "Sequences should not consume time between calls to start_item and finish_item. ",
      "Returning null item."}, UVM_NONE);

endtask


// item_done
// ---------

function void uvm_sequencer::item_done(RSP item = null);
  REQ t;

  // Set flag to allow next get_next_item or peek to get a new sequence_item
  sequence_item_requested = 0;
  get_next_item_called = 0;
  
  if (m_req_fifo.try_get(t) == 0) begin
    uvm_report_fatal(get_full_name(), {"Item_done() called with no outstanding requests.",
      " Each call to item_done() must be paired with a previous call to get_next_item()."});
  end else begin
    m_wait_for_item_sequence_id = t.get_sequence_id();
    m_wait_for_item_transaction_id = t.get_transaction_id();
  end
  
  if (item != null) begin
    seq_item_export.put_response(item);
  end

  // Grant any locks as soon as possible
  grant_queued_locks();
endfunction


// put
// ---

task uvm_sequencer::put (RSP t);
  put_response(t);
endtask


// get
// ---

task uvm_sequencer::get(output REQ t);
  if (sequence_item_requested == 0) begin
    m_select_sequence();
  end
  sequence_item_requested = 1;
  m_req_fifo.peek(t);
  item_done();
endtask


// peek
// ----

task uvm_sequencer::peek(output REQ t);

  if (sequence_item_requested == 0) begin
    m_select_sequence();
  end
  
  // Set flag indicating that the item has been requested to ensure that item_done or get
  // is called between requests
  sequence_item_requested = 1;
  m_req_fifo.peek(t);
endtask


// item_done_trigger
// -----------------

function void uvm_sequencer::item_done_trigger(RSP item = null);
  item_done(item);
endfunction



