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("Maximum number of items (%0d) for queue: %s reached", 00051 this.cfg.get_max_queue_size(this.get_name()), 00052 this.get_name())) 00053 return(1'b0); 00054 end 00055 00056 // Create the new scoreboard item with META data which wraps the 00057 // uvm_sequence_item 00058 // 00059 // *NOTE*: No need for using create. 00060 // New is okay since no customization is needed here 00061 // 00062 // *NOTE*: Create it once with a default name to be able to retrieve the unique 00063 // instance id and then rename the object with a uniqueue name 00064 new_item = new(.name("default-item")); 00065 new_item.set_name({producer,"-item-", $psprintf("%0d", new_item.get_inst_id())}); 00066 00067 // Transfer the producer to the item 00068 // *NOTE*: No need to check the producer since this is checked by the parent component 00069 new_item.set_producer(.producer(producer)); 00070 00071 // Transfer the UVM sequence item to the item 00072 // *NOTE*: No need to copy it since it has been copied by the parent 00073 new_item.set_item(.item(item)); 00074 00075 // Insert the item in the queue 00076 this.items.push_back(new_item); 00077 00078 // Signal that it worked 00079 return 1; 00080 endfunction: add_item 00081 00082 /// <b>Queue API:</b> See cl_syoscb_queue for more details 00083 function bit cl_syoscb_queue_std::delete_item(int unsigned idx); 00084 if(idx < this.items.size()) begin 00085 cl_syoscb_queue_iterator_base iter[$]; 00086 00087 // Wait to get exclusive access to the queue 00088 // if there are multiple iterators 00089 while(!this.iter_sem.try_get()); 00090 items.delete(idx); 00091 00092 // Update iterators 00093 iter = this.iterators.find(x) with (x.get_idx() < idx); 00094 for(int i = 0; i < iter.size(); i++) begin 00095 void'(iter[i].previous()); 00096 end 00097 00098 this.iter_sem.put(); 00099 return 1; 00100 end else begin 00101 `uvm_info("OUT_OF_BOUNDS", $sformatf("Idx: %0d is not present in queue: %0s", idx, this.get_name()), UVM_DEBUG); 00102 return 0; 00103 end 00104 endfunction: delete_item 00105 00106 /// <b>Queue API:</b> See cl_syoscb_queue for more details 00107 function cl_syoscb_item cl_syoscb_queue_std::get_item(int unsigned idx); 00108 if(idx < this.items.size()) begin 00109 return items[idx]; 00110 end else begin 00111 `uvm_info("OUT_OF_BOUNDS", $sformatf("Idx: %0d is not present in queue: %0s", idx, this.get_name()), UVM_DEBUG); 00112 return null; 00113 end 00114 endfunction: get_item 00115 00116 /// <b>Queue API:</b> See cl_syoscb_queue for more details 00117 function int unsigned cl_syoscb_queue_std::get_size(); 00118 return this.items.size(); 00119 endfunction: get_size 00120 00121 /// <b>Queue API:</b> See cl_syoscb_queue for more details 00122 function bit cl_syoscb_queue_std::empty(); 00123 return(this.get_size()!=0 ? 0 : 1); 00124 endfunction 00125 00126 /// <b>Queue API:</b> See cl_syoscb_queue for more details 00127 function bit cl_syoscb_queue_std::insert_item(string producer, uvm_sequence_item item, int unsigned idx); 00128 cl_syoscb_item new_item; 00129 00130 // Create the new scoreboard item with META data which wraps the 00131 // uvm_sequence_item 00132 // 00133 // *NOTE*: No need for using create. 00134 // New is okay since no customization is needed here 00135 // 00136 // *NOTE*: Create it once with a default name to be able to retrieve the unique 00137 // instance id and then rename the object with a uniqueue name 00138 new_item = new(.name("default-item")); 00139 new_item.set_name({producer,"-item-", $psprintf("%0d", new_item.get_inst_id())}); 00140 00141 // Transfer the producer to the item 00142 // *NOTE*: No need to check the producer since this is checked by the parent component 00143 new_item.set_producer(.producer(producer)); 00144 00145 // Transfer the UVM sequence item to the item 00146 // *NOTE*: No need to copy it since it has been copied by the parent 00147 new_item.set_item(.item(item)); 00148 00149 if(idx < this.items.size()) begin 00150 cl_syoscb_queue_iterator_base iter[$]; 00151 00152 // Wait to get exclusive access to the queue 00153 // if there are multiple iterators 00154 while(!this.iter_sem.try_get()); 00155 this.items.insert(idx, new_item); 00156 00157 // Update iterators 00158 iter = this.iterators.find(x) with (x.get_idx() >= idx); 00159 for(int i = 0; i < iter.size(); i++) begin 00160 // Call .next() blindly. This can never fail by design, since 00161 // if it was point at the last element then it points to the second last 00162 // element prior to the .next(). The .next() call will then just 00163 // set the iterator to the correct index again after the insertion 00164 void'(iter[i].next()); 00165 end 00166 00167 this.iter_sem.put(); 00168 return 1; 00169 end else if(idx == this.items.size()) begin 00170 this.items.push_back(new_item); 00171 return 1; 00172 end else begin 00173 `uvm_info("OUT_OF_BOUNDS", $sformatf("Idx: %0d too large for queue %0s", idx, this.get_name()), UVM_DEBUG); 00174 return 0; 00175 end 00176 endfunction: insert_item 00177 00178 00179 /// <b>Queue API:</b> See cl_syoscb_queue for more details 00180 function cl_syoscb_queue_iterator_base cl_syoscb_queue_std::create_iterator(); 00181 cl_syoscb_queue_iterator_std result; 00182 00183 // Wait to get exclusive access to the queue 00184 // if there are multiple iterators 00185 while(this.iter_sem.try_get() == 0); 00186 00187 result = cl_syoscb_queue_iterator_std::type_id::create( 00188 $sformatf("%s_iter%0d", this.get_name(), this.iter_idx)); 00189 00190 // No need to check return value since set_queue will issue 00191 // and `uvm_error of something goes wrong 00192 void'(result.set_queue(this)); 00193 00194 this.iterators[result] = result; 00195 this.iter_idx++; 00196 this.iter_sem.put(); 00197 00198 return result; 00199 endfunction: create_iterator 00200 00201 /// <b>Queue API:</b> See cl_syoscb_queue for more details 00202 function bit cl_syoscb_queue_std::delete_iterator(cl_syoscb_queue_iterator_base iterator); 00203 if(iterator == null) begin 00204 `uvm_info("NULL", $sformatf("Asked to delete null iterator from list of iterators in %s", 00205 this.get_name()), UVM_DEBUG); 00206 return 0; 00207 end else begin 00208 // Wait to get exclusive access to the queue 00209 // if there are multiple iterators 00210 while(!this.iter_sem.try_get()); 00211 00212 this.iterators.delete(iterator); 00213 this.iter_idx--; 00214 this.iter_sem.put(); 00215 return 1; 00216 end 00217 endfunction: delete_iterator
|
Project: SyoSil ApS UVM Scoreboard, Revision: 1.0.2.2 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 Wed Jul 29 14:03:55 2015 |