00001 /// Standard implementation of a queue. Uses a normal SystemVerilog queue as 00002 /// implementation. The class implements the queue API as defined by the queue 00003 /// base class. 00004 class cl_syoscb_queue_std extends cl_syoscb_queue; 00005 //------------------------------------- 00006 // Non randomizable variables 00007 //------------------------------------- 00008 /// Poor mans queue implementation as a SV queue 00009 local cl_syoscb_item items[$]; 00010 00011 //------------------------------------- 00012 // UVM Macros 00013 //------------------------------------- 00014 `uvm_component_utils_begin(cl_syoscb_queue_std) 00015 `uvm_field_queue_object(items, UVM_DEFAULT) 00016 `uvm_component_utils_end 00017 00018 //------------------------------------- 00019 // Constructor 00020 //------------------------------------- 00021 extern function new(string name, uvm_component parent); 00022 00023 //------------------------------------- 00024 // Queue API 00025 //------------------------------------- 00026 // Basic queue functions 00027 extern virtual function bit add_item(string producer, uvm_sequence_item item); 00028 extern virtual function bit delete_item(int unsigned idx); 00029 extern virtual function cl_syoscb_item get_item(int unsigned idx); 00030 extern virtual function int unsigned get_size(); 00031 extern virtual function bit empty(); 00032 extern virtual function bit insert_item(string producer, uvm_sequence_item item, int unsigned idx); 00033 00034 // Iterator support functions 00035 extern virtual function cl_syoscb_queue_iterator_base create_iterator(); 00036 extern virtual function bit delete_iterator(cl_syoscb_queue_iterator_base iterator); 00037 endclass: cl_syoscb_queue_std 00038 00039 function cl_syoscb_queue_std::new(string name, uvm_component parent); 00040 super.new(name, parent); 00041 endfunction: new 00042 00043 /// <b>Queue API:</b> See cl_syoscb_queue for more details 00044 function bit cl_syoscb_queue_std::add_item(string producer, uvm_sequence_item item); 00045 cl_syoscb_item new_item; 00046 00047 // Check that the max_queue_size for this queue is not reached 00048 if(this.cfg.get_max_queue_size(this.get_name())>0 && 00049 this.get_size()==this.cfg.get_max_queue_size(this.get_name())) begin 00050 `uvm_error("QUEUE_ERROR", $sformatf("[%s]: Maximum number of items (%0d) for queue: %s reached", 00051 this.cfg.get_scb_name(), 00052 this.cfg.get_max_queue_size(this.get_name()), 00053 this.get_name())) 00054 return(1'b0); 00055 end 00056 00057 // Create the new scoreboard item with META data which wraps the 00058 // uvm_sequence_item 00059 // 00060 // *NOTE*: No need for using create. 00061 // New is okay since no customization is needed here 00062 // 00063 // *NOTE*: Create it once with a default name to be able to retrieve the unique 00064 // instance id and then rename the object with a uniqueue name 00065 new_item = new(.name("default-item")); 00066 new_item.set_name({producer,"-item-", $psprintf("%0d", new_item.get_inst_id())}); 00067 00068 // Transfer the producer to the item 00069 // *NOTE*: No need to check the producer since this is checked by the parent component 00070 new_item.set_producer(.producer(producer)); 00071 00072 // Transfer the UVM sequence item to the item 00073 // *NOTE*: No need to copy it since it has been copied by the parent 00074 new_item.set_item(.item(item)); 00075 00076 // Insert the item in the queue 00077 this.items.push_back(new_item); 00078 00079 // Count the number of inserts 00080 this.cnt_add_item++; 00081 00082 // Signal that it worked 00083 return 1; 00084 endfunction: add_item 00085 00086 /// <b>Queue API:</b> See cl_syoscb_queue for more details 00087 function bit cl_syoscb_queue_std::delete_item(int unsigned idx); 00088 if(idx < this.items.size()) begin 00089 cl_syoscb_queue_iterator_base iter[$]; 00090 00091 // Wait to get exclusive access to the queue 00092 // if there are multiple iterators 00093 while(!this.iter_sem.try_get()); 00094 items.delete(idx); 00095 00096 // Update iterators 00097 iter = this.iterators.find(x) with (x.get_idx() < idx); 00098 for(int i = 0; i < iter.size(); i++) begin 00099 void'(iter[i].previous()); 00100 end 00101 00102 this.iter_sem.put(); 00103 return 1; 00104 end else begin 00105 `uvm_info("OUT_OF_BOUNDS", $sformatf("[%s]: Idx: %0d is not present in queue: %0s", this.cfg.get_scb_name(), idx, this.get_name()), UVM_DEBUG); 00106 return 0; 00107 end 00108 endfunction: delete_item 00109 00110 /// <b>Queue API:</b> See cl_syoscb_queue for more details 00111 function cl_syoscb_item cl_syoscb_queue_std::get_item(int unsigned idx); 00112 if(idx < this.items.size()) begin 00113 return items[idx]; 00114 end else begin 00115 `uvm_info("OUT_OF_BOUNDS", $sformatf("[%s]: Idx: %0d is not present in queue: %0s", this.cfg.get_scb_name(), idx, this.get_name()), UVM_DEBUG); 00116 return null; 00117 end 00118 endfunction: get_item 00119 00120 /// <b>Queue API:</b> See cl_syoscb_queue for more details 00121 function int unsigned cl_syoscb_queue_std::get_size(); 00122 return this.items.size(); 00123 endfunction: get_size 00124 00125 /// <b>Queue API:</b> See cl_syoscb_queue for more details 00126 function bit cl_syoscb_queue_std::empty(); 00127 return(this.get_size()!=0 ? 0 : 1); 00128 endfunction 00129 00130 /// <b>Queue API:</b> See cl_syoscb_queue for more details 00131 function bit cl_syoscb_queue_std::insert_item(string producer, uvm_sequence_item item, int unsigned idx); 00132 cl_syoscb_item new_item; 00133 00134 // Create the new scoreboard item with META data which wraps the 00135 // uvm_sequence_item 00136 // 00137 // *NOTE*: No need for using create. 00138 // New is okay since no customization is needed here 00139 // 00140 // *NOTE*: Create it once with a default name to be able to retrieve the unique 00141 // instance id and then rename the object with a uniqueue name 00142 new_item = new(.name("default-item")); 00143 new_item.set_name({producer,"-item-", $psprintf("%0d", new_item.get_inst_id())}); 00144 00145 // Transfer the producer to the item 00146 // *NOTE*: No need to check the producer since this is checked by the parent component 00147 new_item.set_producer(.producer(producer)); 00148 00149 // Transfer the UVM sequence item to the item 00150 // *NOTE*: No need to copy it since it has been copied by the parent 00151 new_item.set_item(.item(item)); 00152 00153 if(idx < this.items.size()) begin 00154 cl_syoscb_queue_iterator_base iter[$]; 00155 00156 // Wait to get exclusive access to the queue 00157 // if there are multiple iterators 00158 while(!this.iter_sem.try_get()); 00159 this.items.insert(idx, new_item); 00160 00161 // Update iterators 00162 iter = this.iterators.find(x) with (x.get_idx() >= idx); 00163 for(int i = 0; i < iter.size(); i++) begin 00164 // Call .next() blindly. This can never fail by design, since 00165 // if it was point at the last element then it points to the second last 00166 // element prior to the .next(). The .next() call will then just 00167 // set the iterator to the correct index again after the insertion 00168 void'(iter[i].next()); 00169 end 00170 00171 this.iter_sem.put(); 00172 return 1; 00173 end else if(idx == this.items.size()) begin 00174 this.items.push_back(new_item); 00175 return 1; 00176 end else begin 00177 `uvm_info("OUT_OF_BOUNDS", $sformatf("[%s]: Idx: %0d too large for queue %0s", this.cfg.get_scb_name(), idx, this.get_name()), UVM_DEBUG); 00178 return 0; 00179 end 00180 endfunction: insert_item 00181 00182 00183 /// <b>Queue API:</b> See cl_syoscb_queue for more details 00184 function cl_syoscb_queue_iterator_base cl_syoscb_queue_std::create_iterator(); 00185 cl_syoscb_queue_iterator_std result; 00186 00187 // Wait to get exclusive access to the queue 00188 // if there are multiple iterators 00189 while(this.iter_sem.try_get() == 0); 00190 00191 result = cl_syoscb_queue_iterator_std::type_id::create( 00192 $sformatf("%s_iter%0d", this.get_name(), this.iter_idx)); 00193 00194 // No need to check return value since set_queue will issue 00195 // and `uvm_error of something goes wrong 00196 void'(result.set_queue(this)); 00197 00198 this.iterators[result] = result; 00199 this.iter_idx++; 00200 this.iter_sem.put(); 00201 00202 return result; 00203 endfunction: create_iterator 00204 00205 /// <b>Queue API:</b> See cl_syoscb_queue for more details 00206 function bit cl_syoscb_queue_std::delete_iterator(cl_syoscb_queue_iterator_base iterator); 00207 if(iterator == null) begin 00208 `uvm_info("NULL", $sformatf("[%s]: Asked to delete null iterator from list of iterators in %s", 00209 this.cfg.get_scb_name(), this.get_name()), UVM_DEBUG); 00210 return 0; 00211 end else begin 00212 // Wait to get exclusive access to the queue 00213 // if there are multiple iterators 00214 while(!this.iter_sem.try_get()); 00215 00216 this.iterators.delete(iterator); 00217 this.iter_idx--; 00218 this.iter_sem.put(); 00219 return 1; 00220 end 00221 endfunction: delete_iterator
|
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 |