SyoSil ApS UVM Scoreboard  1.0.3.0
cl_syoscb_compare_base.svh
1 /// Base class for all compare algorithms. The chosen compare algorithm defines how
2 /// matches are found. For more information on the comparison algorithms included with the SyoSil
3 /// UVM Scoreboard, see \ref pCompareImplementationNotes.
4 class cl_syoscb_compare_base extends uvm_object;
5  //-------------------------------------
6  // Non randomizable variables
7  //-------------------------------------
8  /// Handle to the configuration object
9  protected cl_syoscb_cfg cfg;
10  /// Indicates how queues should be split into a primary queue and array of secondary queues.
11  /// This is done once with a static primary queue, done every time compare is invoked with a dynamic
12  /// primary queue
13  protected bit do_split = 1'b1;
14  /// Indicates whether a comparison can be started (1) or not (0)
15  protected bit go = 1'b1;
16  /// If set to 1'b1, no comparisons are performed. If 1'b0, comparisons are executed
17  protected bit disable_compare = 1'b0;
18  /// Name of primary queue
19  protected string primary_queue_name;
20  /// Handle to primary queue
22  /// Names of secondary queues
23  protected string secondary_queue_names[];
24  /// Handles to secondary queues
26  /// Associative array used to indicate if a matching item was found in a secondary queue.
27  /// If matches are found in all secondary queues, all items are removed from their respective queues
29  /// Proxy item for the item being searched for in all secondary queue
31  /// Iterator into primary queue
33  /// Name of the queue currently being searched
34  protected string current_queue_name;
35  /// Handle to the item passed in by cl_syoscb#add_item
37 
38  //-------------------------------------
39  // UVM Macros
40  //-------------------------------------
41  `uvm_object_utils_begin(cl_syoscb_compare_base)
42  `uvm_field_object(cfg, UVM_DEFAULT| UVM_REFERENCE)
43  `uvm_field_int(do_split, UVM_DEFAULT)
44  `uvm_field_int(go, UVM_DEFAULT)
45  `uvm_field_int(disable_compare, UVM_DEFAULT)
46  `uvm_field_string(primary_queue_name, UVM_DEFAULT)
47  `uvm_field_object(primary_queue, UVM_DEFAULT)
48  `uvm_field_array_string(secondary_queue_names, UVM_DEFAULT)
49  `uvm_field_aa_object_string(secondary_item_found, UVM_DEFAULT)
50  `uvm_field_object(primary_item_proxy, UVM_DEFAULT)
51  `uvm_field_object(primary_queue_iter, UVM_DEFAULT)
52  `uvm_field_string(current_queue_name, UVM_DEFAULT)
53  `uvm_field_object(current_item, UVM_DEFAULT)
54  `uvm_object_utils_end
55 
56  //-------------------------------------
57  // Constructor
58  //-------------------------------------
59  extern function new(string name = "cl_syoscb_compare_base");
60 
61  //-------------------------------------
62  // Compare API
63  //-------------------------------------
64  extern virtual function void compare_control(bit cc);
65  extern virtual function void compare_trigger(string queue_name = "",
66  cl_syoscb_item item = null);
67  extern virtual function void compare_main(t_scb_compare_greed greed);
68 
69  //-------------------------------------
70  // Compare Strategy API
71  //-------------------------------------
72  extern protected virtual function void init();
73  extern protected virtual function void compare_do_greed(t_scb_compare_greed greed);
74  extern protected virtual function void compare_init();
75  extern protected virtual function void compare_do();
76  extern protected virtual function string get_primary_queue_name();
77  extern protected virtual function void split_queues();
78  extern protected virtual function void check_queues();
79  extern protected virtual function void count_producers(string producer = "");
80  extern protected virtual function void create_primary_iterator();
81  extern protected virtual function void primary_loop_init();
82  extern protected virtual function void primary_loop_do();
83  extern protected virtual function void secondary_loop_do();
84  extern protected virtual function void static_queue_split_do();
85  extern protected virtual function void dynamic_queue_split_do();
86  extern protected virtual function bit delete();
87  extern protected virtual function string get_count_producer();
88  extern protected virtual function int unsigned get_queues_item_cnt();
89 
90 
91  //-------------------------------------
92  // Local misc methods
93  //-------------------------------------
94  extern virtual function void set_cfg(cl_syoscb_cfg cfg);
95  extern virtual function cl_syoscb_cfg get_cfg();
96  extern virtual function string generate_miscmp_table(cl_syoscb_item primary_item,
97  cl_syoscb_item secondary_item,
98  string sec_queue_name,
99  uvm_comparer comparer,
100  string cmp_name);
101  extern local virtual function int num_uvm_errors();
102  extern virtual function void do_copy(uvm_object rhs);
103  extern virtual function void do_print(uvm_printer printer);
104  extern virtual function bit do_compare(uvm_object rhs,
105  uvm_comparer comparer);
106 endclass: cl_syoscb_compare_base
107 
108 function cl_syoscb_compare_base::new(string name = "cl_syoscb_compare_base");
109  super.new(name);
110 endfunction: new
111 
112 /// <b>Compare API</b>: Toggle comparisons on or off
113 /// \param cc compare control bit. If 1, comparisons are enabled, if 0, comparisons are disabled
115  this.disable_compare = !cc;
116 endfunction: compare_control
117 
118 /// <b>Compare API</b>: Starts a comparison by calling #compare_main if comparisons are not disabled.
119 /// \param queue_name Name of the queue which had an item inserted into it
120 /// \param item The scoreboard wrapper item that was inserted into the SCB
121 function void cl_syoscb_compare_base::compare_trigger(string queue_name = "",
122  cl_syoscb_item item = null);
123  if(this.disable_compare == 1'b0) begin
124  if(item == null) begin
125  `uvm_fatal("COMPARE_ERROR", $sformatf("[%s]: The in-order by producer requires to know the current inserted item", this.cfg.get_scb_name()));
126  end
127 
128  this.current_queue_name = queue_name;
129  this.current_item = item;
130 
131  this.compare_main(this.cfg.get_trigger_greediness());
132  end
133 endfunction: compare_trigger
134 
135 /// <b>Compare API</b>: Main function that contains all the actual compare
136 /// operations requested by the compare algorithm.
137 /// It cares about:
138 /// -# Splitting queues into primary and secondary queues, generating an interator into the primary queue
139 /// -# Calling #compare_do_greed with the proper draining value passed as argument
140 /// -# Deleting the primary queue iterator after the compare algo has finished all comparisons
141 /// \param greed The greed level to use when performing comparisons. See cl_syoscb_cfg#trigger_greediness
142 function void cl_syoscb_compare_base::compare_main(t_scb_compare_greed greed);
143  this.init();
144 
145  this.compare_do_greed(greed);
146 endfunction: compare_main
147 
148 /// <b>Compare Strategy API</b>: Executes some preliminary common operations before starting comparisons:
149 /// -# Split queues into primary and secondary
150 /// -# Create iterator for the chosen primary queue
152  if(this.do_split == 1'b1) begin
153  this.split_queues();
154  end
155 
157 endfunction: init
158 
159 /// <b>Compare Strategy API</b>: Try to remove a match and drain all the potential remaining matches inside the
160 /// queues according to the greed level given as argument. Performs the following:
161 /// -# Calling the checkers in order to verify that starting a comparison makes sense
162 /// -# Calling the actual #compare_do function if a comparison should be starte
163 /// -# Looping to remove additional matches if the greed levels prescribes this
164 /// \param greed The greed level to use when performing comparisons. See cl_syoscb_cfg#trigger_greediness
165 function void cl_syoscb_compare_base::compare_do_greed(t_scb_compare_greed greed);
166  int unsigned item_before_compare = 0;
167 
168  // Check if the conditions for starting a compare are met inside compare_init, and
169  // resolve the potential other matches inside the queue depending on the while condition below
170  do begin
171  item_before_compare = this.get_queues_item_cnt();
172  this.compare_init();
173 
174  if(this.go == 1'b1) begin
175  int unsigned nbr_errors;
176 
177  nbr_errors = this.num_uvm_errors();
178 
179  this.compare_do();
180 
181  if(this.cfg.get_disable_compare_after_error() && (this.num_uvm_errors()>nbr_errors)) begin
182  `uvm_info("DEBUG", $sformatf("[%s]: Disabling compare as error is detected and disable compare after error is enabled", this.cfg.get_scb_name()), UVM_FULL);
183  this.disable_compare = 1'b1;
184  end
185  end
186  end
187  while( greed == pk_syoscb::SYOSCB_COMPARE_GREEDY &&
188  (item_before_compare - this.get_queues_item_cnt()) == (this.secondary_queues.size()+1));
189 endfunction: compare_do_greed
190 
191 /// <b>Compare Strategy API</b>: Verifies if the conditions for starting a compare are met:
192 /// -# Verify that all queues currently contain at least one element
193 /// -# Verify that all queues have at least one element from the same producer as the producer
194 /// returned by #get_count_producer() (the primary item being searched for)
195 /// If the conditions are met then go variable is triggered, and the compare process can start.
197  this.check_queues();
198 
199  this.count_producers();
200 endfunction: compare_init
201 
202 /// <b>Compare Strategy API</b>: Starts the actual comparison operation
203 /// -# Perform initialization on the primary queue, if necessary
204 /// -# Start the primary queue loop
206  this.primary_loop_init();
207 
208  this.primary_loop_do();
209 endfunction: compare_do
210 
211 /// <b>Compare Strategy API</b>: Gets the name of this scoreboard's primary queue.
212 /// Convenience method wrapping cl_syoscb_cfg#get_primary_queue
214  return this.cfg.get_primary_queue();
215 endfunction: get_primary_queue_name
216 
217 /// <b>Compare Strategy API</b>: Splits the scoreboard's queues into 1 primary queue and N-1 secondary queues.
218 /// Selects the primary queue and creates an array of secondary queues with the rest.
219 /// If a dynamic primary queue is used, this split is performed every time a comparison is started.
220 /// If a static primary queue is used, this split is only performed on the first comparison.
222  if(!this.cfg.dynamic_primary_queue()) begin
223  // In case of static primary, the split can be done only once.
224  this.do_split = 1'b0;
225  this.static_queue_split_do();
226  end else begin
227  this.do_split = 1'b1;
228  this.dynamic_queue_split_do();
229  end
230 
231  if(this.secondary_queues.size() == 0 ||
232  this.secondary_queue_names.size() == 0) begin
233  `uvm_fatal("QUEUE_ERROR", $sformatf("[%s]: No secondary queues found", this.cfg.get_scb_name()));
234  end
235 
236  foreach(this.secondary_queues[i]) begin
237  if(this.secondary_queues[i] == null) begin
238  `uvm_fatal("QUEUE_ERROR", $sformatf("[%s]: Unable to retrieve secondary queue handle", this.cfg.get_scb_name()));
239  end
240 
241  `uvm_info("DEBUG", $sformatf("[%s]: Secondary queue: %s found", this.cfg.get_scb_name(), this.secondary_queue_names[i]), UVM_FULL);
242  end
243 
244 endfunction: split_queues
245 
246 /// <b>Compare Strategy API</b>: Check if any queue is empty.
247 /// Assigns 0 to the member variable #go when any of the queues are empty,
248 /// indicating that a comparison cannot be started. Assigns 1 if all queues are non-empty,
249 /// indicating that the comparison may be started.
251  if(this.primary_queue.empty() == 1'b0) begin
252  cl_syoscb_queue_base empties[$];
253 
254  // Search in this.secondary_queues and stores in empties all those who are empty.
255  empties = this.secondary_queues.find(x) with (x.empty() == 1'b1);
256 
257  // If i have an empty secondary queue, i cannot start the compare
258  this.go = (empties.size()>0) ? 1'b0 : 1'b1;
259  end else begin
260  this.go = 1'b0;
261  end
262 endfunction: check_queues
263 
264 /// <b>Compare Strategy API</b>: Checks if the producer of the current item exists in all other queues,
265 /// and whether all other queues have at least 1 item from that producer.
266 /// If true, assigns 1'b1 to member variable #go
267 /// If false, assigns 1'b0 to member variable #go
268 ///
269 /// \param producer The producer to check if exists in all other queues. If not set, checks if the
270 /// producer of #current_item exists in other queues. If set, checks for that producer in other queues.
271 function void cl_syoscb_compare_base::count_producers(string producer = "");
272  string prod;
273  if(this.go == 1'b1) begin
274  cl_syoscb_queue_base producers[$];
275  if(producer == "") begin
276  //Empty string => check for current_item.producer
277  prod = this.get_count_producer();
278  end else begin
279  //Nonempty string => check based on producer parameter.
280  //No need to check validity of producer name. If illegal name, no comparison will be run and go will be set to 1'b0
281  prod = producer;
282  end
283 
284  producers = this.secondary_queues.find(x) with (x.exists_cnt_producer(prod) == 1'b1);
285 
286  this.go = (this.primary_queue.exists_cnt_producer(prod) &&
287  producers.size() == this.secondary_queues.size()) ? 1'b1 : 1'b0;
288 
289  if(this.go == 1'b1) begin
290  cl_syoscb_queue_base cnt_producers[$];
291 
292  cnt_producers = this.secondary_queues.find(x) with (x.get_cnt_producer(prod) > 0);
293 
294  this.go = ((this.primary_queue.get_cnt_producer(prod)>0) &&
295  (cnt_producers.size() == this.secondary_queues.size())) ? 1'b1 : 1'b0;
296  end
297  end
298 endfunction: count_producers
299 
300 /// <b>Compare Strategy API</b>: Deletes matched items from the primary and all secondary queues if a match was found.
301 /// If no match is found, no items are deleted from the queues.
302 /// \return 1'b1 if a match was found and items were deleted, 1'b0 otherwise
304  // Only start to remove items if all slave items are found (One from each slave queue)
305  if(this.secondary_item_found.size() == this.secondary_queue_names.size()) begin
306  `uvm_info("DEBUG", $sformatf("[%s]: cmp: Found match for primary queue item :\n%s", this.cfg.get_scb_name(), cl_syoscb_string_library::sprint_item(this.primary_queue.get_item(this.primary_item_proxy), this.cfg)), UVM_FULL);
307 
308  // Remove from primary
309  if(!this.primary_queue.delete_item(this.primary_item_proxy)) begin
310  `uvm_error("QUEUE_ERROR", $sformatf("[%s]: cmp: Unable to delete item from queue %s",
311  this.cfg.get_scb_name(),this.primary_queue_name));
312  end
313 
314  // Remove from all secondaries
315  foreach(this.secondary_queue_names[i]) begin
316  if(this.secondary_queues[i] == null) begin
317  `uvm_fatal("QUEUE_ERROR", $sformatf("[%s]: cmp: Unable to retrieve secondary queue handle", this.cfg.get_scb_name()));
318  end
319 
320  if(!this.secondary_queues[i].delete_item(this.secondary_item_found[this.secondary_queue_names[i]])) begin
321  `uvm_error("QUEUE_ERROR", $sformatf("[%s]: cmp: Unable to delete item from queue %s",
322  this.cfg.get_scb_name(), this.secondary_queue_names[i]));
323  end
324  end
325  return 1'b1;
326  end
327  return 1'b0;
328 endfunction: delete
329 
330 /// <b>Compare Strategy API</b>: Returns the name of the producer that the compare method should evaluate in
331 /// order to verify if it makes sense to start a comparison.
332 /// \note This function needs to be overridden by the derived compare methods in order to
333 /// change the behaviour accordingly to the requested needs. By default, the function returns the
334 /// producer of #current_item.
335 /// \return The name producer which should be evaluated
337  return this.current_item.get_producer();
338 endfunction: get_count_producer
339 
340 /// <b>Compare Strategy API</b>: Gets the total number of items in all the queues at the
341 /// moment of the function call.
342 /// \return Number of items currently stored in all queues
344  int unsigned item_count = 0;
345  string l_queue_names[];
346  cl_syoscb_queue_base l_queue;
347 
348  this.cfg.get_queues(l_queue_names);
349 
350  foreach(l_queue_names[i]) begin
351  l_queue = this.cfg.get_queue(l_queue_names[i]);
352 
353  item_count = item_count + l_queue.get_size();
354  end
355  return item_count;
356 endfunction: get_queues_item_cnt
357 
358 /// <b>Compare Strategy API</b>: Loop over the primary queue, selecting primary items
359 /// to compare against items in the secondary queues.
360 /// \note Abstract method. This method must be implemented in a subclass.
362  `uvm_fatal("IMPL_ERROR", $sformatf("[%s]: cl_syoscb_compare_base::primary_loop_do() *MUST* be overwritten", this.cfg.get_scb_name()));
363 endfunction
364 
365 /// <b>Compare Strategy API</b>: Loop over all secondary queues to find a match for the primary item.
366 /// \note Abstract method. This method must be implemented in a subclass.
368  `uvm_fatal("IMPL_ERROR", $sformatf("[%s]: cl_syoscb_compare_base::secondary_loop_do() *MUST* be overwritten", this.cfg.get_scb_name()));
369 endfunction
370 
371 /// <b>Compare Strategy API</b>: Splits queues into primary and secondary when a primary queue has been specified.
372 /// The primary queue is the one set by cl_syoscb_cfg#set_primary_queue_name, all other queues
373 /// will be secondary queues
375  string queue_names[];
376  int first = 1;
377  cl_syoscb_queue_base queue_first;
378 
379  // Initialize state variables
380  this.cfg.get_queues(queue_names);
382  this.primary_queue = this.cfg.get_queue(this.primary_queue_name);
383  if(this.primary_queue == null) begin
384  `uvm_fatal("QUEUE_ERROR", $sformatf("[%s]: cmp: Unable to retrieve primary queue handle", this.cfg.get_scb_name()));
385  end
386  foreach(queue_names[i]) begin
387  if(queue_names[i] != this.get_primary_queue_name()) begin
388  this.secondary_queue_names = new[this.secondary_queue_names.size()+1](this.secondary_queue_names);
389  this.secondary_queue_names[this.secondary_queue_names.size()-1] = queue_names[i];
390  this.secondary_queues = new[this.secondary_queues.size()+1](this.secondary_queues);
391  this.secondary_queues[this.secondary_queues.size()-1] = this.cfg.get_queue(queue_names[i]);
392  end
393  end
394 endfunction
395 
396 /// <b>Compare Strategy API</b>: Splits queues into primary and secondary when a primary queue has not been specified.
397 /// Selects as the primary queue the shortest queue, the rest are the secondary queues.
399  string queue_names[];
400  int first = 1;
401  cl_syoscb_queue_base queue_first;
402 
403  // Initialize state variables
404  this.cfg.get_queues(queue_names);
405 
406  foreach(queue_names[i]) begin
407  if(first) begin
408  this.primary_queue = this.cfg.get_queue(queue_names[i]);
409  this.primary_queue_name = queue_names[i];
410  if(this.primary_queue == null) begin
411  `uvm_fatal("QUEUE_ERROR", $sformatf("[%s]: cmp: Unable to retrieve primary queue handle", this.cfg.get_scb_name()));
412  end
415  first = 0;
416  end else begin
417  queue_first = this.cfg.get_queue(queue_names[i]);
418  if(queue_first == null) begin
419  `uvm_fatal("QUEUE_ERROR", $sformatf("[%s]: cmp: Unable to retrieve primary queue handle", this.cfg.get_scb_name()));
420  end
421 
422  this.secondary_queue_names = new[this.secondary_queue_names.size()+1](this.secondary_queue_names);
423  this.secondary_queues = new[this.secondary_queues.size()+1](this.secondary_queues);
424 
425  if(queue_first.get_size() < this.primary_queue.get_size()) begin
426  this.secondary_queue_names[this.secondary_queue_names.size()-1] = primary_queue_name;
427  this.secondary_queues[this.secondary_queues.size()-1] = primary_queue;
428  this.primary_queue = queue_first;
429  this.primary_queue_name = queue_names[i];
430  end else begin
431  this.secondary_queue_names[this.secondary_queue_names.size()-1] = queue_names[i];
432  this.secondary_queues[this.secondary_queues.size()-1] = queue_first;
433  end
434  end
435  end
436 endfunction
437 
438 /// <b>Compare Strategy API</b>: Creates the iterator for the primary queue and sets the pointer to its first element
439 function void cl_syoscb_compare_base::create_primary_iterator();
440  //If iterator already exists, we have run at least one compare, so all queues
441  //should have a "default" iterator. If using dynamic primary, the primary may change,
442  //so we also have to reassign the primary queue iterator on every comparison
443  this.primary_queue_iter = this.primary_queue.get_iterator("default");
444 
445  //If no iterator with that name exists, we are either running first comparison
446  //or it was deleted. Create the iterator in that case
447  if(this.primary_queue_iter == null) begin
448  this.primary_queue_iter = this.primary_queue.create_iterator("default");
449  end
450 
451  `uvm_info("DEBUG",
452  $sformatf("[%s]: cmp: primary queue: %s",
453  this.cfg.get_scb_name(), this.primary_queue.get_name()), UVM_FULL);
454  `uvm_info("DEBUG",
455  $sformatf("[%s]: cmp: number of queues: %0d",
456  this.cfg.get_scb_name(), this.secondary_queue_names.size()+1), UVM_FULL);
457 
458  void'(this.primary_queue_iter.first());
459 endfunction: create_primary_iterator
460 
461 /// <b>Compare Strategy API</b>: Contains all the operations to be executed immediately before
462 /// starting the primary loop. By default is an empty function (no other operations needed).
463 function void cl_syoscb_compare_base::primary_loop_init();
464 endfunction: primary_loop_init
465 
466 /// Returns the number of UVM_ERROR messages that have been generated so far
467 function int cl_syoscb_compare_base::num_uvm_errors();
468  uvm_report_server rs;
469  rs = uvm_report_server::get_server();
470 
471  return rs.get_severity_count(UVM_ERROR);
472 endfunction: num_uvm_errors
473 
474 /// Set the scoreboard configuration associated with this comparer's scoreboard
475 /// \param cfg The scoreboard configuration object
476 function void cl_syoscb_compare_base::set_cfg(cl_syoscb_cfg cfg);
477  this.cfg = cfg;
478 endfunction: set_cfg
479 
480 /// Gets the scoreboard configuration object associated with this scoreboard
481 function cl_syoscb_cfg cl_syoscb_compare_base::get_cfg();
482  return this.cfg;
483 endfunction: get_cfg
484 
485 /// Generates a side-by-side comparison of the seq. items that prompted a miscompare.
486 /// The table includes a header with information on which queues the items originated in,
487 /// a side-by-side view of the two seq. items and, if cl_syoscb_cfg#enable_comparer_report
488 /// is set, it also includes a number of miscompare descriptions from the uvm_comparer used.
489 ///
490 /// \param primary_item The primary item in the comparison
491 /// \param secondary_item The secondary item in the comparison
492 /// \param sec_queue_name The name of the secondary queue
493 /// \param comparer The uvm_comparer used for the comparison
494 /// \param cmp_name Name of the comparison type, to be used when printing the header.
495 /// \return The miscompare table
496 function string cl_syoscb_compare_base::generate_miscmp_table(cl_syoscb_item primary_item,
497  cl_syoscb_item secondary_item,
498  string sec_queue_name,
499  uvm_comparer comparer,
500  string cmp_name);
501 
502  int table_width;
503  bit ecr;
504  string header;
505  string miscmp_table;
506  string footer;
507 
508  //Generate fields for body of miscmp table
509  table_width = cl_syoscb_string_library::generate_cmp_table_body('{primary_item, secondary_item}, this.cfg, miscmp_table);
510 
511  //Generate header
512  header = cl_syoscb_string_library::generate_cmp_table_header(
513  table_width,
514  $sformatf("[%0s]: %0s: Item from primary queue (%0s) not found in secondary queue (%0s)",
515  this.cfg.get_scb_name(),
516  cmp_name,
517  this.primary_queue_name,
518  sec_queue_name
519  )
520  );
521 
522  //Generate footer
523  ecr = this.cfg.get_enable_comparer_report(sec_queue_name, secondary_item.get_producer());
524  if(ecr) begin
525  footer = cl_syoscb_string_library::generate_cmp_table_footer(table_width, comparer);
526  end else begin
527  footer = " ";
528  end
529 
530  return {header, miscmp_table, footer};
531 endfunction: generate_miscmp_table
532 
533 /// Custom do_dopy implementation for secondary queues
534 function void cl_syoscb_compare_base::do_copy(uvm_object rhs);
535  cl_syoscb_compare_base rhs_cast;
536 
537  super.do_copy(rhs);
538 
539  //try to cast an object as rhs should be cl_syoscb_compare_base type
540  if(!$cast(rhs_cast, rhs)) begin
541  `uvm_fatal("DO_COPY", "Cast of rhs failed")
542  end
543 
544  this.secondary_queues = new[rhs_cast.secondary_queues.size()];
545 
546  //now i copy all rhs.secondary_queues content in this.secondary_queues
547  foreach(this.secondary_queues[i]) begin
548  this.secondary_queues[i] = rhs_cast.secondary_queues[i];
549  end
550 endfunction: do_copy
551 
552 // Custom do_print implementation for secondary queues
553 function void cl_syoscb_compare_base::do_print(uvm_printer printer);
554  super.do_print(printer);
555 
556  foreach(this.secondary_queues[i]) begin
557  this.secondary_queues[i].print(printer);
558  end
559 endfunction: do_print
560 
561 // Custom do_compare implementation for secondary queues
562 function bit cl_syoscb_compare_base::do_compare(uvm_object rhs,
563  uvm_comparer comparer);
564  cl_syoscb_compare_base rhs_cast;
565  bit compare_bit = super.do_compare(rhs, comparer);
566 
567  //try to cast an object as rhs should be cl_syoscb_compare_base type
568  if(!$cast(rhs_cast, rhs)) begin
569  `uvm_fatal("DO_COMPARE", "Cast of rhs failed")
570  return 0;
571  end
572 
573  //check if the size of secondary_queues matches
574  if(compare_bit) begin
575  // Some tools have problems with either $size and/or $bits on the return type
576  // of the result of <dynamic array>.size()
577  // On the other hand, the data type of "size" is of type INT.
578  // According to SV-LRM 1800-2017, in section 6.11 (P.104) the integral type INT has a fixed
579  // size equal to 32-bit. In order to keep the scb reusable across all simulators, it has
580  // been choosen to hardwire the "size" argument assigning to it the value of 32, which is the
581  // number of bit representation for the tipe INT, according to what is reported inside the LRM.
582  compare_bit &= comparer.compare_field_int("secondary_queue_size",
583  this.secondary_queues.size(),
584  rhs_cast.secondary_queues.size(),
585  32);
586  end
587 
588  if(compare_bit) begin
589  foreach(this.secondary_queues[i]) begin
590  compare_bit &= comparer.compare_object("secondary_queues",
591  this.secondary_queues[i],
592  rhs_cast.secondary_queues[i]);
593  end
594  end
595 
596  return compare_bit;
597 endfunction: do_compare
virtual cl_syoscb_cfg get_cfg()
Gets the scoreboard configuration object associated with this scoreboard.
virtual void compare_init()
Compare Strategy API: Verifies if the conditions for starting a compare are met:Verify that all queue...
cl_syoscb_queue_iterator_base primary_queue_iter
Iterator into primary queue.
virtual int num_uvm_errors()
Returns the number of UVM_ERROR messages that have been generated so far.
virtual void compare_do()
Compare Strategy API: Starts the actual comparison operationPerform initialization on the primary que...
virtual void count_producers(string producer="")
Compare Strategy API: Checks if the producer of the current item exists in all other queues...
virtual void dynamic_queue_split_do()
Compare Strategy API: Splits queues into primary and secondary when a primary queue has not been spec...
The UVM scoreboard item which wraps uvm_sequence_item .
cl_syoscb_queue_base secondary_queues[]
Handles to secondary queues.
virtual void check_queues()
Compare Strategy API: Check if any queue is empty.
Base class for all proxy items.
Base class for all compare algorithms.
virtual bit delete()
Compare Strategy API: Deletes matched items from the primary and all secondary queues if a match was ...
virtual void secondary_loop_do()
Compare Strategy API: Loop over all secondary queues to find a match for the primary item...
bit go
Indicates whether a comparison can be started (1) or not (0)
cl_syoscb_proxy_item_base secondary_item_found[string]
Associative array used to indicate if a matching item was found in a secondary queue.
virtual void compare_control(bit cc)
Compare API: Toggle comparisons on or off
virtual int unsigned get_queues_item_cnt()
Compare Strategy API: Gets the total number of items in all the queues at the moment of the function ...
virtual void create_primary_iterator()
Compare Strategy API: Creates the iterator for the primary queue and sets the pointer to its first el...
bit disable_compare
If set to 1&#39;b1, no comparisons are performed. If 1&#39;b0, comparisons are executed.
virtual void set_cfg(cl_syoscb_cfg cfg)
Set the scoreboard configuration associated with this comparer&#39;s scoreboard.
string secondary_queue_names[]
Names of secondary queues.
cl_syoscb_proxy_item_base primary_item_proxy
Proxy item for the item being searched for in all secondary queue.
virtual void split_queues()
Compare Strategy API: Splits the scoreboard&#39;s queues into 1 primary queue and N-1 secondary queues...
virtual void compare_main(t_scb_compare_greed greed)
Compare API: Main function that contains all the actual compare operations requested by the compare a...
Queue iterator base class defining the iterator API used for iterating over queues.
string primary_queue_name
Name of primary queue.
virtual string get_primary_queue_name()
Compare Strategy API: Gets the name of this scoreboard&#39;s primary queue.
virtual void static_queue_split_do()
Compare Strategy API: Splits queues into primary and secondary when a primary queue has been specifie...
cl_syoscb_queue_base primary_queue
Handle to primary queue.
virtual void compare_trigger(string queue_name="", cl_syoscb_item item=null)
Compare API: Starts a comparison by calling compare_main if comparisons are not disabled.
virtual string generate_miscmp_table(cl_syoscb_item primary_item, cl_syoscb_item secondary_item, string sec_queue_name, uvm_comparer comparer, string cmp_name)
Generates a side-by-side comparison of the seq.
bit do_split
Indicates how queues should be split into a primary queue and array of secondary queues.
Class which represents the base concept of a queue.
cl_syoscb_cfg cfg
Handle to the configuration object.
virtual string get_count_producer()
Compare Strategy API: Returns the name of the producer that the compare method should evaluate in ord...
virtual void primary_loop_init()
Compare Strategy API: Contains all the operations to be executed immediately before starting the prim...
virtual void do_copy(uvm_object rhs)
Custom do_dopy implementation for secondary queues.
virtual void primary_loop_do()
Compare Strategy API: Loop over the primary queue, selecting primary items to compare against items i...
cl_syoscb_item current_item
Handle to the item passed in by cl_syoscb::add_item.
string current_queue_name
Name of the queue currently being searched.
virtual void compare_do_greed(t_scb_compare_greed greed)
Compare Strategy API: Try to remove a match and drain all the potential remaining matches inside the ...
Configuration class for the SyoSil UVM scoreboard.
virtual void init()
Compare Strategy API: Executes some preliminary common operations before starting comparisons:Split q...

Project: SyoSil ApS UVM Scoreboard, Revision: 1.0.3.0

Copyright 2014-2022 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
Doxygen Version: 1.8.14
Generated with IDV SV Filter Version: 2.6.3
Fri Sep 2 2022 14:39:00
Find a documentation bug? Report bugs to: scoreboard@syosil.com