|
Disabling Timing Checks SelectivelyAndi CarmonOrckit Communications
The VCS command line plusarg option +notimingchecks disables all Setup and Hold checkings of all the design. It is often necessary to selectivelly disable timing checks of one single cell (like a RAM) or some flip-flops. Well, here is a PLI function, named - guess what - $NoTimingChecks to do just that.
The PLI apllication is invoked as follows:
All cells which use the built-in system calls $setup, $hold or $setuphold functions in module mod_instance_name, and its hierarchical sub-modules are not cheked for timing. Note that, unlike the blanket coverage by +notimingchecks, the current PLI application works per instance basis. For example, mod_instance_name may be one single flip-flop, or one single instance of RAM. This is just the beginning! You can use $NoTimingChecks to disable the setup only, the hold only or both (default).
Here is the full invocation syntax:
By default, the system call disables the setup and hold checking. The application has been written and tested for VCS environment, although with little modification, the same routine can be used for Verilog-XL. The pli table file in VCS environment should be as follows.
$NoTimingChecks call=NoTimingChecks_call nocallback The listing for $NoTimingChecks is given below.
#include "vcsuser.h" #include "acc_user.h" #include <stdio.h> #include <stdlib.h> #include <string.h> #include <alloca.h> void NoTimingChecks_OneLevel(); void NoTimingChecks_OneCell(); void NoTimingChecks_abort(); void NoTimingChecks_paramcheck(); typedef struct { bool en_setup ; bool en_hold ; bool en_verbose ; } NoTC_config_type; NoTC_config_type *NoTC_config ; void NoTimingChecks_paramcheck() { int nump, i; NoTC_config = (NoTC_config_type *)malloc(sizeof(NoTC_config_type)); NoTC_config->en_setup = TRUE; NoTC_config->en_hold = TRUE; NoTC_config->en_verbose = FALSE; nump = tf_nump(); if (nump == 0) NoTimingChecks_abort(); else if (nump > 1) { if ((acc_fetch_fulltype(acc_handle_tfarg(1)) != accCellInstance) && (acc_fetch_fulltype(acc_handle_tfarg(1)) != accModuleInstance)) { io_printf("# Error($NoTimingCheck): Parameter #1 should be an instance name\n"); io_printf("# Aborting\n"); exit(2); } for (i = 2 ;i <= nump ; i++) { if (tf_typep(i) != tf_string) NoTimingChecks_abort(); if (strcmp(tf_strgetp(i), "setup_only") == 0) NoTC_config->en_hold = FALSE; else if (strcmp(tf_strgetp(i), "hold_only") == 0) NoTC_config->en_setup = FALSE; else if (strcmp(tf_strgetp(i), "verbose") == 0) NoTC_config->en_verbose = TRUE; else NoTimingChecks_abort(); } } } /* NoTimingChecks_check */ void NoTimingChecks_call() { handle top_handle, curr_mod_handle; int i; acc_initialize(); acc_configure(accDevelopmentVersion, "1.0"); acc_configure(accDisplayWarnings, "true"); acc_configure(accDisplayErrors, "true"); acc_configure(accMinTypMaxDelays, "false"); NoTimingChecks_paramcheck(); top_handle = acc_handle_tfarg(1); if (acc_fetch_fulltype(top_handle) == accCellInstance) NoTimingChecks_OneCell(top_handle); else { NoTimingChecks_OneLevel(top_handle); curr_mod_handle = NULL; while (curr_mod_handle = acc_next_child (top_handle, curr_mod_handle) ) NoTimingChecks_OneLevel(curr_mod_handle); } acc_close(); } /* NoTimingChecks_call */ void NoTimingChecks_OneLevel(mod_handle) handle (mod_handle); { handle cell_handle; if (acc_fetch_fulltype(mod_handle) == accCellInstance) return; else { io_printf("# Info ($NoTimingChecks) : Scanning module '%s'\n", acc_fetch_fullname(mod_handle)); cell_handle = NULL; while (cell_handle = acc_next_cell(mod_handle, cell_handle)) NoTimingChecks_OneCell(cell_handle); } } /* NoTimingChecks_OneLevel */ void NoTimingChecks_OneCell(cell_handle) handle cell_handle; { handle tchk_handle, tchkarg1_handle, tchkarg2_handle; int tchk_type; double tt; if (NoTC_config->en_verbose) io_printf("# Info ($NoTimingChecks) : Cell '%s' (%s)\n", acc_fetch_fullname(cell_handle), acc_fetch_defname(cell_handle)); tchk_handle = NULL; while (tchk_handle = acc_next_tchk(cell_handle, tchk_handle)) { tchk_type = acc_fetch_fulltype(tchk_handle); tchkarg1_handle = acc_handle_tchkarg1(tchk_handle); tchkarg2_handle = acc_handle_tchkarg2(tchk_handle); acc_fetch_delays(tchk_handle, &tt); switch(tchk_type) { case (accSetup) : if (NoTC_config->en_verbose && NoTC_config->en_setup) io_printf("# Info ($NoTimingChecks) : \tSetup %s to %s : Old = %3.2f, disabled\n", acc_fetch_name(tchkarg1_handle), acc_fetch_name(tchkarg2_handle), tt); if (NoTC_config->en_setup) acc_replace_delays(tchk_handle, 0.0); break; case (accHold ) : if (NoTC_config->en_verbose && NoTC_config->en_hold) io_printf("# Info ($NoTimingChecks) : \tHold %s to %s : Old = %3.2f, disabled\n", acc_fetch_name(tchkarg1_handle), acc_fetch_name(tchkarg2_handle), tt); if (NoTC_config->en_hold) acc_replace_delays(tchk_handle, 0.0); break; } /* switch */ } /* while */ } /* NoTimingChecks_OneCell */ void NoTimingChecks_abort() { io_printf("# Error : $NoTimingCheck invocation error \n"); io_printf("# Usage : $NoTimingCheck( |