URL
https://opencores.org/ocsvn/uart2bus_testbench/uart2bus_testbench/trunk
Subversion Repositories uart2bus_testbench
[/] [uart2bus_testbench/] [trunk/] [tb/] [uvm_src/] [base/] [uvm_spell_chkr.svh] - Rev 16
Compare with Previous | Blame | View Log
////------------------------------------------------------------------------------// Copyright 2011 Mentor Graphics Corporation// Copyright 2011 Cadence Design Systems, Inc.// Copyright 2011 Synopsys, Inc.// 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.//------------------------------------------------------------------------------//----------------------------------------------------------------------// class uvm_spell_chkr//----------------------------------------------------------------------class uvm_spell_chkr #(type T=int);typedef T tab_t[string];static const int unsigned max = '1;//--------------------------------------------------------------------// check//// primary interface to the spell checker. The function takes two// arguments, a table of strings and a string to check. The table is// organized as an associative array of type T. E.g.//// T strtab[string]//// It doesn't matter what T is since we are only concerned with the// string keys. However, we need T in order to make argument types// match.//// First, we do the simple thing and see if the string already is in// the string table by calling the ~exists()~ method. If it does exist// then there is a match and we're done. If the string doesn't exist// in the table then we invoke the spell checker algorithm to see if// our string is a misspelled variation on a string that does exist in// the table.//// The main loop traverses the string table computing the levenshtein// distance between each string and the string we are checking. The// strings in the table with the minimum distance are considered// possible alternatives. There may be more than one string in the// table with a minimum distance. So all the alternatives are stored// in a queue.//// Note: This is not a particularly efficient algorithm. It requires// computing the levenshtein distance for every string in the string// table. If that list were very large the run time could be long.// For the resources application in UVM probably the size of the// string table is not excessive and run times will be fast enough.// If, on average, that proves to be an invalid assumption then we'll// have to find ways to optimize this algorithm.//// note: strtab should not be modified inside check()//--------------------------------------------------------------------static function bit check ( /* const */ ref tab_t strtab, input string s);string key;int distance;int unsigned min;string min_key[$];if(strtab.exists(s)) beginreturn 1;endmin = max;foreach(strtab[key]) begindistance = levenshtein_distance(key, s);// A distance < 0 means either key, s, or both are empty. This// should never happen here but we check for that condition just// in case.if(distance < 0)continue;if(distance < min) begin// set a new minimum. Clean out the queue since previous// alternatives are now invalidated.min = distance;min_key.delete();min_key.push_back(key);continue;endif(distance == min) beginmin_key.push_back(key);endend// if (min == max) then the string table is emptyif(min == max) begin`uvm_info("UVM/CONFIGDB/SPELLCHK",$sformatf("%s not located, no alternatives to suggest", s),UVM_NONE)endelse// dump all the alternatives with the minimum distancebeginstring q[$];foreach(min_key[i]) beginq.push_back(min_key[i]);q.push_back("|");endif(q.size())void'(q.pop_back());`uvm_info("UVM/CONFIGDB/SPELLCHK",$sformatf("%s not located, did you mean %s", s, `UVM_STRING_QUEUE_STREAMING_PACK(q)),UVM_NONE)endreturn 0;endfunction//--------------------------------------------------------------------// levenshtein_distance//// Compute levenshtein distance between s and t// The Levenshtein distance is defined as The smallest number of// insertions, deletions, and substitutions required to change one// string into another. There is a tremendous amount of information// available on Levenshtein distance on the internet. Two good// sources are wikipedia and nist.gov. A nice, simple explanation of// the algorithm is at// http://www.codeproject.com/KB/recipes/Levenshtein.aspx. Use google// to find others.//// This implementation of the Levenshtein// distance computation algorithm is a SystemVerilog adaptation of the// C implementatiion located at http://www.merriampark.com/ldc.htm.//--------------------------------------------------------------------static local function int levenshtein_distance(string s, string t);int k, i, j, n, m, cost, distance;int d[];//Step 1n = s.len() + 1;m = t.len() + 1;if(n == 1 || m == 1)return -1; //a negative return value means that one or both strings are empty.d = new[m*n];//Step 2for(k = 0; k < n; k++)d[k] = k;for(k = 0; k < m; k++)d[k*n] = k;//Steps 3 and 4for(i = 1; i < n; i++) beginfor(j = 1; j < m; j++) begin//Step 5cost = !(s[i-1] == t[j-1]);//Step 6d[j*n+i] = minimum(d[(j-1)*n+i]+1, d[j*n+i-1]+1, d[(j-1)*n+i-1]+cost);endenddistance = d[n*m-1];return distance;endfunction//--------------------------------------------------------------------// Gets the minimum of three values//--------------------------------------------------------------------static local function int minimum(int a, int b, int c);int min = a;if(b < min)min = b;if(c < min)min = c;return min;endfunctionendclass
