10 `uvm_component_utils_begin(cl_scb_test_iterator_unit_tests)
12 `uvm_component_utils_end
17 function new(string name = "cl_scb_test_iterator_unit_tests", uvm_component parent = null);
18 super.new(name, parent);
25 extern task main_phase(uvm_phase phase);
26 extern function cl_tb_seq_item get_next(cl_syoscb_queue_iterator_base iter);
27 extern function cl_tb_seq_item get_previous(cl_syoscb_queue_iterator_base iter);
40 function cl_tb_seq_item cl_scb_test_iterator_unit_tests::get_next(cl_syoscb_queue_iterator_base iter);
42 $cast(ctsi, iter.next().get_item().get_item());
46 function cl_tb_seq_item cl_scb_test_iterator_unit_tests::get_previous(cl_syoscb_queue_iterator_base iter);
48 $cast(ctsi, iter.previous().get_item().get_item());
50 endfunction: get_previous
62 for(int i=0; i<10; i++) begin
63 ctsi = this.get_next(iter);
64 if(ctsi.int_a != i || iter.previous_index() != i) begin
65 `uvm_error("ITER_NEXT", $sformatf("iterator.next() did not correctly advance the iterator. i=%0d, int_a=%0d, prev_idx=%0x", i, ctsi.int_a, iter.previous_index()))
69 if(iter.next_index() != q.get_size()) begin
70 `uvm_error("ITER_NEXT", "iterator.next() did not advance to the end of the queue")
74 if(iter.has_next()) begin
75 `uvm_error("ITER_NEXT", "iterator.has_next() returned 1'b1 while at the end of the queue")
80 cl_syoscb_queue_iterator_base iter2 = this.syoscb_cfgs.syoscb_cfg[0].get_queue("Q2").create_iterator();
81 if(iter2.has_next()) begin
82 `uvm_error("ITER_NEXT", "iterator.has_next() returned 1'b1 on an empty queue")
84 void'(this.syoscb_cfgs.syoscb_cfg[0].get_queue("Q2").delete_iterator(iter2));
87 void'(q.delete_iterator(iter));
88 `uvm_info("ITER_NEXT", "iterator.next() and iterator.has_next() passed tests", UVM_LOW)
96 task cl_scb_test_iterator_unit_tests::check_prev();
99 cl_syoscb_queue_base q = this.syoscb_cfgs.syoscb_cfg[0].get_queue("Q1");
100 cl_syoscb_queue_iterator_base iter = q.create_iterator();
103 while(iter.has_next()) begin
108 for(int i=9; i>0; i--) begin
109 ctsi = this.get_previous(iter);
110 if(ctsi.int_a != i || iter.next_index() != i) begin
111 `uvm_error("ITER_PREV", "iterator.previous() did not correctly move iterator back")
116 ctsi = this.get_previous(iter);
117 if(ctsi.int_a != 0 || iter.previous_index() != -1) begin
118 `uvm_error("ITER_PREV", "iterator.previous() did not move to index 0")
122 if(iter.has_previous()) begin
123 `uvm_error("ITER_PREV", "iterator.has_previous() returned 1'b1 while at the start of the queue")
129 if(iter2.has_previous()) begin
130 `uvm_error("ITER_PREV", "iterator.has_previous() returned 1'b1 on an empty queue")
132 void'(this.syoscb_cfgs.syoscb_cfg[0].get_queue("Q2").delete_iterator(iter2));
135 void'(q.delete_iterator(iter));
136 `uvm_info("ITER_PREV", "iterator.previous() and iterator.has_previous() passed tests", UVM_LOW)
150 for(int i=0; i<6; i++) begin
156 for(int i=0; i<2; i++) begin
158 if(!iter.first()) begin
159 `uvm_error("ITER_FIRST", "iterator.first() did not return 1'b1 while moving to first element")
163 if(iter.previous_index() != -1) begin
164 `uvm_error("ITER_FIRST", "iterator.first() did not set idx to 0")
167 ctsi = this.get_next(iter);
168 if(ctsi.int_a != 0) begin
169 `uvm_error("ITER_FIRST", "iterator.first() did not move to first element in queue")
175 cl_syoscb_queue_iterator_base iter2 = this.syoscb_cfgs.syoscb_cfg[0].get_queue("Q2").create_iterator();
176 if(iter2.first()) begin
177 `uvm_error("ITER_FIRST", "iterator.first() did not return 1'b0 when called on an empty queue")
179 void'(this.syoscb_cfgs.syoscb_cfg[0].get_queue("Q2").delete_iterator(iter2));
182 void'(q.delete_iterator(iter));
183 `uvm_info("ITER_FIRST", "iterator.first() passed tests", UVM_LOW)
190 task cl_scb_test_iterator_unit_tests::check_last();
192 cl_syoscb_queue_base q = this.syoscb_cfgs.syoscb_cfg[0].get_queue("Q1");
193 cl_syoscb_queue_iterator_base iter = q.create_iterator();
197 for(int i=0; i<2; i++) begin
198 if(!iter.last()) begin
199 `uvm_error("ITER_LAST", "iterator.last() did not return 1'b1 when moving to last element")
201 ctsi = this.get_previous(iter);
202 if(ctsi.int_a != q.get_size()-1 || iter.next_index() != q.get_size()-1) begin
203 $display("int_a=%0d, next_index=%0d, get_size=%0d", ctsi.int_a, iter.next_index(), q.get_size());
204 `uvm_error("ITER_LAST", "iterator.last() did not move to the last element of the queue")
210 cl_syoscb_queue_iterator_base iter2 = this.syoscb_cfgs.syoscb_cfg[0].get_queue("Q2").create_iterator();
211 if(iter2.last()) begin
212 `uvm_error("ITER_LAST", "iterator.last() did not return 1'b0 when called on an empty queue")
214 void'(this.syoscb_cfgs.syoscb_cfg[0].get_queue("Q2").delete_iterator(iter2));
217 void'(q.delete_iterator(iter));
218 `uvm_info("ITER_LAST", "iterator.last() passed tests", UVM_LOW)
226 task cl_scb_test_iterator_unit_tests::check_set_queue();
228 cl_syoscb_queue_iterator_std iter2_std;
229 cl_syoscb_queue_iterator_hash#(pk_syoscb::MD5_HASH_DIGEST_WIDTH) iter2_hash;
231 cl_syoscb_queue_base q = this.syoscb_cfgs.syoscb_cfg[0].get_queue("Q1");
232 cl_syoscb_queue_base q2 = this.syoscb_cfgs.syoscb_cfg[0].get_queue("Q2");
233 cl_syoscb_queue_iterator_base iter = q.create_iterator();
236 uvm_root::get().set_report_severity_id_override(UVM_ERROR, "ITER_ERROR", UVM_INFO);
239 if(iter.set_queue(q2)) begin
240 `uvm_error("ITER_SET_QUEUE", "iter.set_queue() allowed us to reassign the owner of an iterator")
246 if(iter2_std.set_queue(null)) begin
247 `uvm_error("ITER_SET_QUEUE", "iter.set_queue() allowed us to set owner of a std queue to null")
249 if(iter2_hash.set_queue(null)) begin
250 `uvm_error("ITER_SET_QUEUE", "iter.set_queue() allowed us to set owner of a hash queue to null")
254 if(this.syoscb_cfgs.syoscb_cfg[0].get_queue_type() == SYOSCB_QUEUE_STD) begin
256 if(iter2_hash.set_queue(q2)) begin
257 `uvm_error("ITER_SET_QUEUE", "iter.set_queue() allowed us to assign a hash iterator to a standard queue")
260 if(!iter2_std.set_queue(q2)) begin
261 `uvm_error("ITER_SET_QUEUE", "iter.set_queue() did not allow us to set owner of an un-owned iterator")
264 if(iter2_std.set_queue(q)) begin
265 `uvm_error("ITER_SET_QUEUE", "iter.set_queue() did not correctly set owner of an un-owned iterator")
269 if(iter2_std.set_queue(q2)) begin
270 `uvm_error("ITER_SET_QUEUE", "iter.set_queue() allowed us to assign a std iterator to a hash queue");
273 if(!iter2_hash.set_queue(q2)) begin
274 `uvm_error("ITER_SET_QUEUE", "iter.set_queue() did not allow us to set owner of an un-owned iterator")
277 if(iter2_hash.set_queue(q)) begin
278 `uvm_error("ITER_SET_QUEUE", "iter.set_queue() did not correctly set owner of an un-owned iterator")
282 void'(q.delete_iterator(iter));
283 uvm_root::get().set_report_severity_id_override(UVM_INFO, "ITER_ERROR", UVM_ERROR);
284 `uvm_info("ITER_SET_QUEUE", "iterator.set_queue() passed tests", UVM_LOW)
286 endtask: check_set_queue
292 task cl_scb_test_iterator_unit_tests::check_names();
293 cl_syoscb_queue_base q = this.syoscb_cfgs.syoscb_cfg[0].get_queue("Q2");
294 cl_syoscb_queue_iterator_base iter = q.create_iterator("custom_name");
297 if(q.create_iterator("custom_name") != null) begin
298 `uvm_error("ITER_NAMES", "queue.create_iterator() allowed us to create two iterators with the same name")
303 cl_syoscb_queue_iterator_base iter2, iter3, iter4;
304 int iter2_idx, iter4_idx;
305 string iter2_name, iter4_name;
306 iter2 = q.create_iterator();
307 iter3 = q.create_iterator("iter3");
308 iter4 = q.create_iterator();
310 iter2_name = iter2.get_name();
311 iter4_name = iter4.get_name();
313 for(int i=iter2_name.len(); i>=0; i--) begin
314 if(iter2_name[i] == "r") begin
315 string sub = iter2_name.substr(i+1, iter2_name.len()-1);
316 iter2_idx = sub.atoi();
319 for(int i=iter4_name.len(); i>=0; i--) begin
320 if(iter4_name[i] == "r") begin
321 string sub = iter4_name.substr(i+1, iter4_name.len()-1);
322 iter4_idx = sub.atoi();
325 if(iter4_idx != iter2_idx+2) begin
326 `uvm_error("ITER_NAMES", $sformatf({"queue.create_iterator() did not use progessively larger indices for iterators\n",
327 "iterators were named %0s and %0s, indices were %0d and %0d"}, iter2_name, iter4_name, iter2_idx, iter4_idx))
330 void'(q.delete_iterator(iter2));
331 void'(q.delete_iterator(iter3));
332 void'(q.delete_iterator(iter4));
336 if(q.get_iterator("not_set") != null) begin
337 `uvm_error("ITER_NAMES", "queue.get_iterator() returned an iterator for a name that was not set")
341 if(q.get_iterator("custom_name") != iter) begin
342 `uvm_error("ITER_NAMES", "queue.get_iterator() did not return the same handle for the same name")
346 void'(q.delete_iterator(iter));
348 if(q.get_iterator("custom_name") != null) begin
349 `uvm_error("ITER_NAMES", "queue.get_iterator() returned an iterator after deleting it")
350 end else if(q.create_iterator("custom_name") == null) begin
351 `uvm_error("ITER_NAMES", "queue.create_iterator() was not able to create an iterator after the last iterator with same name was deleted")
354 `uvm_info("ITER_NAMES", "queue.get_iterator() and queue.create_iterator() name functionality passed tests", UVM_LOW)
358 task cl_scb_test_iterator_unit_tests::check_flush();
359 cl_syoscb_queue_base q;
360 cl_syoscb_queue_iterator_base iter;
361 cl_syoscb_proxy_item_base pib;
362 cl_tb_seq_item first;
364 q = this.syoscb_cfgs.syoscb_cfg[0].get_queue("Q1");
365 iter = q.create_iterator();
369 first = this.get_next(iter);
374 this.scb_env.syoscb[0].flush_queues_all();
377 if(iter.has_next()) begin
378 `uvm_error("ITER_FLUSH", "iter.has_next() returns 1 after flushing queue.");
380 if(iter.has_previous()) begin
381 `uvm_error("ITER_FLUSH", "iter.has_previous() returns 1 after flushing queue.");
383 if(iter.first()) begin
384 `uvm_error("ITER_FLUSH", "iter.first() returns 1 after flushing queue.");
386 if(iter.last()) begin
387 `uvm_error("ITER_FLUSH", "iter.last() returns 1 after flushing queue.");
389 if(iter.next_index() != 0) begin
390 `uvm_error("ITER_FLUSH", $sformatf("iter.next_index() did not return 0 after flushing queue, returned %0d", iter.next_index()))
392 if(iter.previous_index() != -1) begin
393 `uvm_error("ITER_FLUSH", $sformatf("iter.previous_index() did not return -1 after flushing queue, returned %0d", iter.next_index()))
397 for(int i=0; i<10; i++) begin
398 cl_tb_seq_item item = cl_tb_seq_item::type_id::create("item");
400 this.scb_env.syoscb[0].add_item("Q1", "P1", item);
404 if(!iter.has_next()) begin
405 `uvm_error("ITER_FLUSH", "iter.has_next() returns 0 after reinserting items.");
407 cl_tb_seq_item ctsi = this.get_next(iter);
409 if(ctsi.int_a != first.int_a) begin
410 `uvm_error("ITER_FLUSH", $sformatf("iter.next() did not return item with int_a=%0d after reinserting, got int_a=%0d", first.int_a, ctsi.int_a))
414 void'(q.delete_iterator(iter));
415 `uvm_info("ITER_FLUSH", "Queue behavior after flushing queues passed tests", UVM_LOW)
419 task cl_scb_test_iterator_unit_tests::main_phase(uvm_phase phase);
420 phase.raise_objection(this);
421 super.main_phase(phase);
424 for(int i=0; i<10; i++) begin
425 cl_tb_seq_item item = cl_tb_seq_item::type_id::create("item");
427 this.scb_env.syoscb[0].add_item("Q1", "P1", item);
435 this.check_set_queue();
437 `uvm_info("ITER_TESTS", "ALL TESTS PASSED", UVM_LOW)
440 for(int i=0; i<10; i++) begin
441 cl_tb_seq_item item = cl_tb_seq_item::type_id::create("item");
443 this.scb_env.syoscb[0].add_item("Q2", "P1", item);
446 phase.drop_objection(this);
task check_first()
Checks whether the cl_syoscb_queue_iterator_base::first method correctly moves through the queue...
Test containing a series of unit tests to ensure that all iterators conform to spec.
task check_names()
Checks whether cl_syoscb_queue_base::get_iterator and cl_syoscb_queue_base::create_iterator correctly...
Queue iterator base class defining the iterator API used for iterating over queues.
task check_next()
Checks whether the cl_syoscb_queue_iterator_base::next method correctly moves through the queue When ...
task check_last()
Checks whether the cl_syoscb_queue_iterator_base::last method correctly moves through the queue...
Class which represents the base concept of a queue.
task check_flush()
When a queue is flushed, all associated iterators should be reset such that has_next/has_previous bot...
task check_prev()
Checks whether the cl_syoscb_queue_iterator_base::previous method correctly moves through the queue...
task check_set_queue()
Checks whether the cl_syoscb_queue_iterator_base::set_queue method correctly sets the queue associate...