00001 // Class which implements the in order by producer compare algorithm 00002 class cl_syoscb_compare_iop extends cl_syoscb_compare_base; 00003 //------------------------------------- 00004 // UVM Macros 00005 //------------------------------------- 00006 `uvm_object_utils(cl_syoscb_compare_iop) 00007 00008 //------------------------------------- 00009 // Constructor 00010 //------------------------------------- 00011 extern function new(string name = "cl_syoscb_compare_iop"); 00012 00013 //------------------------------------- 00014 // Compare API 00015 //------------------------------------- 00016 extern virtual function void compare(); 00017 extern function void compare_do(); 00018 endclass: cl_syoscb_compare_iop 00019 00020 function cl_syoscb_compare_iop::new(string name = "cl_syoscb_compare_iop"); 00021 super.new(name); 00022 endfunction: new 00023 00024 /// <b>Compare API</b>: Mandatory overwriting of the base class' compare method. 00025 /// Currently, this just calls do_copy() blindly 00026 function void cl_syoscb_compare_iop::compare(); 00027 // Here any state variables should be queried 00028 // to compute if the compare should be done or not 00029 this.compare_do(); 00030 endfunction: compare 00031 00032 /// <b>Compare API</b>: Mandatory overwriting of the base class' do_compare method. 00033 /// Here the actual out of order compare is implemented. 00034 /// 00035 /// The algorithm gets the primary queue and then loops over all other queues to see if 00036 /// it can find the primary item as the first item of the same producer in all of the other queues. 00037 /// If so then the items are removed from all queues. If not then nothing is done. Thus, if some items are not 00038 /// matched then the result is that the queue will be non-empty at the end of simulation. 00039 /// This will then be caught by the check_phase. 00040 function void cl_syoscb_compare_iop::compare_do(); 00041 string primary_queue_name; 00042 cl_syoscb_queue primary_queue; 00043 cl_syoscb_queue_iterator_base primary_queue_iter; 00044 string queue_names[]; 00045 int unsigned secondary_item_found[string]; 00046 bit compare_continue = 1'b1; 00047 bit compare_result = 1'b0; 00048 cl_syoscb_item primary_item; 00049 00050 // Initialize state variables 00051 primary_queue_name = this.get_primary_queue_name(); 00052 this.cfg.get_queues(queue_names); 00053 00054 primary_queue = this.cfg.get_queue(primary_queue_name); 00055 if(primary_queue == null) begin 00056 `uvm_fatal("QUEUE_ERROR", $sformatf("[%s]: cmp-iop: Unable to retrieve primary queue handle", this.cfg.get_scb_name())); 00057 end 00058 00059 primary_queue_iter = primary_queue.create_iterator(); 00060 00061 `uvm_info("DEBUG", $sformatf("[%s]: cmp-iop: primary queue: %s", this.cfg.get_scb_name(), primary_queue_name), UVM_FULL); 00062 `uvm_info("DEBUG", $sformatf("[%s]: cmp-iop: number of queues: %0d", this.cfg.get_scb_name(), queue_names.size()), UVM_FULL); 00063 00064 // Outer loop loops through all 00065 while (!primary_queue_iter.is_done()) begin 00066 primary_item = primary_queue_iter.get_item(); 00067 00068 `uvm_info("DEBUG", $sformatf("[%s]: cmp-iop: Now comparing primary transaction:\n%s", this.cfg.get_scb_name(), primary_item.sprint()), UVM_FULL); 00069 00070 // Clear list of found slave items before starting new inner loop 00071 secondary_item_found.delete(); 00072 00073 // Inner loop through all queues 00074 foreach(queue_names[i]) begin 00075 `uvm_info("DEBUG", $sformatf("[%s]: cmp-iop: Looking at queue: %s", this.cfg.get_scb_name(), queue_names[i]), UVM_FULL); 00076 00077 if(queue_names[i] != primary_queue_name) begin 00078 cl_syoscb_queue secondary_queue; 00079 cl_syoscb_queue_iterator_base secondary_queue_iter; 00080 00081 `uvm_info("DEBUG", $sformatf("[%s]: cmp-iop: %s is a secondary queue - now comparing", this.cfg.get_scb_name(), queue_names[i]), UVM_FULL); 00082 00083 // Get the secondary queue 00084 secondary_queue = this.cfg.get_queue(queue_names[i]); 00085 00086 if(secondary_queue == null) begin 00087 `uvm_fatal("QUEUE_ERROR", $sformatf("[%s]: cmp-iop: Unable to retrieve secondary queue handle", this.cfg.get_scb_name())); 00088 end 00089 00090 `uvm_info("DEBUG", $sformatf("[%s]: cmp-iop: %0d items in queue: %s", this.cfg.get_scb_name(), secondary_queue.get_size(), queue_names[i]), UVM_FULL); 00091 00092 // Only trigger the compare if there are elements in the queue 00093 if(secondary_queue.get_size()>0) begin 00094 // Get an iterator for the secondary queue 00095 secondary_queue_iter = secondary_queue.create_iterator(); 00096 00097 // Only the first match is removed 00098 while(!secondary_queue_iter.is_done()) begin 00099 // Get the item from the secondary queue 00100 cl_syoscb_item sih = secondary_queue_iter.get_item(); 00101 00102 // Only do the compare if the producers match 00103 if(primary_item.get_producer == sih.get_producer()) begin 00104 if(sih.compare(primary_item) == 1'b1) begin 00105 secondary_item_found[queue_names[i]] = secondary_queue_iter.get_idx(); 00106 `uvm_info("DEBUG", $sformatf("[%s]: cmp-iop: Secondary item found at index: %0d:\n%s", this.cfg.get_scb_name(), secondary_queue_iter.get_idx(), sih.sprint()), UVM_FULL); 00107 break; 00108 end else begin 00109 `uvm_error("COMPARE_ERROR", $sformatf("[%s]: cmp-iop: Item:\n%s\nfrom primary queue: %s not found in secondary queue: %s. Found this item in %s instead:\n%s", 00110 this.cfg.get_scb_name(), primary_item.sprint(), primary_queue_name, queue_names[i], queue_names[i], sih.sprint())) 00111 00112 // The first element was not a match => break since this is an in order compare on the producer 00113 break; 00114 end 00115 end 00116 00117 if(!secondary_queue_iter.next()) begin 00118 `uvm_fatal("QUEUE_ERROR", $sformatf("[%s]: cmp-iop: Unable to get next element from iterator on secondary queue: %s", this.cfg.get_scb_name(), queue_names[i])); 00119 end 00120 end 00121 00122 if(!secondary_queue.delete_iterator(secondary_queue_iter)) begin 00123 `uvm_fatal("QUEUE_ERROR", $sformatf("[%s]: cmp-iop: Unable to delete iterator from secondaery queue: %s", this.cfg.get_scb_name(), queue_names[i])); 00124 end 00125 end else begin 00126 `uvm_info("DEBUG", $sformatf("[%s]: cmp-iop: %s is empty - skipping", this.cfg.get_scb_name(), queue_names[i]), UVM_FULL); 00127 end 00128 end else begin 00129 `uvm_info("DEBUG", $sformatf("[%s]: cmp-iop: %s is the primary queue - skipping", this.cfg.get_scb_name(), queue_names[i]), UVM_FULL); 00130 end 00131 end 00132 00133 // Only start to remove items if all slave items are found (One from each slave queue) 00134 if(secondary_item_found.size() == queue_names.size()-1) begin 00135 string queue_name; 00136 cl_syoscb_item pih; 00137 00138 // Get the item from the primary queue 00139 pih = primary_queue_iter.get_item(); 00140 00141 `uvm_info("DEBUG", $sformatf("[%s]: cmp-iop: Found match for primary queue item :\n%s", this.cfg.get_scb_name(), pih.sprint()), UVM_FULL); 00142 00143 // Remove from primary 00144 if(!primary_queue.delete_item(primary_queue_iter.get_idx())) begin 00145 `uvm_error("QUEUE_ERROR", $sformatf("[%s]: cmp-iop: Unable to delete item idx %0d from queue %s", 00146 this.cfg.get_scb_name(), primary_queue_iter.get_idx(), primary_queue.get_name())); 00147 end 00148 00149 // Remove from all secondaries 00150 while(secondary_item_found.next(queue_name)) begin 00151 cl_syoscb_queue secondary_queue; 00152 00153 // Get the secondary queue 00154 secondary_queue = this.cfg.get_queue(queue_name); 00155 00156 if(secondary_queue == null) begin 00157 `uvm_fatal("QUEUE_ERROR", $sformatf("[%s]: cmp-iop: Unable to retrieve secondary queue handle", this.cfg.get_scb_name())); 00158 end 00159 00160 if(!secondary_queue.delete_item(secondary_item_found[queue_name])) begin 00161 `uvm_error("QUEUE_ERROR", $sformatf("[%s]: cmp-iop: Unable to delete item idx %0d from queue %s", 00162 this.cfg.get_scb_name(), secondary_item_found[queue_name], secondary_queue.get_name())); 00163 end 00164 end 00165 end 00166 00167 // Call .next() blindly since we do not care about the 00168 // return value, since we might be at the end of the queue. 00169 // Thus, .next() will return 1'b0 at the end of the queue 00170 void'(primary_queue_iter.next()); 00171 end 00172 00173 if(!primary_queue.delete_iterator(primary_queue_iter)) begin 00174 `uvm_fatal("QUEUE_ERROR", $sformatf("[%s]: cmp-iop: Unable to delete iterator from primary queue: %s", this.cfg.get_scb_name(), primary_queue_name)); 00175 end 00176 endfunction: compare_do
|
Project: SyoSil ApS UVM Scoreboard, Revision: 1.0.2.5 Copyright 2014-2015 SyoSil ApS 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. |
![]() Doxygen Version: 1.6.1 IDV SV Filter Version: 2.6.2 Sat Nov 28 05:41:54 2015 |