SyoSil ApS UVM Scoreboard  1.0.3.0
cl_syoscb_queue_locator_hash.svh
1 /// Locator class for searching over generic hash queues
2 class cl_syoscb_queue_locator_hash#(int unsigned HASH_DIGEST_WIDTH = 1) extends cl_syoscb_queue_locator_base;
3  //-------------------------------------
4  // UVM Macros
5  //-------------------------------------
6  `uvm_object_param_utils(cl_syoscb_queue_locator_hash#(HASH_DIGEST_WIDTH))
7 
8  function new(string name = "cl_syoscb_queue_locator_hash");
9  super.new(name);
10  endfunction: new
11 
12  //-------------------------------------
13  // Locator API
14  //-------------------------------------
15  extern virtual function cl_syoscb_proxy_item_base search(cl_syoscb_proxy_item_base proxy_item);
16 
17  //-------------------------------------
18  // Internal support functions
19  //-------------------------------------
20  extern virtual function bit validate_match(cl_syoscb_proxy_item_base primary_proxy,
21  cl_syoscb_proxy_item_base secondary_proxy);
22  extern virtual function void validate_no_match(cl_syoscb_proxy_item_base primary_proxy);
24 
25 /// <b>Locator API:</b> See cl_syoscb_queue_locator_base#search for details
27  cl_syoscb_queue_hash#(HASH_DIGEST_WIDTH) qh, q_primary;
28  cl_syoscb_proxy_item_hash#(HASH_DIGEST_WIDTH) proxy_item_hash;
29  cl_syoscb_proxy_item_hash#(HASH_DIGEST_WIDTH) proxy_item_hash_return;
30  cl_syoscb_hash_aa_wrapper#(HASH_DIGEST_WIDTH) hash, hash_primary;
31 
32  proxy_item_hash_return = cl_syoscb_proxy_item_hash#(HASH_DIGEST_WIDTH)::type_id::create("proxy_item_hash_return");
33 
34  if(!$cast(proxy_item_hash,proxy_item))begin
35  `uvm_fatal("Incorrect item type", $sformatf("[%s]:Proxy_item ", this.cfg.get_scb_name()));
36  return null;
37  end
38 
39  if(!$cast(qh,this.owner))begin
40  `uvm_fatal("Incorrect queue type", $sformatf("[%s]:Queue ", this.cfg.get_scb_name()));
41  return null;
42  end
43  if(!$cast(q_primary, proxy_item.get_queue())) begin
44  `uvm_fatal("TYPECAST", $sformatf("[%0s]Incorrect queue type from proxy item. Expected hash queue, got %0s", this.cfg.get_scb_name(), proxy_item.get_queue().get_type_name()))
45  return null;
46  end
47 
48 
49  hash = qh.get_hash();
50  hash_primary = q_primary.get_hash();
51 
52  if(hash.exists(proxy_item_hash.digest) == 1) begin
53  bit found = 0;
54  proxy_item_hash_return.digest = proxy_item_hash.digest;
55  proxy_item_hash_return.set_queue(qh);
56  proxy_item_hash_return.idx = 0;
57 
58  //If there is more than one item in hash item from primary queue or this queue,
59  //we must manually compare items to ensure that a hash collision doesn't remove the wrong item from the queues
60  if(hash.get_size(proxy_item_hash.digest) != 1 || hash_primary.get_size(proxy_item_hash.digest) != 1) begin
61  cl_syoscb_item primary_item, sec_item;
62  uvm_comparer comparer;
63 
64  primary_item = proxy_item_hash.get_item();
65  comparer = this.cfg.get_comparer(this.owner.get_name(), primary_item.get_producer());
66  if(comparer == null) begin
67  comparer = this.cfg.get_default_comparer();
68  end
69  for(int i=0; i<hash.get_size(proxy_item_hash.digest) && !found; i++) begin
70  sec_item = hash.get_item(proxy_item_hash.digest, i);
71  if(primary_item.compare(sec_item, comparer)) begin
72  proxy_item_hash_return.idx = i;
73  found = 1;
74  end
75  end
76  end else begin //only one item in each queue at that hash, they should match
77  found = 1'b1;
78  end
79 
80 
81  if(found && this.validate_match(proxy_item, proxy_item_hash_return)) begin
82  return proxy_item_hash_return;
83  end else begin
84  //If match was not validated, a uvm_error was raised
85  //We can just return null here to signal that no match was found
86  return null;
87  end
88  end else begin
89  this.validate_no_match(proxy_item);
90  //validate_no_match raises a uvm_error if an actual match is found. We still return
91  //null no matter what, as something went wrong
92  return null;
93  end
94 endfunction: search
95 
96 /// Validates that a sequence item found in a secondary hash queue matches the sequence item
97 /// being searched for. Raises a UVM_ERROR if the items do not match
98 /// \param primary_proxy The proxy item from the primary queue
99 /// \param secondary_proxy The proxy item found in the secondary queue
100 /// \return 1 is the two items match represented by proxy items match, 0 otherwise
102  cl_syoscb_proxy_item_base secondary_proxy);
103  cl_syoscb_proxy_item_hash#(HASH_DIGEST_WIDTH) primary_proxy_hash;
104 
105  //Cast to hash item as we need the digest
106  if(!$cast(primary_proxy_hash, primary_proxy)) begin
107  `uvm_fatal("ITEM_TYPE", "Primary item was not a hash item")
108  end
109 
110  case (this.cfg.get_hash_compare_check())
111  pk_syoscb::SYOSCB_HASH_COMPARE_VALIDATE_NO_MATCH,
112  pk_syoscb::SYOSCB_HASH_COMPARE_NO_VALIDATION: begin
113  return 1'b1;
114  end
115  pk_syoscb::SYOSCB_HASH_COMPARE_VALIDATE_ALL,
116  pk_syoscb::SYOSCB_HASH_COMPARE_VALIDATE_MATCH: begin
117  cl_syoscb_item primary, secondary;
118  uvm_comparer comparer;
119 
120  primary = primary_proxy.get_item();
121  secondary = secondary_proxy.get_item();
122  comparer = this.cfg.get_comparer(this.owner.get_name(), primary.get_producer());
123  if(comparer == null) begin
124  comparer = this.cfg.get_default_comparer();
125  end
126  if(primary.compare(secondary, comparer)) begin
127  return 1'b1;
128  end else begin
129  string header, body, footer;
130  int table_width;
131  table_width = cl_syoscb_string_library::generate_cmp_table_body('{primary, secondary}, this.cfg, body);
132  header = cl_syoscb_string_library::generate_cmp_table_header(
133  table_width,
134  $sformatf("[%s] Seq. items with same hash did not have the same contents.\nHash=%x",
135  this.cfg.get_scb_name(),
136  primary_proxy_hash.digest
137  )
138  );
139  footer = cl_syoscb_string_library::generate_cmp_table_footer(table_width, comparer);
140 
141  `uvm_error("MISCMP_HASH", {"\n", header, body, footer})
142  return 1'b0;
143  end
144  end
145  default: begin
146  t_hash_compare_check hcc = this.cfg.get_hash_compare_check();
147  `uvm_fatal("QUEUE_ERROR", $sformatf("[%s] Value of cfg.hash_compare_check (%s, %d) was not valid",
148  this.cfg.get_scb_name(),
149  hcc.name(),
150  hcc))
151  end
152  endcase
153 endfunction: validate_match
154 
155 /// Validates that no sequence item in this secondary hash queue matches the primary
156 /// sequence item being searched for.
157 /// Raises a UVM_ERROR if a match is actually found
158 /// \param primary_proxy The proxy item from the primary queue
160  cl_syoscb_queue_hash#(HASH_DIGEST_WIDTH) owner_hash;
161  cl_syoscb_proxy_item_hash#(HASH_DIGEST_WIDTH) primary_proxy_hash;
162  cl_syoscb_item primary, secondary;
163  uvm_comparer comparer;
164 
165  if(!$cast(owner_hash, this.owner)) begin
166  `uvm_fatal("QUEUE_ERROR", $sformatf("[%s] Queue %s is not a hash queue. It must be to work with hash items", this.cfg.get_scb_name(), this.owner.get_name()))
167  end
168 
169  if(!$cast(primary_proxy_hash, primary_proxy)) begin
170  `uvm_fatal("ITEM_TYPE", "Primary item was not a hash item")
171  end
172 
173  case (this.cfg.get_hash_compare_check())
174  pk_syoscb::SYOSCB_HASH_COMPARE_NO_VALIDATION,
175  pk_syoscb::SYOSCB_HASH_COMPARE_VALIDATE_MATCH: begin
176  return;
177  end
178  pk_syoscb::SYOSCB_HASH_COMPARE_VALIDATE_ALL,
179  pk_syoscb::SYOSCB_HASH_COMPARE_VALIDATE_NO_MATCH: begin
180  cl_syoscb_hash_aa_wrapper#(HASH_DIGEST_WIDTH) hash;
181  cl_syoscb_queue_hash#(HASH_DIGEST_WIDTH)::tp_digest sec_digest;
182 
183  hash = owner_hash.get_hash();
184  primary = primary_proxy.get_item();
185  comparer = this.cfg.get_comparer(this.owner.get_name(), primary.get_producer());
186  if(comparer == null) begin
187  comparer = this.cfg.get_default_comparer();
188  end
189 
190  //Iterate through hash, comparing every entry to our primary entry
191  if(hash.first(sec_digest)) begin
192  do begin
193  int size_before = hash.get_size(sec_digest);
194 
195  //Iterate through all items with this hash:
196  for(int i=0; i<hash.get_size(sec_digest); i++) begin
197 
198  secondary = hash.get_item(sec_digest, i);
199 
200  if(primary.compare(secondary, comparer)) begin //True comparison => different hash but same contents
201  string header, body;
202  int table_width;
203 
204  table_width = cl_syoscb_string_library::generate_cmp_table_body('{primary, secondary}, this.cfg, body);
205  header = cl_syoscb_string_library::generate_cmp_table_header(
206  table_width,
207  $sformatf(
208  "[%s] Seq. items with different hash but same contents were found\nPrimary: %x. Secondary: %x",
209  this.cfg.get_scb_name(),
210  primary_proxy_hash.digest,
211  sec_digest
212  )
213  );
214  `uvm_error("MISCMP_HASH", {"\n", header, body})
215  end
216  end
217  end while (hash.next(sec_digest));
218  end
219  end
220  default: begin
221  t_hash_compare_check hcc = this.cfg.get_hash_compare_check();
222  `uvm_fatal("QUEUE_ERROR", $sformatf("[%s] Value of cfg.hash_compare_check (%s, %d) was not valid",
223  this.cfg.get_scb_name(),
224  hcc.name(),
225  hcc))
226  end
227  endcase
228 endfunction: validate_no_match
virtual cl_syoscb_proxy_item_base search(cl_syoscb_proxy_item_base proxy_item)
Locator API: See cl_syoscb_queue_locator_base::search for details
virtual tp_aa_hash get_hash()
Gets the hash AA wrapper used for this queue.
virtual uvm_comparer get_comparer(string queue_name, string producer_name)
Configuration API: Returns the comparer associated with a given queue and producer.
The UVM scoreboard item which wraps uvm_sequence_item .
cl_syoscb_cfg cfg
Local handle to the SCB cfg.
virtual uvm_comparer get_default_comparer()
Configuration API: Get the value of the default_comparer member variable
cl_syoscb_item get_item(tp_digest digest, int unsigned idx=0)
Gets the scoreboard item at an index with a given hash value.
Base class for all proxy items.
Locator class for searching over generic hash queues.
Locator base class defining the locator API used for searching in queues.
virtual t_hash_compare_check get_hash_compare_check()
Configuration API: Get the value of the hash_compare_check member variable
virtual bit validate_match(cl_syoscb_proxy_item_base primary_proxy, cl_syoscb_proxy_item_base secondary_proxy)
Validates that a sequence item found in a secondary hash queue matches the sequence item being search...
cl_syoscb_queue_base owner
The queue owning this locator.
A wrapper around an associative array, used for storing hash queues.
virtual bit set_queue(cl_syoscb_queue_base owner)
Locator API: Sets the queue that this locator is associated with
static int generate_cmp_table_body(cl_syoscb_item items[], cl_syoscb_cfg cfg, output string result)
Generates the body of a comparison table.
Proxy item implementation for hash queues.
virtual string get_scb_name()
Configuration API: Get the name of the SCB that this cfg is related to
Class which represents the base concept of a hash queue.
virtual void validate_no_match(cl_syoscb_proxy_item_base primary_proxy)
Validates that no sequence item in this secondary hash queue matches the primary sequence item being ...

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