⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ovm_sequencer_base.svh

📁 This is OVM 2.0 source code .Very useful for developing system verilog Env
💻 SVH
📖 第 1 页 / 共 3 页
字号:
//----------------------------------------------------------------------//   Copyright 2007-2008 Mentor Graphics Corporation//   Copyright 2007-2008 Cadence Design Systems, 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.//----------------------------------------------------------------------typedef class ovm_sequencer_base;typedef enum {SEQ_TYPE_REQ, SEQ_TYPE_LOCK, SEQ_TYPE_GRAB} SEQ_REQ_TYPE;typedef enum {SEQ_ARB_FIFO, SEQ_ARB_WEIGHTED, SEQ_ARB_RANDOM, SEQ_ARB_STRICT_FIFO, SEQ_ARB_STRICT_RANDOM, SEQ_ARB_USER}         SEQ_ARB_TYPE;class seq_req_class;  static integer    g_request_id = 0;  bit               grant;  integer           sequence_id;  integer           request_id;  integer           item_priority;  SEQ_REQ_TYPE      request;  ovm_sequence_base sequence_ptr;  function new(string name= "");  endfunctionendclass  class ovm_sequencer_base extends ovm_component;  protected seq_req_class       arb_sequence_q[$];  // The arb_completed associative array is used to indicate when a particular request_id  // has been completed.  The array in indexed by request_id, and sequences will wait based  // on the request_id assigned in the arb_sequence_q  protected bit                 arb_completed[integer];  protected ovm_sequence_base   lock_list[$];  local     SEQ_ARB_TYPE        arbitration = SEQ_ARB_FIFO;  local     ovm_sequence_base   reg_sequences[integer];  local     static integer      g_sequence_id = 1;  local     static integer      g_sequencer_id = 1;  protected integer             m_sequencer_id;  protected integer             m_lock_arb_size;  // used for waiting processes  protected integer             m_arb_size;       // used for waiting processes  protected integer             m_wait_for_item_sequence_id, m_wait_for_item_transaction_id;            integer unsigned    pound_zero_count = 4;             ///// Copied from ovm_sequencer  //set main and random sequence count variable if != -1  //also accessed by ovm_main/random_sequence   integer count = -1;  // testing fields  integer m_random_count = 0;  integer m_exhaustive_count = 0;  integer m_simple_count = 0;  //user settable property to limit main/random subsequences   //also accessed by ovm_main/random_sequence   integer unsigned max_random_count = 10;  //Used for setting the maximum depth inside random sequences.   //(Beyond that depth, random creates only simple sequences.)  int unsigned max_random_depth = 4;  // This property defines which sequence will be auto-started (default=main).  protected string default_sequence = "ovm_random_sequence";                 // The sequeunce aray holds the type names of the sequence types registered  // to this sequencer; the factory will actually create the instances on demand.  string sequences[$];  // The ids array associates each sequence entry (above) with an integer  // number. This allows sequences to be randomly selected by randomizing  // a number between 0 and the sequences array size.  protected integer sequence_ids[string];  // variable used to randomly select a sequence from the sequences array  protected rand integer seq_kind;///// End of Copied from ovm_sequencer    ///////////////////////////////////////////////////    function new (string name, ovm_component parent);    super.new(name, parent);    void'(get_config_string("default_sequence", default_sequence));    void'(get_config_int("count", count));    void'(get_config_int("max_random_count", max_random_count));    void'(get_config_int("max_random_depth", max_random_depth));    void'(get_config_int("pound_zero_count", pound_zero_count));    m_sequencer_id = g_sequencer_id++;    m_lock_arb_size = -1;  endfunction // new  function void do_print (ovm_printer printer);    super.do_print(printer);    if(sequences.size() != 0) begin      printer.print_string("default_sequence", default_sequence);      printer.print_field("count", count, $bits(count), OVM_DEC);      printer.print_field("max_random_count", max_random_count,         $bits(max_random_count), OVM_DEC);      printer.print_array_header("sequences", sequences.size());      for(int i=0; i<sequences.size(); ++i)        printer.print_string($psprintf("[%0d]", i), sequences[i], "[");      printer.print_array_footer();      printer.print_field("max_random_depth", max_random_depth,         $bits(max_random_depth), OVM_DEC);    end  endfunction   ///////////////////////////////////////////////////  //  // Local functions  //  ///////////////////////////////////////////////////  protected function void m_update_lists();    m_lock_arb_size++;  endfunction // void  function string display_queues();    string s;        $sformat(s, "  -- arb i/id/type: ");    foreach (arb_sequence_q[i]) begin      $sformat(s, "%s %0d/%0d/%s ", s, i, arb_sequence_q[i].sequence_id, arb_sequence_q[i].request);    end // UNMATCHED !!    $sformat(s, "%s\n -- lock_list i/id: ", s);    foreach (lock_list[i]) begin      $sformat(s, "%s %0d/%0d",s, i, lock_list[i].get_sequence_id());    end // UNMATCHED !!    return(s);  endfunction // string  local function integer next_sequence_id();    return(g_sequence_id++);  endfunction // int  ///////////////////////////////////////////////////  //  // Local Sequence Registration Functions  //  ///////////////////////////////////////////////////  protected function integer register_sequence(ovm_sequence_base sequence_ptr);    if (sequence_ptr.m_get_sqr_sequence_id(m_sequencer_id, 1) > 0) begin      return (sequence_ptr.get_sequence_id());    end        sequence_ptr.m_set_sqr_sequence_id(m_sequencer_id, next_sequence_id());    reg_sequences[sequence_ptr.get_sequence_id()] = sequence_ptr;    return(sequence_ptr.get_sequence_id());  endfunction  protected function ovm_sequence_base find_sequence(integer sequence_id);    ovm_sequence_base seq_ptr;    integer           i;        // When sequence_id is -1, return the first available sequence.  This is used    // when deleting all sequences    if (sequence_id == -1) begin      if (reg_sequences.first(i)) begin        return(reg_sequences[i]);      end      return(null);    end        if (reg_sequences.exists(sequence_id) == 0) begin//      ovm_report_warning("find_sequence", //                         $psprintf("Sequence %d doesn't exist (find_sequence)", sequence_id));      return (null);    end    return(reg_sequences[sequence_id]);  endfunction    protected function void unregister_sequence(integer sequence_id);    if (reg_sequences.exists(sequence_id) == 0) begin//      ovm_report_warning("unregister_sequence", //                         $psprintf("Sequence %d doesn't exist (unregister_sequence)", sequence_id));    end    reg_sequences.delete(sequence_id);  endfunction    ///////////////////////////////////////////////////  //  // virtual function integer user_priority_arbitration(integer avail_sequences[$]);  //  // If a user specifies that the sequencer is to use user_priority_arbitration  // through the call set_arbitration(SEQ_ARB_USER), then the sequencer will  // call this function each time that it needs to arbitrate among sequences.  //  // This function must return an integer that matches one of the available  // sequences that is passed into the call through the avail_sequences parameter  //  // Each integer in avail_sequences points to an entry in the arb_sequence_q,   // which is a protected queue that may be accessed from this function.  //  // To modify the operation of user_priority_arbitration, the function may  // arbitrarily choose any sequence among the list of avail_sequences.  It is  // important to choose only an available sequence.  //  // The default implementation is FIFO, which simply returns the first integer  // in the avail_sequences array  ///////////////////////////////////////////////////    virtual function integer user_priority_arbitration(integer avail_sequences[$]);    return (avail_sequences[0]);  endfunction // user_priority_arbitration  ///////////////////////////////////////////////////  //  // grant_queued_locks  //    Any lock or grab requests that are at the front of the  //    queue will be granted at the earliest possible time.  //  //    This function grants any queues at the front that are  //    not locked out  ///////////////////////////////////////////////////    protected function void grant_queued_locks();    integer i, temp;    for (i = 0; i < arb_sequence_q.size(); i++) begin            // Check for lock requests.  Any lock request at the head      // of the queue that is not blocked will be granted immediately.      temp = 0;      if (i < arb_sequence_q.size()) begin        if (arb_sequence_q[i].request == SEQ_TYPE_LOCK) begin          temp = (is_blocked(arb_sequence_q[i].sequence_ptr) == 0);        end      end      // Grant the lock request and remove it from the queue.      // This is a loop to handle multiple back-to-back locks.      // Since each entry is deleted, i remains constant      while (temp) begin        lock_list.push_back(arb_sequence_q[i].sequence_ptr);        set_arbitration_completed(arb_sequence_q[i].request_id);        arb_sequence_q.delete(i);        m_update_lists();        temp = 0;        if (i < arb_sequence_q.size()) begin          if (arb_sequence_q[i].request == SEQ_TYPE_LOCK) begin            temp = is_blocked(arb_sequence_q[i].sequence_ptr) == 0;          end        end      end    end // for (i = 0; i < arb_sequence_q.size(); i++)  endfunction // void      ///////////////////////////////////////////////////  //  // choose_next_request  //    When a driver requests an operation, this function  //    must find the next available, unlocked, relevant sequence  //  //    This function returns -1 if no sequences are available  //    or the entry into arb_sequence_q for the chosen sequence  ///////////////////////////////////////////////////    protected function integer choose_next_request();    integer i, temp;    integer avail_sequence_count;    integer sum_priority_val;    integer avail_sequences[$];    integer highest_sequences[$];    integer highest_pri;    string  s;    avail_sequence_count = 0;    grant_queued_locks();    for (i = 0; i < arb_sequence_q.size(); i++) begin      // Search for available sequences.  If in SEQ_ARB_FIFO arbitration,      // then just return the first available sequence.  Otherwise,      // create a list for arbitration purposes.      if (i < arb_sequence_q.size())        if (arb_sequence_q[i].request == SEQ_TYPE_REQ)          if (is_blocked(arb_sequence_q[i].sequence_ptr) == 0)            if (arb_sequence_q[i].sequence_ptr.is_relevant() == 1) begin              if (arbitration == SEQ_ARB_FIFO) begin                return (i);              end              else avail_sequences.push_back(i);            end    end // for (i = 0; i < arb_sequence_q.size(); i++)    // Return immediately if there are 0 or 1 available sequences    if (arbitration == SEQ_ARB_FIFO) begin      return (-1);    end    if (avail_sequences.size() < 1)  begin      return (-1);    end        if (avail_sequences.size() == 1) begin      return (avail_sequences[0]);    end        // If any locks are in place, then the available queue must    // be checked to see if a lock prevents any sequence from proceeding    if (lock_list.size() > 0) begin      for (i = 0; i < avail_sequences.size(); i++) begin        if (is_blocked(arb_sequence_q[avail_sequences[i]].sequence_ptr) != 0) begin

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -