16 typedef tp_item_digest tp_queue_of_keys[$];
39 protected tp_item_digest key_queue[$];
42 protected int unsigned size;
48 `uvm_field_object(hash, UVM_DEFAULT)
49 `uvm_field_object(hash_algo,UVM_DEFAULT)
50 `uvm_field_int(size, UVM_DEFAULT)
51 `uvm_component_utils_end
56 extern function new(
string name, uvm_component parent);
62 extern virtual function bit add_item(
string producer, uvm_sequence_item item);
65 extern virtual function int unsigned get_size();
66 extern virtual function bit empty();
67 extern virtual function bit insert_item(
string producer,
68 uvm_sequence_item item,
75 extern virtual function tp_queue_of_keys get_key_queue();
79 extern protected virtual function void do_flush_queue();
84 function cl_syoscb_queue_hash::new(
string name, uvm_component parent);
85 super.new(name, parent);
94 new_item = this.pre_add_item(producer, item);
99 digest=this.hash_algo.hash(new_item);
100 this.hash.insert(digest, new_item);
102 if(this.cfg.get_ordered_next() == 1) begin
103 this.key_queue.push_back(
'{new_item, digest}); 106 this.post_add_item(new_item); 109 // Signal that it worked 111 endfunction: add_item
118 if(!
this.cfg.get_ordered_next()) begin
119 `uvm_fatal(
"CFG_ERROR",
"Cannot use insert_item() on hash queues when cfg.ordered_next is disabled")
121 end else if(idx > this.get_size()) begin //Check immediatedly if index is too large 122 `uvm_info("OUT_OF_BOUNDS", $sformatf("[%s] Idx %0d too large for insertion into queue %0s", this.cfg.get_scb_name(), idx, this.get_name()), UVM_DEBUG) 126 new_item = this.pre_add_item(producer, item);
127 digest = this.hash_algo.hash(new_item);
130 if(idx < this.get_size()) begin
134 while(!this.iter_sem.try_get());
135 this.hash.insert(digest, new_item);
138 this.key_queue.insert(idx,
'{new_item, digest}); 139 iters = this.iterators.find(x) with (x.next_index() > idx); 140 for(int i=0; i<iters.size(); i++) begin 141 //We can blindly call iter.next 142 //See cl_syoscb_queue_std::insert_item for more description as to why 143 void'(iters[i].next());
148 this.hash.insert(digest, new_item);
149 this.key_queue.push_back(
'{new_item, digest}); 152 this.post_add_item(new_item); 155 endfunction: insert_item
161 int unsigned item_position_idx = 0;
165 if(!$cast(proxy_item_hash,proxy_item))begin
166 `uvm_fatal(
"Incorrect item type", $sformatf(
"[%s]:Proxy_item ", this.cfg.get_scb_name()));
170 digest = proxy_item_hash.digest;
173 if(!this.hash.exists(digest)) begin
179 while(!this.iter_sem.try_get());
185 producer = tmp_item.get_producer();
191 if(this.cfg.get_ordered_next() == 1) begin
194 q_idx = this.key_queue.find_index with (item.digest==digest);
197 if(this.hash.get_size(digest) <= 1) begin
198 if(q_idx.size() == 0) begin
201 this.key_queue.delete(q_idx[0]);
202 item_position_idx = q_idx[0];
210 foreach(q_idx[i]) begin
211 item2 = this.key_queue[q_idx[i]].item;
212 if(item1.compare(item2)) begin
213 item_position_idx = q_idx[i];
226 foreach(this.iterators[i]) begin
230 void'(this.iterators[i].previous()); 231 other_proxy = this.iterators[i].next(); 232 //Can compare references directly, since they should both be pointing to the same object. 233 //No need to compare hash digest or contents 234 if(other_proxy.get_item() == proxy_item_hash.get_item()) begin 235 item_position_idx = this.iterators[i].previous_index(); 240 // Only need to search if we didn't previously find the item by checking iterators
242 if(this.iterators.size() > 0 && item_position_idx == 0) begin
243 int unsigned v_idx = 0;
246 if(this.hash.first(loop_digest)) begin
247 while(loop_digest != digest) begin
248 void'(this.hash.next(loop_digest)); 249 //If multiple items have this digest, we must also account for those in our final position idx 250 v_idx += this.hash.get_size(loop_digest); 252 v_idx += proxy_item_hash.idx; 254 item_position_idx = v_idx; 258 // Iterators update process can be shared independently by the value of ordered_next 259 // Find all the iter which need to be updated (all of those which have a next idx > item_position_idx) 260 iter = this.iterators.find(x) with (x.next_index() > item_position_idx); 263 foreach(iter[i]) begin 268 this.hash.delete(digest, proxy_item_hash.idx);
269 this.decr_cnt_producer(producer);
274 endfunction: delete_item
280 if(!$cast(proxy_item_hash, proxy_item)) begin
281 `uvm_fatal(
"Incorrect item type", $sformatf(
"[%s]:Proxy_item was of type %0s", this.cfg.get_scb_name(), proxy_item.get_type_name()));
285 return this.hash.
get_item(proxy_item_hash.digest, proxy_item_hash.idx);
286 endfunction: get_item
291 endfunction: get_size
295 return this.get_size()==0;
300 if(iterator == null) begin
301 `uvm_info(
"NULL", $sformatf(
"[%s]: Asked to delete null iterator from list of iterators in %s",
302 this.cfg.get_scb_name(), this.get_name()), UVM_DEBUG);
307 while(!this.iter_sem.try_get());
309 this.iterators.delete(iterator);
313 endfunction: delete_iterator
317 this.hash.delete_all();
320 endfunction: do_flush_queue
326 return this.key_queue;
327 endfunction: get_key_queue
332 endfunction: get_hash
virtual void do_flush_queue()
See cl_syoscb_queue_base::do_flush_queue for more details.
int unsigned size
Size of queue, stored here to optimize for speed.
virtual bit delete_item(cl_syoscb_proxy_item_base proxy_item)
Queue API: See cl_syoscb_queue_base::delete_item for more details
virtual cl_syoscb_proxy_item_base previous()
Iterator API: Moves the iterator one step backward, returning the previous item in the queue...
virtual tp_aa_hash get_hash()
Gets the hash AA wrapper used for this queue.
The UVM scoreboard item which wraps uvm_sequence_item .
virtual bit empty()
Queue API: See cl_syoscb_queue_base::empty for more details
tp_item_digest tp_queue_of_keys[$]
Typedef for queue of digests and items.
Base class for all proxy items.
virtual int unsigned get_size()
Queue API: See cl_syoscb_queue_base::get_size for more details.
Typedef for struct used to track items and their digests in the key queue.
virtual bit add_item(string producer, uvm_sequence_item item)
Queue API: See cl_syoscb_queue_base::add_item for more details
cl_syoscb_hash_base< HASH_DIGEST_WIDTH >::tp_hash_digest tp_digest
Typedef for hash algorithm digests.
virtual tp_queue_of_keys get_key_queue()
Get the list of hash values of items in the queue.
virtual cl_syoscb_item get_item()
Item API: Get the scoreboard item that this proxy item represents
virtual bit insert_item(string producer, uvm_sequence_item item, int unsigned idx)
Queue API: See cl_syoscb_queue_base::insert_item for more details
virtual uvm_sequence_item get_item()
Item API: Returns the wrapped uvm_sequence_item
Typedef for struct representing whether an option with an iterator was valid.
Queue iterator base class defining the iterator API used for iterating over queues.
virtual bit delete_iterator(cl_syoscb_queue_iterator_base iterator)
Queue API: See cl_syoscb_queue_base::delete_iterator for more details
Class which represents the base concept of a queue.
virtual cl_syoscb_item get_item(cl_syoscb_proxy_item_base proxy_item)
Queue API: See cl_syoscb_queue_base::get_item for more details
Class which defines the base concept of a hash algorithm.
A wrapper around an associative array, used for storing hash queues.
Proxy item implementation for hash queues.
Class which represents the base concept of a hash queue.