SyoSil ApS UVM Scoreboard  1.0.3.0
cl_syoscb_string_library.svh
1 /// A utility class holding a number of static methods for performing string manipulation.
2 class cl_syoscb_string_library extends uvm_object;
3  //-------------------------------------
4  // Non randomizable variables
5  //-------------------------------------
6 
7 
8  //-------------------------------------
9  // UVM Macros
10  //-------------------------------------
11  `uvm_object_utils_begin(cl_syoscb_string_library)
12 
13  `uvm_object_utils_end
14 
15  //-------------------------------------
16  // Constructor
17  //-------------------------------------
18  function new(string name = "cl_syoscb_string_library");
19  super.new(name);
20  endfunction: new
21 
22  //-------------------------------------
23  // Functions
24  //-------------------------------------
25  extern static function string pad_str(string str, int unsigned max_length, string expand = " ", bit side = 1'b0);
26  extern static function string scb_separator_str(int unsigned pre_length);
27  extern static function string scb_header_str(string hn, int unsigned pre_length, bit side,
28  string col_names[] = '{" Inserts " , " Matches ", " Flushed ", " Orphans "});
29  extern static function void split_string(string in, byte delim[], output string out[]);
30  extern static function int merge_string_arrays(string inputs[$][], string concat = "|", output string result);
31  extern static function string generate_cmp_table_header(int table_width, string header_text);
32  extern static function int generate_cmp_table_body(cl_syoscb_item items[], cl_syoscb_cfg cfg, output string result);
33  extern static function string generate_cmp_table_footer(int table_width, uvm_comparer comparer);
34  extern static function string sprint_item(cl_syoscb_item item, cl_syoscb_cfg cfg);
35 
37 
38 /// Pads the input string with another string until it reaches a given length.
39 /// \param str The input string to pad
40 /// \param max_length The length to pad it to
41 /// \param expand The character(s) to insert on the left/right of the original string until \c max_length is reached
42 /// \param side Which side of the string to insert padding on. If 1, inserts on the right, if 0, inserts on the left
43 /// \return The padded string
44 function string cl_syoscb_string_library::pad_str(string str, int unsigned max_length, string expand = " ", bit side = 1'b0);
45  if(str.len() >= max_length) begin
46  return str;
47  end
48 
49  while(str.len() < max_length) begin
50  str = (side == 1'b1) ? {str, expand} : {expand, str};
51  end
52 
53  return str;
54 endfunction: pad_str
55 
56 /// Creates a new separator string for scoreboard stat tables.
57 /// \param pre_length: The width of the first column of the table
58 /// \return The separator string
59 function string cl_syoscb_string_library::scb_separator_str(int unsigned pre_length);
60  string str;
61 
62  str = { "\n",
63  cl_syoscb_string_library::pad_str("", pre_length, "-"),
64  "+----------+----------+----------+----------+"};
65 
66  return str;
67 endfunction: scb_separator_str
68 
69 /// Creates a new header string for a scoreboard stat table.
70 /// \param hn The name of the table
71 /// \param pre_length The width of the first column of the table
72 /// \param side Whether to pad the table name with spaces on the right (1) or left (0)
73 /// \param col_names The names of the columns in the table. Must have exactly 4 entries, each of which should be 10 characters wide
74 function string cl_syoscb_string_library::scb_header_str(string hn, int unsigned pre_length, bit side,
75  string col_names[] = '{" Inserts " , " Matches ", " Flushed ", " Orphans "});
76  string str;
77 
78  if(col_names.size() != 4) begin
79  `uvm_error("CFG_ERROR", $sformatf("col_names must have exactly 4 entries, found %0d", col_names.size()))
80  end
81 
82  str = cl_syoscb_string_library::scb_separator_str(1+pre_length);
83  str = {str, "\n",
84  cl_syoscb_string_library::pad_str(hn, pre_length+1, " ", side),
85  "|", col_names[0], "|", col_names[1], "|", col_names[2], "|", col_names[3], "|"};
86 
87  str = { str, cl_syoscb_string_library::scb_separator_str(1+pre_length)};
88 
89  return str;
90 endfunction: scb_header_str
91 
92 /// Splits the string 'in' by any of the delimiter strings in 'delim',
93 /// returning the result in 'out'.
94 ///
95 /// Example: in="Hello, world..", delim={",", " ", "."} => out={"Hello", "world"}
96 /// \param in: The input string to be split
97 /// \param delim: An array of possible delimiter characters to be used in splitting the string
98 /// \param out: A handle to an array in which the split strings will be placed.
99 function void cl_syoscb_string_library::split_string(string in, byte delim[], output string out[]);
100  int start; //start index of current substring
101  string res[$]; //queue of result strings
102  bit state; //Current state. 1'b0: Scan through delimiters. 1'b1: Scan through string
103  bit is_delim; //Flag indicating if in[idx] is a delimiter
104 
105  start = 0;
106  state = 1'b0;
107 
108  for(int idx=0; idx<in.len(); idx++) begin
109  //Check if current char is a delimiter
110  is_delim = 1'b0;
111  foreach (delim[i]) begin
112  if(in[idx] == delim[i]) begin
113  is_delim = 1'b1;
114  break;
115  end
116  end
117 
118  //Based on current state, handle delim value
119  if(state == 1'b0) begin //Delimiter scan
120  if(is_delim) begin
121  //Do nothing
122  end else begin
123  start = idx;
124  state = 1'b1;
125  end
126  end else begin //Scanning text
127  if(is_delim) begin //End of word
128  res.push_back(in.substr(start, idx-1));
129  state = 1'b0;
130  end //Else do nothing
131  end
132  end
133 
134  if(state == 1'b1) begin //Push in final string
135  res.push_back(in.substr(start, in.len()-1));
136  end
137  out = res;
138 endfunction: split_string
139 
140 /// Takes a queue of string arrays, merging these into a single string.
141 /// The output consists of the i'th lines of all entries concatenated together.
142 /// Each corresponding line is joined with a line break "\n".
143 /// Primarily intended to be used for merging item printouts previously split by split_string()
144 /// \param inputs A queue of string arrays. inputs[x] is a string array, and inputs [x][y] is the y'th line of that string
145 /// \param concat A concatenator to be used between strings. Defaults to "|"
146 /// \param result A string handle where the result is returned
147 /// \return The width of the resulting table
148 function int cl_syoscb_string_library::merge_string_arrays(string inputs[$][], string concat = "|", output string result);
149  int max_length; //Table with the most entries
150  int total_width; //Total width of all entries, excluding spacers
151 
152  if(inputs.size() < 2) begin
153  `uvm_error("STR_ERROR", "Must have at least two tables to merge")
154  end
155 
156  //Find the length of the longest string array + the width of all arrays
157  max_length = inputs[0].size();
158  total_width = inputs[0][0].len();
159  for(int i=1; i<inputs.size(); i++) begin
160  total_width += inputs[i][0].len();
161  if(inputs[i].size() > max_length) begin
162  max_length = inputs[i].size();
163  end
164  end
165  total_width = total_width + 3*(inputs.size()-1);
166 
167  //Add a top bar of '#'
168  result = {" ", { (total_width){"#"} }, "\n"};
169 
170  for(int i=0; i<max_length-1; i++) begin
171  result = {result, " "}; //Add leading " " to avoid questasim gobbling #'s
172  for(int j=0; j<inputs.size(); j++) begin
173  if(i >= inputs[j].size()-1) begin
174  //If inputs[j].size < max_length, we insert spaces for the remaining rows
175  result = {result, {(inputs[j][0].len()){" "}} };
176  end else begin
177  result = {result, inputs[j][i]};
178  end
179  //On all but the final column, add a concatenation symbol
180  if(j != inputs.size()-1) begin
181  result = {result, " ", concat, " "};
182  end
183  end
184  result = {result, "\n"};
185  end
186 
187  //Insert the final row of dashes
188  result = {result, " "};
189  for(int j=0; j<inputs.size(); j++) begin
190  result = {result, inputs[j][inputs[j].size()-1]};
191  if(j != inputs.size()-1) begin
192  result = {result, " ", concat, " "};
193  end
194  end
195  result = {result, "\n"};
196 
197  //Add a bottom bar of #
198  result = {result, " ", {(total_width){"#"}}, "\n"};
199 
200  return total_width;
201 endfunction: merge_string_arrays
202 
203 
204 /// Generates the body of a comparison table. Primarily used for inspecting miscompares.
205 ///
206 /// \param items An array of all cl_syoscb_items that must be included in the table
207 /// \param cfg The configuration object for the scoreboard
208 /// \param result Handle to a string in which the result is returned
209 /// \return The width of the comparison table
210 function int cl_syoscb_string_library::generate_cmp_table_body(cl_syoscb_item items[], cl_syoscb_cfg cfg, output string result);
211  string item_string;
212  string item_tokens[$][];
213 
214  foreach(items[i]) begin
215  string tokens[];
216  item_string = sprint_item(items[i], cfg);
217  split_string(item_string, '{"\n"}, tokens);
218  item_tokens.push_back(tokens);
219  end
220 
221  return merge_string_arrays(item_tokens, "|", result);
222 endfunction
223 
224 /// Generates the header section of a comparison table.
225 ///
226 /// \param table_width The width of the comparison table
227 /// \param header_text The text to be included in the header
228 /// \return A string containing the header
229 function string cl_syoscb_string_library::generate_cmp_table_header(int table_width, string header_text);
230  string pounds;
231  string header;
232  string header_text_split[];
233 
234  pounds = {(table_width){"#"}};
235  cl_syoscb_string_library::split_string(header_text, '{"\n"}, header_text_split);
236 
237  header = {" ", pounds, "\n"};
238  foreach(header_text_split[i]) begin
239  header = {header, " # ", pad_str(header_text_split[i], table_width-3, " ", 1'b1), "#\n"};
240  end
241 
242  return header;
243 endfunction: generate_cmp_table_header
244 
245 /// Generates the footer section of a comparison table.
246 ///
247 /// \param table_width The width of the comparison table
248 /// \param comparer The UVM comparer used to compare seq. items
249 function string cl_syoscb_string_library::generate_cmp_table_footer(int table_width, uvm_comparer comparer);
250  string comparer_miscompares;
251  string comparer_miscompares_tokens[];
252  string dashes, pounds, footer;
253  int show_max;
254 
255  comparer_miscompares = cl_syoscb_comparer_config::get_miscompares_from_comparer(comparer);
256  split_string(comparer_miscompares, '{"\n"}, comparer_miscompares_tokens);
257  show_max = cl_syoscb_comparer_config::get_show_max(comparer);
258  dashes = {table_width{"-"}};
259  pounds = {table_width{"#"}};
260 
261  footer = {" ", dashes, "\n",
262  $sformatf(" Results from uvm_comparer::get_miscompares() [show_max=%0d]\n", show_max),
263  " ", dashes, "\n" };
264 
265  //Include miscompares found
266  for(int i=0; i<show_max && i<comparer_miscompares_tokens.size(); i++) begin
267  string miscmp;
268  string tokens;
269 
270  tokens = comparer_miscompares_tokens[i];
271 
272  //Trim the "Miscompare for <item.field>" string away, preserving only "<item.field>: lhs=<lhs> : rhs=<rhs>"
273  //Not necessary on UVM_IEEE
274  `ifdef UVM_VERSION
275  miscmp = tokens;
276  `else
277  for(int j=0; j<tokens.len(); j++) begin
278  if(tokens[j] == ":") begin
279  if(miscmp == "") begin //Nothing included yet: Include <item.field>
280  miscmp = tokens.substr(0, j);
281  end else begin //Already included <item.field>, included lhs/rhs information
282  miscmp = {miscmp, tokens.substr(j+1, tokens.len()-1)};
283  break;
284  end
285  end
286  end
287  `endif
288 
289  footer = {footer, " ", miscmp, "\n"};
290  end
291 
292  footer = {footer, " ", pounds, "\n"};
293  return footer;
294 endfunction: generate_cmp_table_footer
295 
296 /// Utility function for printing sequence items using a table printer.
297 /// This function sprints the given seq. item. using the uvm_default_table_printer.
298 /// The value of the configuration object's default_printer_verbosity bit is used to control
299 /// how many array elements are included in long arrays. (See cl_syoscb_cfg#default_printer_verbosity)
300 ///
301 /// \param item The sequence item to sprint
302 /// \param cfg The configuration object for the current scoreboard
303 function string cl_syoscb_string_library::sprint_item(cl_syoscb_item item, cl_syoscb_cfg cfg);
304  uvm_printer printer;
305  bit verbosity;
306 
307  `ifdef UVM_VERSION
308  printer = uvm_table_printer::get_default();
309  `else
310  printer = uvm_default_table_printer;
311  `endif
312  verbosity = cfg.get_default_printer_verbosity();
313 
314  if(verbosity == 1'b1) begin
315  cl_syoscb_printer_config::set_printer_begin_elements(printer, -1);
316  cl_syoscb_printer_config::set_printer_end_elements(printer, -1);
317  end else begin
318  cl_syoscb_printer_config::set_printer_begin_elements(printer, 5);
319  cl_syoscb_printer_config::set_printer_end_elements(printer, 5);
320  end
321 
322  return item.sprint(printer);
323 endfunction: sprint_item
static string scb_separator_str(int unsigned pre_length)
Creates a new separator string for scoreboard stat tables.
A utility class holding a number of static methods for performing string manipulation.
static string generate_cmp_table_footer(int table_width, uvm_comparer comparer)
Generates the footer section of a comparison table.
static void split_string(string in, byte delim[], output string out[])
Splits the string &#39;in&#39; by any of the delimiter strings in &#39;delim&#39;, returning the result in &#39;out&#39;...
static string pad_str(string str, int unsigned max_length, string expand=" ", bit side=0b0)
Pads the input string with another string until it reaches a given length.
static string sprint_item(cl_syoscb_item item, cl_syoscb_cfg cfg)
Utility function for printing sequence items using a table printer. This function sprints the given s...
static int merge_string_arrays(string inputs[$][], string concat="|", output string result)
Takes a queue of string arrays, merging these into a single string.
static int generate_cmp_table_body(cl_syoscb_item items[], cl_syoscb_cfg cfg, output string result)
Generates the body of a comparison table.
static string generate_cmp_table_header(int table_width, string header_text)
Generates the header section of a comparison table.
static string scb_header_str(string hn, int unsigned pre_length, bit side, string col_names[]=(" Inserts ", " Matches ", " Flushed ", " Orphans "))
Creates a new header string for a scoreboard stat table.

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