SyoSil ApS UVM Scoreboard  1.0.3.0
cl_syoscb_compare_iop.svh
1 /// Class which implements the in order by producer compare algorithm
3 
4  /// Scoreboard wrapper item from the primary queue
6  /// Scoreboard wrapper item from the secondary queue currently being inspected
8 
9  //-------------------------------------
10  // UVM Macros
11  //-------------------------------------
12  `uvm_object_utils_begin(cl_syoscb_compare_iop)
13  `uvm_field_object(primary_item, UVM_DEFAULT)
14  `uvm_field_object(secondary_item, UVM_DEFAULT)
15  `uvm_object_utils_end
16 
17  //-------------------------------------
18  // Constructor
19  //-------------------------------------
20  extern function new(string name = "cl_syoscb_compare_iop");
21 
22  //-------------------------------------
23  // Compare Strategy API
24  //-------------------------------------
25  extern protected virtual function void compare_init();
26  extern protected virtual function void primary_loop_do();
27  extern protected virtual function void secondary_loop_do();
28  extern protected virtual function string get_count_producer();
29 endclass: cl_syoscb_compare_iop
30 
31 function cl_syoscb_compare_iop::new(string name = "cl_syoscb_compare_iop");
32  super.new(name);
33 endfunction: new
34 
35 /// <b>Compare Strategy API</b>: Verifies if the conditions for starting a compare are met.
36 /// For IOP comparison, we only check whether all queues have at least one item in them, but do not check
37 /// if primary queue's oldest item's producer exists in all queues.
38 /// Checking if all queues have an item from the same producer is moved to primary_loop_do
40  this.check_queues();
41 endfunction: compare_init
42 
43 
44 /// <b>Compare Strategy API</b>: Implementation of the in-order by producer comparison.
45 ///
46 /// The algorithm gets the primary queue, extracting the oldest element.
47 /// It then checks if all other queues also contain an element from this element's producer.
48 /// If true, it attempts to find a match for the primary item in all secondary queues.
49 /// If false, extracts the second-oldest element from primary, checking if this item's producer
50 /// has at least one item in all other queues.
51 /// Continues performing this loop over items in primary queue until one of three things happen:
52 /// -# A match is found for the item from the primary queue, the item and matches are removed from their queues.
53 /// -# An item from a secondary queue has the same producer but does not match primary item.
54 /// This generates a miscompare and raises a UVM_ERROR.
55 /// -# No matches are found. Will search over at most cl_syoscb_cfg#max_search_window elements in the primary
56 /// and secondary queues. Does not raise a UVM_ERROR
57 /// Note that this may leave the queues non_empty at the end of simulation without triggering any errors.
58 /// These orphaned items in queues are caught in the check_phase.
61  int unsigned msw = this.cfg.get_max_search_window(this.primary_queue_name);
62 
63  if(this.primary_queue_iter.first()) begin //Reset iterator, start while-loop
64  //Iterator not finished and not exceeding max search window
65  while(this.primary_queue_iter.has_next() && (msw > 0 ? this.primary_queue_iter.next_index() < msw : 1)) begin
66  this.primary_item_proxy = this.primary_queue_iter.next();
67  this.primary_item = this.primary_queue.get_item(this.primary_item_proxy);
68 
69  //Set go=1 to indicate that we wish to start a comparison
70  //If still 1 after calling count_producers, we have matching producers in all queues
71  this.go = 1'b1;
72  this.count_producers(this.primary_item.get_producer());
73  if(this.go) begin
74  `uvm_info("DEBUG", $sformatf("[%s]: cmp-iop: Now comparing primary transaction:\n%s",
75  this.cfg.get_scb_name(),
76  cl_syoscb_string_library::sprint_item(this.primary_item, this.cfg)),
77  UVM_FULL);
79  this.secondary_loop_do();
80 
81  if(this.delete()) begin
82  //If delete return 1'b1, we found matching items in all queues.
83  //If it return 1'b0, the primary item's producer exists in all queues,
84  //but items were not found (due to max search window limiting the
85  //number of seq. items searched).
86  break;
87  end
88  return;
89  end else begin
90  `uvm_info("DEBUG", $sformatf({"[%s]: cmp-iop: Not comparing primary transaction since not all queues",
91  " have items from producer '%s'"}, this.primary_item.get_producer()), UVM_DEBUG)
92  end
93  end
94  end
95 endfunction: primary_loop_do
96 
97 /// <b>Compare Strategy API:</b> Loop through all secondary queues, attempting to find an item
98 /// which matches the primary item.
100  foreach(this.secondary_queue_names[i]) begin
101  cl_syoscb_queue_iterator_base secondary_queue_iter;
102  string sec_queue_name;
103  int unsigned msw;
104 
105  sec_queue_name = this.secondary_queue_names[i];
106 
107  `uvm_info("DEBUG", $sformatf("[%s]: cmp-iop: Looking at queue: %s", this.cfg.get_scb_name(), sec_queue_name), UVM_FULL);
108  `uvm_info("DEBUG", $sformatf("[%s]: cmp-iop: %s is a secondary queue - now comparing", this.cfg.get_scb_name(), sec_queue_name), UVM_FULL);
109 
110  `uvm_info("DEBUG", $sformatf("[%s]: cmp-iop: %0d items in queue: %s", this.cfg.get_scb_name(), this.secondary_queues[i].get_size(), sec_queue_name), UVM_FULL);
111 
112  // *NOTE*: No need to check if there is any item since compare_do is only invoked
113  // if there is at least a single element in all queues
114 
115  secondary_queue_iter = this.secondary_queues[i].get_iterator("default");
116  if(secondary_queue_iter == null) begin
117  secondary_queue_iter = this.secondary_queues[i].create_iterator("default");
118  end
119  void'(secondary_queue_iter.first());
120  msw = this.cfg.get_max_search_window(sec_queue_name);
121 
122  // Only the first match is removed
123  while(secondary_queue_iter.has_next() && (msw > 0 ? secondary_queue_iter.next_index() < msw : 1)) begin
124  // Get the item from the secondary queue
125  cl_syoscb_proxy_item_base secondary_item_proxy = secondary_queue_iter.next();
126  this.secondary_item = this.secondary_queues[i].get_item(secondary_item_proxy);
127 
128  // Only do the compare if the producers match
129  if(this.primary_item.get_producer() == secondary_item.get_producer()) begin
130  uvm_comparer comparer;
131 
132  comparer = this.cfg.get_comparer(this.primary_queue_name, this.primary_item.get_producer());
133  if(comparer == null) begin
134  comparer = this.cfg.get_default_comparer();
135  end
136 
137  if(this.secondary_item.compare(this.primary_item, comparer) == 1'b1) begin
138  this.secondary_item_found[sec_queue_name] = secondary_item_proxy;
139 
140  `uvm_info("DEBUG", $sformatf("[%s]: cmp-iop: Secondary item found at index: %0d:\n%s",
141  this.cfg.get_scb_name(),
142  secondary_queue_iter.previous_index(),
143  cl_syoscb_string_library::sprint_item(this.secondary_item, this.cfg)),
144  UVM_FULL);
145 
146  break;
147  end else begin
148  string miscmp_table;
149 
150  miscmp_table = this.generate_miscmp_table(this.primary_item, this.secondary_item, sec_queue_name, comparer, "cmp-iop");
151  `uvm_error("COMPARE_ERROR", $sformatf("\n%0s", miscmp_table))
152 
153  // The first element was not a match => break since this is an in order compare
154  // w.r.t. the producer name.
155  break;
156  end
157  end
158  end
159  end
160 endfunction: secondary_loop_do
161 
162 
163 /// <b>Compare Strategy API</b>: For IOP comparisons, this function returns the producer
164 /// of the first element (the oldest) inside the primary queue, and not the most recently inserted item.
166  cl_syoscb_proxy_item_base l_item_proxy;
167  cl_syoscb_item l_item;
169 
170  if(this.primary_queue_iter == null) begin
171  this.primary_queue_iter = this.primary_queue.create_iterator("default");
172  end
173 
174  void'(this.primary_queue_iter.first());
175 
176  l_item_proxy = this.primary_queue_iter.next();
177  l_item = this.primary_queue.get_item(l_item_proxy);
178  void'(this.primary_queue_iter.first()); //Must reset after peeking first item
179 
180  return l_item.get_producer();
181 endfunction: get_count_producer
cl_syoscb_item primary_item
Scoreboard wrapper item from the primary queue.
virtual void primary_loop_do()
Compare Strategy API: Implementation of the in-order by producer comparison.
cl_syoscb_queue_iterator_base primary_queue_iter
Iterator into primary queue.
virtual void count_producers(string producer="")
Compare Strategy API: Checks if the producer of the current item exists in all other queues...
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 ...
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.
Class which implements the in order by producer compare algorithm.
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.
Queue iterator base class defining the iterator API used for iterating over queues.
cl_syoscb_queue_base primary_queue
Handle to primary queue.
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.
cl_syoscb_cfg cfg
Handle to the configuration object.
virtual string get_count_producer()
Compare Strategy API: For IOP comparisons, this function returns the producer of the first element (t...
virtual void compare_init()
Compare Strategy API: Verifies if the conditions for starting a compare are met.
cl_syoscb_item secondary_item
Scoreboard wrapper item from the secondary queue currently being inspected.
virtual void secondary_loop_do()
Compare Strategy API: Loop through all secondary queues, attempting to find an item which matches the...

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:05
Find a documentation bug? Report bugs to: scoreboard@syosil.com