| 1 | // ========== Copyright Header Begin ========================================== |
| 2 | // |
| 3 | // OpenSPARC T2 Processor File: ZeroInManager.vr |
| 4 | // Copyright (C) 1995-2007 Sun Microsystems, Inc. All Rights Reserved |
| 5 | // 4150 Network Circle, Santa Clara, California 95054, U.S.A. |
| 6 | // |
| 7 | // * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| 8 | // |
| 9 | // This program is free software; you can redistribute it and/or modify |
| 10 | // it under the terms of the GNU General Public License as published by |
| 11 | // the Free Software Foundation; version 2 of the License. |
| 12 | // |
| 13 | // This program is distributed in the hope that it will be useful, |
| 14 | // but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 15 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 16 | // GNU General Public License for more details. |
| 17 | // |
| 18 | // You should have received a copy of the GNU General Public License |
| 19 | // along with this program; if not, write to the Free Software |
| 20 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| 21 | // |
| 22 | // For the avoidance of doubt, and except that if any non-GPL license |
| 23 | // choice is available it will apply instead, Sun elects to use only |
| 24 | // the General Public License version 2 (GPLv2) at this time for any |
| 25 | // software where a choice of GPL license versions is made |
| 26 | // available with the language indicating that GPLv2 or any later version |
| 27 | // may be used, or where a choice of which version of the GPL is applied is |
| 28 | // otherwise unspecified. |
| 29 | // |
| 30 | // Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, |
| 31 | // CA 95054 USA or visit www.sun.com if you need additional information or |
| 32 | // have any questions. |
| 33 | // |
| 34 | // ========== Copyright Header End ============================================ |
| 35 | #include <vera_defines.vrh> |
| 36 | #include <ListMacros.vrh> |
| 37 | |
| 38 | #include "ZeroInDefines.vri" |
| 39 | // std disp |
| 40 | #include "std_display_defines.vri" |
| 41 | #include "std_display_class.vrh" |
| 42 | // plus args |
| 43 | #include "plusArgMacros.vri" |
| 44 | |
| 45 | class AssertionInfo { |
| 46 | string _pathToAssertion; // Hierarchical path to assertion |
| 47 | string _type; |
| 48 | string _module; |
| 49 | string _statistic; |
| 50 | bit[63:0] _valueToCheck; |
| 51 | task new (string a_type, |
| 52 | string a_path, |
| 53 | string a_module, |
| 54 | string a_statistic = "", |
| 55 | bit[63:0] a_valueToCheck = 1 |
| 56 | ) { |
| 57 | _pathToAssertion = a_path; |
| 58 | _type = a_type; |
| 59 | _module = a_module; |
| 60 | _statistic = a_statistic; |
| 61 | _valueToCheck = a_valueToCheck; |
| 62 | } |
| 63 | } |
| 64 | |
| 65 | MakeVeraList(AssertionInfo); |
| 66 | |
| 67 | class ZeroInManager { |
| 68 | StandardDisplay _dbg; |
| 69 | bit _zeroInCheckOff; |
| 70 | string _name; |
| 71 | local bit _rtlOnly; |
| 72 | |
| 73 | local VeraList_AssertionInfo _listOfAssertions; |
| 74 | |
| 75 | task new (StandardDisplay a_dbg, string a_name); |
| 76 | |
| 77 | task turnOffAllAssertionsInModule(string a_moduleName); |
| 78 | |
| 79 | // Add to list of a 0in assertions being checked |
| 80 | virtual task addCheck(string a_type, |
| 81 | string a_pathToAssertion, |
| 82 | string a_moduleName="", |
| 83 | string a_statistic="", |
| 84 | bit [63:0] a_valueToCheck = 0); |
| 85 | |
| 86 | // disable checker. |
| 87 | virtual task disableCheck(string a_type, string a_pathToAssertion, string a_moduleName=""); |
| 88 | |
| 89 | // enable checker. |
| 90 | virtual task enableCheck(string a_type, string a_pathToAssertion, string a_moduleName=""); |
| 91 | |
| 92 | // check if the assertion is covered |
| 93 | // return 1 if covered, else return 0. |
| 94 | virtual function bit checkIfCovered(string a_type, string a_pathToAssertion, |
| 95 | string a_statistic, bit[63:0] a_val); |
| 96 | |
| 97 | // check if assertion fired. |
| 98 | // return 1 if fired, else return 0. |
| 99 | function bit checkIfFired(string a_type, string a_pathToAssertion, |
| 100 | string a_check, string a_module); |
| 101 | |
| 102 | // Check if all 0in cheks that have been added are covered |
| 103 | // Return 1 if covered, else return 0 |
| 104 | virtual function bit coveredAllChecks(); |
| 105 | |
| 106 | local function zin_status conv2zin_status(integer i) { |
| 107 | case (i) { |
| 108 | 0 : conv2zin_status = ZIN_STATUS_SUCCESS; |
| 109 | 1 : conv2zin_status = ZIN_STATUS_INCORRECT_CHECKER_IDENTIFIER; |
| 110 | 2 : conv2zin_status = ZIN_STATUS_NOT_READY_FOR_ZIN_CALLS; |
| 111 | 3 : conv2zin_status = ZIN_STATUS_ILLEGAL_NULL_PARAMS; |
| 112 | 4 : conv2zin_status = ZIN_STATUS_NO_CHECKERS_OF_GIVEN_TYPE; |
| 113 | 5 : conv2zin_status = ZIN_STATUS_NO_CHECKER_OF_GIVEN_NAME; |
| 114 | 6 : conv2zin_status = ZIN_STATUS_NO_INFO_PORT_WITH_GIVEN_NAME; |
| 115 | 7 : conv2zin_status = ZIN_STATUS_UNSUPPORTED_INFO_TYPE; |
| 116 | 8 : conv2zin_status = ZIN_STATUS_INCORRECT_DB_NAME; |
| 117 | 9 : conv2zin_status = ZIN_STATUS_CORRUPTED_DB; |
| 118 | 10 : conv2zin_status = ZIN_STATUS_INCORRECT_DB_HANDLE; |
| 119 | 11 : conv2zin_status = ZIN_STATUS_ILLEGAL_VALUES_FOR_CACTION; |
| 120 | default: conv2zin_status = ZIN_STATUS_UNKNOWN; |
| 121 | } |
| 122 | } |
| 123 | |
| 124 | local function zin_checker_action conv2zin_checker_action(integer i) { |
| 125 | case (i) { |
| 126 | 0: conv2zin_checker_action = ZIN_CHECKER_ACTION_NONE; |
| 127 | 1: conv2zin_checker_action = ZIN_CHECKER_ACTION_STOP; |
| 128 | 2: conv2zin_checker_action = ZIN_CHECKER_ACTION_FINISH; |
| 129 | default: { |
| 130 | _dbg.dispmon(_name, MON_ERROR, |
| 131 | psprintf("Invalid checker action seen: %d", i)); |
| 132 | } |
| 133 | } |
| 134 | } |
| 135 | } |
| 136 | |
| 137 | task ZeroInManager::new (StandardDisplay a_dbg, string a_name) |
| 138 | { |
| 139 | _dbg = a_dbg; |
| 140 | _name = a_name; |
| 141 | _listOfAssertions = new; |
| 142 | _zeroInCheckOff = 1; |
| 143 | |
| 144 | //if (get_plus_arg(CHECK, "runsim_0incheck")) { |
| 145 | if (mChkPlusarg(runsim_0incheck)) { |
| 146 | _zeroInCheckOff = 0; |
| 147 | } |
| 148 | //if (get_plus_arg(CHECK, "runsim_0insearch")) { |
| 149 | if (mChkPlusarg(runsim_0insearch)) { |
| 150 | _zeroInCheckOff = 0; |
| 151 | } |
| 152 | |
| 153 | if (_zeroInCheckOff) |
| 154 | _dbg.dispmon(_name, MON_ALWAYS, "new()... ignoring all Zero In commands from testbench"); |
| 155 | |
| 156 | // sim_type may not be always defined, so I use rtl as default |
| 157 | _rtlOnly = 1; |
| 158 | // if (get_plus_arg(CHECK, "sim_type=")) { |
| 159 | // string plusArgValStr; |
| 160 | // bit [63:0] plusArgVal = get_plus_arg(STR, "sim_type="); |
| 161 | // plusArgValStr.bittostr(plusArgVal); |
| 162 | // case (plusArgValStr) { |
| 163 | // "rtl": _rtlOnly = 1; |
| 164 | // "gate", "gates": _rtlOnly = 0; |
| 165 | // } |
| 166 | // } |
| 167 | } |
| 168 | |
| 169 | task ZeroInManager::turnOffAllAssertionsInModule(string a_moduleName) |
| 170 | { |
| 171 | zin_status zinStat; |
| 172 | integer retVal; |
| 173 | |
| 174 | if (_zeroInCheckOff) return; |
| 175 | |
| 176 | // Turn off all assertions in the coverage file |
| 177 | retVal = zin_checker_turn_off("", "", a_moduleName, ZIN_NO_SEVERITY); |
| 178 | zinStat = conv2zin_status(retVal); |
| 179 | if (zinStat == ZIN_STATUS_SUCCESS) { |
| 180 | _dbg.dispmon(_name, MON_ALWAYS, |
| 181 | psprintf("zin_checker_turn_off succeeded for all assertions in module %s", a_moduleName)); |
| 182 | } |
| 183 | else { |
| 184 | _dbg.dispmon(_name, MON_ERROR, |
| 185 | psprintf("zin_checker_turn_off failed for with status %s for all assertions in module %s", |
| 186 | zinStat, "")); |
| 187 | } |
| 188 | } |
| 189 | |
| 190 | // add to list of a 0in assertions being checked. Make sure assertion is enabled. |
| 191 | task ZeroInManager::addCheck(string a_type, |
| 192 | string a_pathToAssertion, |
| 193 | string a_moduleName="", |
| 194 | string a_statistic="", |
| 195 | bit [63:0] a_valueToCheck = 1) |
| 196 | { |
| 197 | AssertionInfo info; |
| 198 | |
| 199 | if (_zeroInCheckOff) return; |
| 200 | |
| 201 | info = new (a_type, a_pathToAssertion, a_moduleName, a_statistic, a_valueToCheck); |
| 202 | _listOfAssertions.push_back(info); |
| 203 | |
| 204 | // Turn on check |
| 205 | enableCheck(a_type, a_pathToAssertion, a_moduleName); |
| 206 | |
| 207 | } |
| 208 | |
| 209 | // disable 0in checker. |
| 210 | task ZeroInManager::disableCheck(string a_type, string a_pathToAssertion, string a_moduleName="") |
| 211 | { |
| 212 | integer retVal; |
| 213 | zin_status zinStat; |
| 214 | |
| 215 | if (_zeroInCheckOff) return; |
| 216 | |
| 217 | retVal = zin_checker_turn_off(a_type, a_pathToAssertion, a_moduleName, ZIN_NO_SEVERITY); |
| 218 | zinStat = conv2zin_status(retVal); |
| 219 | if (zinStat == ZIN_STATUS_SUCCESS) { |
| 220 | _dbg.dispmon(_name, MON_DEBUG, |
| 221 | psprintf("zin_checker_turn_off succeeded for (%s, %s) in module %s", a_type, a_pathToAssertion, a_moduleName)); |
| 222 | } |
| 223 | else { |
| 224 | _dbg.dispmon(_name, MON_ERROR, |
| 225 | psprintf("zin_checker_turn_off failed with status %s for (%s, %s) in module %s", |
| 226 | zinStat, a_type, a_pathToAssertion, a_moduleName)); |
| 227 | } |
| 228 | } |
| 229 | |
| 230 | // enable 0in checker. |
| 231 | task ZeroInManager::enableCheck(string a_type, string a_pathToAssertion, string a_moduleName="") |
| 232 | { |
| 233 | integer retVal; |
| 234 | zin_status zinStat; |
| 235 | |
| 236 | if (_zeroInCheckOff) return; |
| 237 | |
| 238 | retVal = zin_checker_turn_on(a_type, a_pathToAssertion, a_moduleName, ZIN_NO_SEVERITY); |
| 239 | zinStat = conv2zin_status(retVal); |
| 240 | if (zinStat == ZIN_STATUS_SUCCESS) { |
| 241 | _dbg.dispmon(_name, MON_DEBUG, |
| 242 | psprintf("zin_checker_turn_on succeeded for (%s, %s) in module %s", a_type, a_pathToAssertion, a_moduleName)); |
| 243 | } |
| 244 | else { |
| 245 | _dbg.dispmon(_name, MON_ERROR, |
| 246 | psprintf("zin_checker_turn_on failed with status %s for (%s, %s) in module %s", |
| 247 | zinStat, a_type, a_pathToAssertion, a_moduleName)); |
| 248 | } |
| 249 | } |
| 250 | |
| 251 | // check if the assertion is covered. |
| 252 | function bit ZeroInManager::checkIfCovered(string a_type, string a_pathToAssertion, |
| 253 | string a_statistic, bit[63:0] a_val) |
| 254 | { |
| 255 | integer retVal; |
| 256 | zin_status zinStat; |
| 257 | integer severity = ZIN_NO_SEVERITY; |
| 258 | integer loVal, hiVal; |
| 259 | |
| 260 | if (_zeroInCheckOff) { |
| 261 | checkIfCovered = 1; |
| 262 | return; |
| 263 | } |
| 264 | |
| 265 | checkIfCovered = 0; |
| 266 | |
| 267 | // Make sure the assertion is evaluated at least once |
| 268 | retVal = zin_checker_info(a_type, a_pathToAssertion, a_statistic, loVal, hiVal); |
| 269 | zinStat = conv2zin_status(retVal); |
| 270 | |
| 271 | if (zinStat == ZIN_STATUS_SUCCESS) { |
| 272 | _dbg.dispmon(_name, MON_DEBUG, |
| 273 | psprintf("zin_checker_info(%s, %s, %s ...) returned %s with (hiVal:%d, loVal%d)", |
| 274 | a_type, a_pathToAssertion, a_statistic, zinStat, hiVal, loVal)); |
| 275 | } |
| 276 | else { |
| 277 | _dbg.dispmon(_name, MON_ERROR, |
| 278 | psprintf("zin_checker_info(%s, %s, ...) returned %s with (hiVal:%d, loVal%d)", |
| 279 | a_type, a_pathToAssertion, zinStat, hiVal, loVal)); |
| 280 | return; |
| 281 | } |
| 282 | if (zinStat == ZIN_STATUS_SUCCESS) { |
| 283 | checkIfCovered = {hiVal, loVal} >= a_val; |
| 284 | } |
| 285 | } |
| 286 | |
| 287 | // check if the assertion fired. |
| 288 | function bit ZeroInManager::checkIfFired(string a_type, string a_pathToAssertion, |
| 289 | string a_check, string a_module) |
| 290 | { |
| 291 | integer retVal; |
| 292 | zin_status zinStat; |
| 293 | integer severity = ZIN_NO_SEVERITY; |
| 294 | integer firing_count; |
| 295 | |
| 296 | if (_zeroInCheckOff) { |
| 297 | checkIfFired = 1; |
| 298 | return; |
| 299 | } |
| 300 | |
| 301 | checkIfFired = 0; |
| 302 | |
| 303 | // Make sure the assertion fired at least once |
| 304 | retVal = zin_checker_firing_count(a_type, a_pathToAssertion, a_check, a_module, |
| 305 | severity, firing_count); |
| 306 | zinStat = conv2zin_status(retVal); |
| 307 | |
| 308 | if (zinStat == ZIN_STATUS_SUCCESS) { |
| 309 | _dbg.dispmon(_name, MON_DEBUG, |
| 310 | psprintf("zin_checker_firing_count(%s, %s, %s ...) returned %s with (count:%d)", |
| 311 | a_type, a_pathToAssertion, a_check, zinStat, firing_count)); |
| 312 | } |
| 313 | else { |
| 314 | _dbg.dispmon(_name, MON_ERROR, |
| 315 | psprintf("zin_checker_firing_count(%s, %s, %s, ...) returned %s with (count:%d)", |
| 316 | a_type, a_pathToAssertion, a_check, zinStat, firing_count)); |
| 317 | return; |
| 318 | } |
| 319 | if (zinStat == ZIN_STATUS_SUCCESS) { |
| 320 | checkIfFired = firing_count >= 1; |
| 321 | } |
| 322 | } |
| 323 | |
| 324 | // check if all 0in checks that have been added are covered. |
| 325 | function bit ZeroInManager::coveredAllChecks() |
| 326 | { |
| 327 | VeraListIterator_AssertionInfo iter; |
| 328 | AssertionInfo info; |
| 329 | |
| 330 | coveredAllChecks = 1; |
| 331 | |
| 332 | if (_zeroInCheckOff) return; |
| 333 | |
| 334 | for (iter = _listOfAssertions.start(); iter.neq(_listOfAssertions.finish());) { |
| 335 | info = iter.data(); |
| 336 | if (info._statistic.compare("") != 0) { |
| 337 | coveredAllChecks = coveredAllChecks && |
| 338 | checkIfCovered(info._type, info._pathToAssertion, |
| 339 | info._statistic, info._valueToCheck); |
| 340 | } |
| 341 | iter.next(); |
| 342 | } |
| 343 | } |