OpenCores
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] - Blame information for rev 16

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 16 HanySalah
//
2
//------------------------------------------------------------------------------
3
//   Copyright 2011 Mentor Graphics Corporation
4
//   Copyright 2011 Cadence Design Systems, Inc.
5
//   Copyright 2011 Synopsys, Inc.
6
//   All Rights Reserved Worldwide
7
//
8
//   Licensed under the Apache License, Version 2.0 (the
9
//   "License"); you may not use this file except in
10
//   compliance with the License.  You may obtain a copy of
11
//   the License at
12
//
13
//       http://www.apache.org/licenses/LICENSE-2.0
14
//
15
//   Unless required by applicable law or agreed to in
16
//   writing, software distributed under the License is
17
//   distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
18
//   CONDITIONS OF ANY KIND, either express or implied.  See
19
//   the License for the specific language governing
20
//   permissions and limitations under the License.
21
//------------------------------------------------------------------------------
22
 
23
 
24
 
25
//----------------------------------------------------------------------
26
// class uvm_spell_chkr
27
//----------------------------------------------------------------------
28
class uvm_spell_chkr #(type T=int);
29
 
30
  typedef T tab_t[string];
31
  static const int unsigned max = '1;
32
 
33
  //--------------------------------------------------------------------
34
  // check
35
  //
36
  // primary interface to the spell checker.  The function takes two
37
  // arguments, a table of strings and a string to check.  The table is
38
  // organized as an associative array of type T.  E.g.
39
  //
40
  //    T strtab[string]
41
  //
42
  // It doesn't matter what T is since we are only concerned with the
43
  // string keys. However, we need T in order to make argument types
44
  // match.
45
  //
46
  // First, we do the simple thing and see if the string already is in
47
  // the string table by calling the ~exists()~ method.  If it does exist
48
  // then there is a match and we're done.  If the string doesn't exist
49
  // in the table then we invoke the spell checker algorithm to see if
50
  // our string is a misspelled variation on a string that does exist in
51
  // the table.
52
  //
53
  // The main loop traverses the string table computing the levenshtein
54
  // distance between each string and the string we are checking.  The
55
  // strings in the table with the minimum distance are considered
56
  // possible alternatives.  There may be more than one string in the
57
  // table with a minimum distance. So all the alternatives are stored
58
  // in a queue.
59
  //
60
  // Note: This is not a particularly efficient algorithm.  It requires
61
  // computing the levenshtein distance for every string in the string
62
  // table.  If that list were very large the run time could be long.
63
  // For the resources application in UVM probably the size of the
64
  // string table is not excessive and run times will be fast enough.
65
  // If, on average, that proves to be an invalid assumption then we'll
66
  // have to find ways to optimize this algorithm.
67
  //
68
  // note: strtab should not be modified inside check()
69
  //--------------------------------------------------------------------
70
  static function bit check ( /* const */ ref tab_t strtab, input string s);
71
 
72
    string key;
73
    int distance;
74
    int unsigned min;
75
    string min_key[$];
76
 
77
    if(strtab.exists(s)) begin
78
      return 1;
79
    end
80
 
81
    min = max;
82
    foreach(strtab[key]) begin
83
      distance = levenshtein_distance(key, s);
84
 
85
      // A distance < 0 means either key, s, or both are empty.  This
86
      // should never happen here but we check for that condition just
87
      // in case.
88
      if(distance < 0)
89
        continue;
90
 
91
      if(distance < min) begin
92
        // set a new minimum.  Clean out the queue since previous
93
        // alternatives are now invalidated.
94
        min = distance;
95
        min_key.delete();
96
        min_key.push_back(key);
97
        continue;
98
      end
99
 
100
      if(distance == min) begin
101
        min_key.push_back(key);
102
      end
103
 
104
    end
105
 
106
 
107
    // if (min == max) then the string table is empty
108
    if(min == max) begin
109
          `uvm_info("UVM/CONFIGDB/SPELLCHK",$sformatf("%s not located, no alternatives to suggest", s),UVM_NONE)
110
    end
111
    else
112
    // dump all the alternatives with the minimum distance
113
    begin
114
                string q[$];
115
 
116
                foreach(min_key[i]) begin
117
                        q.push_back(min_key[i]);
118
                        q.push_back("|");
119
                end
120
                if(q.size())
121
                        void'(q.pop_back());
122
 
123
                `uvm_info("UVM/CONFIGDB/SPELLCHK",$sformatf("%s not located, did you mean %s", s, `UVM_STRING_QUEUE_STREAMING_PACK(q)),UVM_NONE)
124
    end
125
 
126
    return 0;
127
 
128
  endfunction
129
 
130
 
131
  //--------------------------------------------------------------------
132
  // levenshtein_distance
133
  //
134
  // Compute levenshtein distance between s and t
135
  // The Levenshtein distance is defined as The smallest number of
136
  // insertions, deletions, and substitutions required to change one
137
  // string into another.  There is a tremendous amount of information
138
  // available on Levenshtein distance on the internet.  Two good
139
  // sources are wikipedia and nist.gov.  A nice, simple explanation of
140
  // the algorithm is at
141
  // http://www.codeproject.com/KB/recipes/Levenshtein.aspx.  Use google
142
  // to find others.
143
  //
144
  // This implementation of the Levenshtein
145
  // distance computation algorithm is a SystemVerilog adaptation of the
146
  // C implementatiion located at http://www.merriampark.com/ldc.htm.
147
  //--------------------------------------------------------------------
148
  static local function int levenshtein_distance(string s, string t);
149
 
150
    int k, i, j, n, m, cost, distance;
151
    int d[];
152
 
153
    //Step 1
154
    n = s.len() + 1;
155
    m = t.len() + 1;
156
 
157
    if(n == 1 || m == 1)
158
      return -1; //a negative return value means that one or both strings are empty.
159
 
160
    d = new[m*n];
161
 
162
    //Step 2
163
    for(k = 0; k < n; k++)
164
      d[k] = k;
165
 
166
    for(k = 0; k < m; k++)
167
      d[k*n] = k;
168
 
169
    //Steps 3 and 4
170
    for(i = 1; i < n; i++) begin
171
      for(j = 1; j < m; j++) begin
172
 
173
        //Step 5
174
        cost = !(s[i-1] == t[j-1]);
175
 
176
        //Step 6
177
        d[j*n+i] = minimum(d[(j-1)*n+i]+1, d[j*n+i-1]+1, d[(j-1)*n+i-1]+cost);
178
 
179
      end
180
    end
181
 
182
    distance = d[n*m-1];
183
    return distance;
184
 
185
  endfunction
186
 
187
  //--------------------------------------------------------------------
188
  // Gets the minimum of three values
189
  //--------------------------------------------------------------------
190
  static local function int minimum(int a, int b, int c);
191
 
192
    int min = a;
193
 
194
    if(b < min)
195
      min = b;
196
    if(c < min)
197
      min = c;
198
 
199
    return min;
200
 
201
  endfunction
202
 
203
endclass

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.