00001 /// Class which implements the in order compare algorithm 00002 class cl_syoscb_compare_io extends cl_syoscb_compare_base; 00003 //------------------------------------- 00004 // UVM Macros 00005 //------------------------------------- 00006 `uvm_object_utils(cl_syoscb_compare_io) 00007 00008 //------------------------------------- 00009 // Constructor 00010 //------------------------------------- 00011 extern function new(string name = "cl_syoscb_compare_io"); 00012 00013 //------------------------------------- 00014 // Compare API 00015 //------------------------------------- 00016 extern virtual function void compare(); 00017 extern function void compare_do(); 00018 endclass: cl_syoscb_compare_io 00019 00020 function cl_syoscb_compare_io::new(string name = "cl_syoscb_compare_io"); 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_compare() blindly 00026 function void cl_syoscb_compare_io::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 in 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 primary item as the first item in all of the other queues. If so then the items 00037 /// are removed from all queues. If not then a UVM error is issued. 00038 function void cl_syoscb_compare_io::compare_do(); 00039 string primary_queue_name; 00040 cl_syoscb_queue primary_queue; 00041 cl_syoscb_queue_iterator_base primary_queue_iter; 00042 string queue_names[]; 00043 int unsigned secondary_item_found[string]; 00044 bit compare_continue = 1'b1; 00045 bit compare_result = 1'b0; 00046 cl_syoscb_item primary_item; 00047 00048 // Initialize state variables 00049 primary_queue_name = this.get_primary_queue_name(); 00050 this.cfg.get_queues(queue_names); 00051 00052 primary_queue = this.cfg.get_queue(primary_queue_name); 00053 if(primary_queue == null) begin 00054 `uvm_fatal("QUEUE_ERROR", $sformatf("[%s]: cmp-io: Unable to retrieve primary queue handle", this.cfg.get_scb_name())); 00055 end 00056 00057 primary_queue_iter = primary_queue.create_iterator(); 00058 00059 `uvm_info("DEBUG", $sformatf("[%s]: cmp-io: primary queue: %s", this.cfg.get_scb_name(), primary_queue_name), UVM_FULL); 00060 `uvm_info("DEBUG", $sformatf("[%s]: cmp-io: number of queues: %0d", this.cfg.get_scb_name(), queue_names.size()), UVM_FULL); 00061 00062 // Outer loop loops through all 00063 while(!primary_queue_iter.is_done()) begin 00064 primary_item = primary_queue_iter.get_item(); 00065 00066 `uvm_info("DEBUG", $sformatf("[%s]: cmp-io: Now comparing primary transaction:\n%s", this.cfg.get_scb_name(), primary_item.sprint()), UVM_FULL); 00067 00068 // Clear list of found slave items before starting new inner loop 00069 secondary_item_found.delete(); 00070 00071 // Inner loop through all queues 00072 foreach(queue_names[i]) begin 00073 `uvm_info("DEBUG", $sformatf("[%s]: cmp-io: Looking at queue: %s", this.cfg.get_scb_name(), queue_names[i]), UVM_FULL); 00074 00075 if(queue_names[i] != primary_queue_name) begin 00076 cl_syoscb_queue secondary_queue; 00077 cl_syoscb_queue_iterator_base secondary_queue_iter; 00078 cl_syoscb_item sih; 00079 00080 `uvm_info("DEBUG", $sformatf("[%s]: cmp-io: %s is a secondary queue - now comparing", this.cfg.get_scb_name(), queue_names[i]), UVM_FULL); 00081 00082 // Get the secondary queue 00083 secondary_queue = this.cfg.get_queue(queue_names[i]); 00084 00085 if(secondary_queue == null) begin 00086 `uvm_fatal("QUEUE_ERROR", $sformatf("[%s]: cmp-io: Unable to retrieve secondary queue handle", this.cfg.get_scb_name())); 00087 end 00088 00089 `uvm_info("DEBUG", $sformatf("[%s]: cmp-io: %0d items in queue: %s", this.cfg.get_scb_name(), secondary_queue.get_size(), queue_names[i]), UVM_FULL); 00090 00091 // Get an iterator for the secondary queue 00092 secondary_queue_iter = secondary_queue.create_iterator(); 00093 00094 // Only do the compare if there are actually an item in the secondary queue 00095 if(!secondary_queue_iter.is_done()) begin 00096 // Get the first item from the secondary queue 00097 sih = secondary_queue_iter.get_item(); 00098 00099 if(sih.compare(primary_item) == 1'b1) begin 00100 secondary_item_found[queue_names[i]] = secondary_queue_iter.get_idx(); 00101 `uvm_info("DEBUG", $sformatf("[%s]: cmp-io: Secondary item found at index: %0d:\n%s", this.cfg.get_scb_name(), secondary_queue_iter.get_idx(), sih.sprint()), UVM_FULL); 00102 end else begin 00103 `uvm_error("COMPARE_ERROR", $sformatf("[%s]: cmp-io: Item:\n%s\nfrom primary queue: %s not found in secondary queue: %s. Found this item in %s instead:\n%s", this.cfg.get_scb_name(), primary_item.sprint(), primary_queue_name, queue_names[i], queue_names[i], sih.sprint())) 00104 00105 // The first element was not a match => break since this is an in order compare 00106 break; 00107 end 00108 end else begin 00109 `uvm_info("DEBUG", $sformatf("[%s]: cmp-io: %s is empty - skipping", this.cfg.get_scb_name(), queue_names[i]), UVM_FULL); 00110 end 00111 00112 if(!secondary_queue.delete_iterator(secondary_queue_iter)) begin 00113 `uvm_fatal("QUEUE_ERROR", $sformatf("[%s]: cmp-io: Unable to delete iterator from secondaery queue: %s", this.cfg.get_scb_name(), queue_names[i])); 00114 end 00115 end else begin 00116 `uvm_info("DEBUG", $sformatf("[%s]: cmp-io: %s is the primary queue - skipping", this.cfg.get_scb_name(), queue_names[i]), UVM_FULL); 00117 end 00118 end 00119 00120 // Only start to remove items if all slave items are found (One from each slave queue) 00121 if(secondary_item_found.size() == queue_names.size()-1) begin 00122 string queue_name; 00123 cl_syoscb_item pih; 00124 00125 // Get the item from the primary queue 00126 pih = primary_queue_iter.get_item(); 00127 00128 `uvm_info("DEBUG", $sformatf("[%s]: cmp-io: Found match for primary queue item :\n%s", this.cfg.get_scb_name(), pih.sprint()), UVM_FULL); 00129 00130 // Remove from primary 00131 if(!primary_queue.delete_item(primary_queue_iter.get_idx())) begin 00132 `uvm_error("QUEUE_ERROR", $sformatf("[%s]: cmp-io: Unable to delete item idx %0d from queue %s", 00133 this.cfg.get_scb_name(), primary_queue_iter.get_idx(), primary_queue.get_name())); 00134 end 00135 00136 // Remove from all secondaries 00137 while(secondary_item_found.next(queue_name)) begin 00138 cl_syoscb_queue secondary_queue; 00139 00140 // Get the secondary queue 00141 secondary_queue = this.cfg.get_queue(queue_name); 00142 00143 if(secondary_queue == null) begin 00144 `uvm_fatal("QUEUE_ERROR", $sformatf("[%s]: cmp-io: Unable to retrieve secondary queue handle", this.cfg.get_scb_name())); 00145 end 00146 00147 if(!secondary_queue.delete_item(secondary_item_found[queue_name])) begin 00148 `uvm_error("QUEUE_ERROR", $sformatf("[%s]: cmp-io: Unable to delete item idx %0d from queue %s", 00149 this.cfg.get_scb_name(), secondary_item_found[queue_name], secondary_queue.get_name())); 00150 end 00151 end 00152 end 00153 00154 // Call .next() blindly since we do not care about the 00155 // return value, since we might be at the end of the queue. 00156 // Thus, .next() will return 1'b0 at the end of the queue 00157 void'(primary_queue_iter.next()); 00158 end 00159 00160 if(!primary_queue.delete_iterator(primary_queue_iter)) begin 00161 `uvm_fatal("QUEUE_ERROR", $sformatf("[%s]: cmp-io: Unable to delete iterator from primary queue: %s", this.cfg.get_scb_name(), primary_queue_name)); 00162 end 00163 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 |