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

📄 ovm_sequencer_base.svh

📁 This is OVM 2.0 source code .Very useful for developing system verilog Env
💻 SVH
📖 第 1 页 / 共 3 页
字号:
          avail_sequences.delete(i);          i--;        end      end      if (avail_sequences.size() < 1) return (-1);      if (avail_sequences.size() == 1) return (avail_sequences[0]);    end    ///////////////////////////////////    //  Weighted Priority Distribution    ///////////////////////////////////    if (arbitration == SEQ_ARB_WEIGHTED) begin      sum_priority_val = 0;      for (i = 0; i < avail_sequences.size(); i++) begin        sum_priority_val += get_seq_item_priority(arb_sequence_q[avail_sequences[i]]);      end            // Pick an available sequence based on weighted priorities of available sequences      temp = $urandom_range(sum_priority_val-1, 0);      sum_priority_val = 0;      for (i = 0; i < avail_sequences.size(); i++) begin        if ((get_seq_item_priority(arb_sequence_q[avail_sequences[i]]) +              sum_priority_val) > temp) begin          return (avail_sequences[i]);        end        sum_priority_val += get_seq_item_priority(arb_sequence_q[avail_sequences[i]]);      end      ovm_report_fatal("Sequencer", "OVM Internal error in weighted arbitration code");    end // if (arbitration == SEQ_ARB_WEIGHTED)        ///////////////////////////////////    //  Random Distribution    ///////////////////////////////////    if (arbitration == SEQ_ARB_RANDOM) begin      i = $urandom_range(avail_sequences.size()-1, 0);      return (avail_sequences[i]);    end    ///////////////////////////////////    //  Strict Fifo    ///////////////////////////////////    if ((arbitration == SEQ_ARB_STRICT_FIFO) || arbitration == SEQ_ARB_STRICT_RANDOM) begin      highest_pri = 0;      // Build a list of sequences at the highest priority      for (i = 0; i < avail_sequences.size(); i++) begin        if (get_seq_item_priority(arb_sequence_q[avail_sequences[i]]) > highest_pri) begin          // New highest priority, so start new list          `ovm_clear_queue(highest_sequences)          highest_sequences.push_back(i);          highest_pri = get_seq_item_priority(arb_sequence_q[avail_sequences[i]]);        end        else if (get_seq_item_priority(arb_sequence_q[avail_sequences[i]]) == highest_pri) begin          highest_sequences.push_back(i);        end      end      // Now choose one based on arbitration type      if (arbitration == SEQ_ARB_STRICT_FIFO) begin        return(highest_sequences[0]);      end            i = $urandom_range(highest_sequences.size()-1, 0);      return (highest_sequences[i]);    end // if ((arbitration == SEQ_ARB_STRICT_FIFO) || arbitration == SEQ_ARB_STRICT_RANDOM)    if (arbitration == SEQ_ARB_USER) begin      i = user_priority_arbitration(avail_sequences);      // Check that the returned sequence is in the list of available sequences.  Failure to      // use an available sequence will cause highly unpredictable results.      highest_sequences = avail_sequences.find with (item == i);      if (highest_sequences.size() == 0) begin        ovm_report_fatal("Sequencer", $psprintf("Error in User arbitration, sequence %0d not available\n%s",                                                i, display_queues()));      end      return(i);    end          ovm_report_fatal("Sequencer", "Internal error: Failed to choose sequence");  endfunction // int  protected task m_wait_arb_not_equal();    wait (m_arb_size != m_lock_arb_size);  endtask // m_wait_arb_not_equal  protected task wait_for_available_sequence();    integer i;    integer is_relevant_entries[$];    // This routine will wait for a change in the request list, or for    // wait_for_relevant to return on any non-relevant, non-blocked sequence    m_arb_size = m_lock_arb_size;    for (i = 0; i < arb_sequence_q.size(); i++) begin      if (arb_sequence_q[i].request == SEQ_TYPE_REQ) begin        if (is_blocked(arb_sequence_q[i].sequence_ptr) == 0) begin          if (arb_sequence_q[i].sequence_ptr.is_relevant() == 0) begin            is_relevant_entries.push_back(i);          end        end      end    end    // Typical path - don't need fork if all queued entries are relevant    if (is_relevant_entries.size() == 0) begin      m_wait_arb_not_equal();      return;    end    fork  // isolate inner fork block for disabling      begin        fork          begin            fork              // One path in fork is for any wait_for_relevant to return              for(i = 0; i < is_relevant_entries.size(); i++) begin                fork                  begin                    arb_sequence_q[is_relevant_entries[i]].sequence_ptr.wait_for_relevant();                  end                join_any              end              // The other path in the fork is for any queue entry to change              begin                m_wait_arb_not_equal();              end            join_any          end        join_any        disable fork;      end // fork    join  endtask // wait_for_available_sequence  protected function integer get_seq_item_priority(seq_req_class seq_q_entry);    // If the priority was set on the item, then that is used    if (seq_q_entry.item_priority != -1) begin      return (seq_q_entry.item_priority);    end    // Otherwise, use the priority of the calling sequence    return (seq_q_entry.sequence_ptr.get_priority());  endfunction    ///////////////////////////////////////////////////  //  // arbitration completed tasks  //    Used to tell the wait_for_grant function when  //    a new arbitration is available  ///////////////////////////////////////////////////    task wait_for_arbitration_completed(integer request_id);    int lock_arb_size;        // Search the list of arb_wait_q, see if this item is done    forever       begin        lock_arb_size  = m_lock_arb_size;                if (arb_completed.exists(request_id)) begin          arb_completed.delete(request_id);          return;        end        wait (lock_arb_size != m_lock_arb_size);      end  endtask // wait_for_arbitration_completed  function void set_arbitration_completed(integer request_id);    arb_completed[request_id] = 1;  endfunction // void/////////////////////////////////////////////////////// is_child//    Determine if a scenario is a child of a parent///////////////////////////////////////////////////function bit is_child (ovm_sequence_base parent, ovm_sequence_base child);    ovm_sequence_base sequence_ptr;    if (child == null) begin      ovm_report_fatal("ovm_sequencer", "is_child passed null child");    end    if (parent == null) begin      ovm_report_fatal("ovm_sequencer", "is_child passed null parent");    end    sequence_ptr = child.get_parent_sequence();    while (sequence_ptr != null) begin      if (sequence_ptr.m_get_sqr_sequence_id(m_sequencer_id, 0) ==           (parent.m_get_sqr_sequence_id(m_sequencer_id, 0))) begin        return (1);      end      sequence_ptr = sequence_ptr.get_parent_sequence();    end    return (0);endfunction // bit  ///////////////////////////////////////////////////  //  // Methods available to Sequences  //   ///////////////////////////////////////////////////    task wait_for_grant(ovm_sequence_base sequence_ptr, integer item_priority = -1, bit lock_request = 0);    seq_req_class req_s;    integer my_seq_id;    if (sequence_ptr == null) begin      ovm_report_fatal("ovm_sequencer", "wait_for_grant passed null sequence_ptr");    end    my_seq_id = register_sequence(sequence_ptr);        // If lock_request is asserted, then issue a lock.  Don't wait for the response, since    // there is a request immediately following the lock request    if (lock_request == 1) begin      req_s = new();      req_s.grant = 0;      req_s.sequence_id = sequence_ptr.get_sequence_id();      req_s.request = SEQ_TYPE_LOCK;      req_s.sequence_ptr = sequence_ptr;      req_s.request_id = req_s.g_request_id++;      arb_sequence_q.push_back(req_s);    end // lock_request == 1            // Push the request onto the queue    req_s = new();    req_s.grant = 0;    req_s.request = SEQ_TYPE_REQ;    req_s.sequence_id = my_seq_id;    req_s.item_priority = item_priority;    req_s.sequence_ptr = sequence_ptr;    req_s.request_id = req_s.g_request_id++;    arb_sequence_q.push_back(req_s);    m_update_lists();    // Wait until this entry is granted    // Continue to point to the element, since location in queue will change    wait_for_arbitration_completed(req_s.request_id);  endtask // wait_for_grant  task wait_for_item_done(ovm_sequence_base sequence_ptr, integer transaction_id);    integer sequence_id;    sequence_id = sequence_ptr.m_get_sqr_sequence_id(m_sequencer_id, 1);    m_wait_for_item_sequence_id = -1;    m_wait_for_item_transaction_id = -1;    if (transaction_id == -1) begin      wait (m_wait_for_item_sequence_id == sequence_id);    end else begin      wait ((m_wait_for_item_sequence_id == sequence_id &&             m_wait_for_item_transaction_id == transaction_id));    end  endtask // wait_for_item_done///////////////////////////////////////////////////////  function bit is_blocked(ovm_sequence_base sequence_ptr);////  is_blocked will return 1 if the sequence refered to in the parameter//  is currently locked out of the sequencer.  It will return 0 if the//  sequence is currently allowed to issue operations////  Note that even when a sequence is not blocked, it is possible//  for another sequence to issue a lock before this sequence is able//  to issue a request or lock/////////////////////////////////////////////////////  function bit is_blocked(ovm_sequence_base sequence_ptr);    if (sequence_ptr == null)      ovm_report_fatal("ovm_sequence_controller", "is_blocked passed null sequence_ptr");      foreach (lock_list[i]) begin        if ((lock_list[i].m_get_sqr_sequence_id(m_sequencer_id, 0) !=              sequence_ptr.m_get_sqr_sequence_id(m_sequencer_id, 0)) &&            (is_child(lock_list[i], sequence_ptr) == 0)) begin          return (1);        end      end       return (0);endfunction /////////////////////////////////////////////////////////  function bit is_locked(ovm_sequence_base sequence_ptr);////  is_locked returns 1 if the sequence refered to in the parameter//  currently has a lock on this sequencer.  It will return 0 if the//  sequence does not currently have a lock.// //  Note that even if this sequence has a lock, a child sequence may//  also have a lock, in which case the sequence is still blocked from//  issueing operations on the sequencer/////////////////////////////////////////////////////  function bit is_locked(ovm_sequence_base sequence_ptr);    integer my_seq_id;        if (sequence_ptr == null)      ovm_report_fatal("ovm_sequence_controller", "is_locked passed null sequence_ptr");    my_seq_id = register_sequence(sequence_ptr);      foreach (lock_list[i]) begin        if (lock_list[i].m_get_sqr_sequence_id(m_sequencer_id, 0) ==             sequence_ptr.m_get_sqr_sequence_id(m_sequencer_id, 0)) begin          return (1);        end      end     return (0);endfunction // bit/////////////////////////////////////////////////////// lock_req//    Internal Call by a sequence to request a lock.  Puts//    the lock request onto the arbitration queue

⌨️ 快捷键说明

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