| [14] | 1 | /**CFile*********************************************************************** |
|---|
| 2 | |
|---|
| 3 | FileName [synth.c] |
|---|
| 4 | |
|---|
| 5 | PackageName [synth] |
|---|
| 6 | |
|---|
| 7 | Synopsis [Commands for synthesize_network.] |
|---|
| 8 | |
|---|
| 9 | Description [External procedures included in this module: |
|---|
| 10 | <ul> |
|---|
| 11 | <li> Synth_Init() |
|---|
| 12 | <li> Synth_End() |
|---|
| 13 | </ul> |
|---|
| 14 | Static procedures included in this module: |
|---|
| 15 | <ul> |
|---|
| 16 | <li> CommandSynthesizeNetwork() |
|---|
| 17 | <li> TimeOutHandle() |
|---|
| 18 | </ul> ] |
|---|
| 19 | |
|---|
| 20 | Author [Balakrishna Kumthekar, In-Ho Moon] |
|---|
| 21 | |
|---|
| 22 | Copyright [This file was created at the University of Colorado at |
|---|
| 23 | Boulder. The University of Colorado at Boulder makes no warranty |
|---|
| 24 | about the suitability of this software for any purpose. It is |
|---|
| 25 | presented on an AS IS basis.] |
|---|
| 26 | |
|---|
| 27 | ******************************************************************************/ |
|---|
| 28 | |
|---|
| 29 | #include "synthInt.h" |
|---|
| 30 | |
|---|
| 31 | static char rcsid[] UNUSED = "$Id: synth.c,v 1.60 2005/05/16 06:22:00 fabio Exp $"; |
|---|
| 32 | |
|---|
| 33 | /*---------------------------------------------------------------------------*/ |
|---|
| 34 | /* Constant declarations */ |
|---|
| 35 | /*---------------------------------------------------------------------------*/ |
|---|
| 36 | |
|---|
| 37 | |
|---|
| 38 | /*---------------------------------------------------------------------------*/ |
|---|
| 39 | /* Stucture declarations */ |
|---|
| 40 | /*---------------------------------------------------------------------------*/ |
|---|
| 41 | |
|---|
| 42 | |
|---|
| 43 | /*---------------------------------------------------------------------------*/ |
|---|
| 44 | /* Type declarations */ |
|---|
| 45 | /*---------------------------------------------------------------------------*/ |
|---|
| 46 | |
|---|
| 47 | |
|---|
| 48 | /*---------------------------------------------------------------------------*/ |
|---|
| 49 | /* Variable declarations */ |
|---|
| 50 | /*---------------------------------------------------------------------------*/ |
|---|
| 51 | |
|---|
| 52 | extern int VerifyTreeMode; |
|---|
| 53 | |
|---|
| 54 | static jmp_buf timeOutEnv; |
|---|
| 55 | |
|---|
| 56 | /*---------------------------------------------------------------------------*/ |
|---|
| 57 | /* Macro declarations */ |
|---|
| 58 | /*---------------------------------------------------------------------------*/ |
|---|
| 59 | |
|---|
| 60 | |
|---|
| 61 | /**AutomaticStart*************************************************************/ |
|---|
| 62 | |
|---|
| 63 | /*---------------------------------------------------------------------------*/ |
|---|
| 64 | /* Static function prototypes */ |
|---|
| 65 | /*---------------------------------------------------------------------------*/ |
|---|
| 66 | |
|---|
| 67 | static int CommandSynthesizeNetwork(Hrc_Manager_t **hmgr, int argc, char **argv); |
|---|
| 68 | static void TimeOutHandle(void); |
|---|
| 69 | static int TestIsNetworkMultipleValued(Ntk_Network_t *network); |
|---|
| 70 | |
|---|
| 71 | /**AutomaticEnd***************************************************************/ |
|---|
| 72 | |
|---|
| 73 | |
|---|
| 74 | /*---------------------------------------------------------------------------*/ |
|---|
| 75 | /* Definition of exported functions */ |
|---|
| 76 | /*---------------------------------------------------------------------------*/ |
|---|
| 77 | |
|---|
| 78 | /**Function******************************************************************** |
|---|
| 79 | |
|---|
| 80 | Synopsis [This function initializes the synth package.] |
|---|
| 81 | |
|---|
| 82 | Description [This function initializes the synth package.] |
|---|
| 83 | |
|---|
| 84 | SideEffects [Installs the synthesize_network command.] |
|---|
| 85 | |
|---|
| 86 | SeeAlso [Synth_End()] |
|---|
| 87 | |
|---|
| 88 | ******************************************************************************/ |
|---|
| 89 | void |
|---|
| 90 | Synth_Init(void) |
|---|
| 91 | { |
|---|
| 92 | Cmd_CommandAdd("synthesize_network", CommandSynthesizeNetwork, 0); |
|---|
| 93 | } |
|---|
| 94 | |
|---|
| 95 | /**Function******************************************************************** |
|---|
| 96 | |
|---|
| 97 | Synopsis [This function ends the synth package.] |
|---|
| 98 | |
|---|
| 99 | Description [This function ends the synth package.] |
|---|
| 100 | |
|---|
| 101 | SideEffects [none] |
|---|
| 102 | |
|---|
| 103 | SeeAlso [Synth_Init()] |
|---|
| 104 | |
|---|
| 105 | ******************************************************************************/ |
|---|
| 106 | void |
|---|
| 107 | Synth_End(void) |
|---|
| 108 | { |
|---|
| 109 | } |
|---|
| 110 | |
|---|
| 111 | /*---------------------------------------------------------------------------*/ |
|---|
| 112 | /* Definition of internal functions */ |
|---|
| 113 | /*---------------------------------------------------------------------------*/ |
|---|
| 114 | |
|---|
| 115 | /*---------------------------------------------------------------------------*/ |
|---|
| 116 | /* Definition of static functions */ |
|---|
| 117 | /*---------------------------------------------------------------------------*/ |
|---|
| 118 | |
|---|
| 119 | /**Function******************************************************************** |
|---|
| 120 | |
|---|
| 121 | Synopsis [Implements the synthesize_network command.] |
|---|
| 122 | |
|---|
| 123 | Description [This function synthesizes a network to have as few |
|---|
| 124 | literals as possible and outputs a blif file and an equation file. |
|---|
| 125 | Those files are the results of the synthesis. By default, the names |
|---|
| 126 | of the files are model_name.ml.blif and model_name.eq unless users |
|---|
| 127 | specify the model_name explicitly using -o option. But, when the |
|---|
| 128 | output blif file is read in sis, it may have slightly different |
|---|
| 129 | number of literals. This problem will be fixed in the later version. |
|---|
| 130 | Currently, this command can be used only with CUDD package. |
|---|
| 131 | |
|---|
| 132 | Designs described in BLIF or BLIF-MV format can be synthesized by |
|---|
| 133 | this command. However, multiple valued variables are not |
|---|
| 134 | supported. Hence, signals in the designs described in BLIF-MV need |
|---|
| 135 | to be restricted to binary values.] |
|---|
| 136 | |
|---|
| 137 | SideEffects [None] |
|---|
| 138 | |
|---|
| 139 | SeeAlso [] |
|---|
| 140 | |
|---|
| 141 | CommandName [synthesize_network] |
|---|
| 142 | |
|---|
| 143 | CommandSynopsis [Synthesizes a network using ZDD factorization method.] |
|---|
| 144 | |
|---|
| 145 | CommandArguments [\[-d <divisor>\] \[-e\] \[-f <factoringMethod>\] |
|---|
| 146 | \[-h\] \[-i <prefix>\] \[-o <fileHead>\] |
|---|
| 147 | \[-r <reachMethod>\] |
|---|
| 148 | \[-t <timeOut>\] \[-v\] \[-A\] \[-O <outputOrdering>\] |
|---|
| 149 | \[-R <reorder>\] \[-T\]] |
|---|
| 150 | |
|---|
| 151 | CommandDescription [This command synthesizes a network to have as few |
|---|
| 152 | literals as possible and outputs a blif file and an equation file. Those |
|---|
| 153 | files are the results of the synthesis. By default, the names of the files |
|---|
| 154 | are model_name.ml.blif and model_name.eq unless users specify the model_name |
|---|
| 155 | explicitly using -o option. But, when the output blif file is read in sis, it |
|---|
| 156 | may have slightly different number of literals. This problem will be fixed in |
|---|
| 157 | the later version. Currently, this command can be used only with CUDD |
|---|
| 158 | package. |
|---|
| 159 | |
|---|
| 160 | Designs described in BLIF or BLIF-MV format can be synthesized by this |
|---|
| 161 | command. However, multiple valued variables are not supported. Hence, signals |
|---|
| 162 | in the designs described in BLIF-MV need to be restricted to binary values. |
|---|
| 163 | |
|---|
| 164 | There are 4 divisor functions to find a good divisor of a function. Neither |
|---|
| 165 | of them consistently generates the best result. And, there are 2 factoring |
|---|
| 166 | methods: simple factoring and generic factoring. Also, neither of two always |
|---|
| 167 | does better than the other. <p> |
|---|
| 168 | |
|---|
| 169 | Command options:<p> |
|---|
| 170 | |
|---|
| 171 | <dl> |
|---|
| 172 | |
|---|
| 173 | <dt> -d <divisor> |
|---|
| 174 | <dd> Choose a divisor.<p> |
|---|
| 175 | <dd> |
|---|
| 176 | 0 : Fast divisor. We find a divisor on a ZDD graph. As soon as any |
|---|
| 177 | shared node(variable) is found, the variable is returned as a divisor. |
|---|
| 178 | <p> |
|---|
| 179 | |
|---|
| 180 | 1 : (default) Least occuring literal divisor. If a variable occurs the least |
|---|
| 181 | frequently(but, should be more than one) in cubes, it returns the |
|---|
| 182 | variable as a divisor. <p> |
|---|
| 183 | |
|---|
| 184 | 2 : Most occuring literal divisor. If a variable occurs the most frequently |
|---|
| 185 | in cubes, it returns the variable as a divisor. <p> |
|---|
| 186 | |
|---|
| 187 | 3 : Level-0 divisor. It finds a divisor that is a level-0 cokernel. |
|---|
| 188 | <p> |
|---|
| 189 | |
|---|
| 190 | <dt> -e |
|---|
| 191 | <dd> Dump the synthesized circuit in equation format also. Default is |
|---|
| 192 | not to. <p> |
|---|
| 193 | |
|---|
| 194 | <dt> -f <factoringMethod> |
|---|
| 195 | <dd> Choose a factoring method.<p> |
|---|
| 196 | <dd> |
|---|
| 197 | 0 : (default) Simple factoring. This method uses a simple recursion. First, |
|---|
| 198 | it finds a proper divisor of a function, then divide the function by the |
|---|
| 199 | divisor, then it gets a quotient and a remainder. And, it does the |
|---|
| 200 | same thing recursively for each divisor, quotient, and |
|---|
| 201 | remainder. <p> |
|---|
| 202 | |
|---|
| 203 | 1 : Generic factoring. This method is quite similar to the simple |
|---|
| 204 | factoring, but it does more in terms of considering cube-free and |
|---|
| 205 | common divisor and literal factoring. But, it does not always generate |
|---|
| 206 | better results than the simple factoring does. <p> |
|---|
| 207 | |
|---|
| 208 | <dt> -h |
|---|
| 209 | <dd> Print the command usage. <p> |
|---|
| 210 | |
|---|
| 211 | <dt> -i <prefix> |
|---|
| 212 | <dd> Specify the prefix of internal node names. By default, the prefix |
|---|
| 213 | is "_n". <p> |
|---|
| 214 | |
|---|
| 215 | <dt> -o <fileHead> |
|---|
| 216 | <dd> Specify the output file name (without extension). By default, the model |
|---|
| 217 | name in a blif file is used. <p> |
|---|
| 218 | |
|---|
| 219 | <dt> -r <reachMethod> |
|---|
| 220 | <dd> If the network is sequential, then use unreachable states as dont cares |
|---|
| 221 | in the optimization. By default no reachability analysis is performed. See |
|---|
| 222 | -A option of command compute_reach for more details. The various options |
|---|
| 223 | are:<p> |
|---|
| 224 | <dd> |
|---|
| 225 | 0 : Do not use dont cares (default). <p> |
|---|
| 226 | |
|---|
| 227 | 1 : Use normal breadth first search method for reachability analysis. <p> |
|---|
| 228 | |
|---|
| 229 | 2 : Use high density traversal method for reachablity analysis. <p> |
|---|
| 230 | |
|---|
| 231 | 3 : Use approximate unreachable states(a subset of actual unreachable states) |
|---|
| 232 | as dont cares. <p> |
|---|
| 233 | |
|---|
| 234 | <dt> -t <timeOut> |
|---|
| 235 | <dd> Time in seconds allowed to perform synthesize_network. The default is |
|---|
| 236 | no limit.<p> |
|---|
| 237 | |
|---|
| 238 | <dt> -v |
|---|
| 239 | <dd> Print debug information. <p> |
|---|
| 240 | |
|---|
| 241 | <dt> -A |
|---|
| 242 | <dd> Allow realignment to ZDD/BDD after BDD/ZDD reordering, respectively. |
|---|
| 243 | This option is effective when only one reordering in BDD or ZDD is enabled. |
|---|
| 244 | |
|---|
| 245 | <dt> -O <outputOrdering> |
|---|
| 246 | <dd> Choose an output ordering method. <p> |
|---|
| 247 | <dd> |
|---|
| 248 | 0 : No ordering. <p> |
|---|
| 249 | |
|---|
| 250 | 1 : (default) Use support variable set of output functions. <p> |
|---|
| 251 | |
|---|
| 252 | 2 : Use BDD size of output functions. <p> |
|---|
| 253 | |
|---|
| 254 | <dt> -R <reorder> |
|---|
| 255 | <dd> Allow reordering in BDD and/or ZDD. <p> |
|---|
| 256 | <dd> |
|---|
| 257 | 0 or n : (default) No reordering neither in BDD nor in ZDD. <p> |
|---|
| 258 | |
|---|
| 259 | 1 or b : Allows reordering only in BDD, not in ZDD. <p> |
|---|
| 260 | |
|---|
| 261 | 2 or z : Allows reordering only in ZDD, not in BDD. <p> |
|---|
| 262 | |
|---|
| 263 | 3 or a : Allows reordering both in BDD and in ZDD. <p> |
|---|
| 264 | |
|---|
| 265 | <dt> -T |
|---|
| 266 | <dd> Try to share more nodes during symbolic factorization. Existing |
|---|
| 267 | divisors are checked for potential reuse before extracting divisors from the |
|---|
| 268 | current boolean function.<p> |
|---|
| 269 | |
|---|
| 270 | <\dl> |
|---|
| 271 | ] |
|---|
| 272 | |
|---|
| 273 | ******************************************************************************/ |
|---|
| 274 | static int |
|---|
| 275 | CommandSynthesizeNetwork(Hrc_Manager_t **hmgr, |
|---|
| 276 | int argc, |
|---|
| 277 | char **argv) |
|---|
| 278 | { |
|---|
| 279 | Ntk_Network_t *network1; |
|---|
| 280 | Ntk_Node_t *node; |
|---|
| 281 | bdd_manager *ddManager; |
|---|
| 282 | int timeOutPeriod; |
|---|
| 283 | int createdMgr; |
|---|
| 284 | int factoring, divisor; |
|---|
| 285 | int unreachDC, verbosity; |
|---|
| 286 | int result, varOrdered; |
|---|
| 287 | long initialTime, finalTime; |
|---|
| 288 | char *filehead,*filename; |
|---|
| 289 | char *prefix; |
|---|
| 290 | FILE *fp; |
|---|
| 291 | int c; |
|---|
| 292 | lsList dummy = (lsList) 0; |
|---|
| 293 | lsGen gen; |
|---|
| 294 | Synth_InfoData_t *synthInfo; |
|---|
| 295 | char *reorder = NIL(char); |
|---|
| 296 | int reordering; |
|---|
| 297 | int trySharing; |
|---|
| 298 | int realign; |
|---|
| 299 | int outputOrdering; |
|---|
| 300 | boolean eqn; |
|---|
| 301 | |
|---|
| 302 | if (bdd_get_package_name() != CUDD) { |
|---|
| 303 | (void) fprintf(vis_stderr, |
|---|
| 304 | "** synth error: synthesize_network can be used only with the CUDD package\n"); |
|---|
| 305 | (void) fprintf(vis_stderr, |
|---|
| 306 | "** synth error: Please link with CUDD package\n"); |
|---|
| 307 | return 1; |
|---|
| 308 | } |
|---|
| 309 | |
|---|
| 310 | /* To keep the Alpha compilers happy. */ |
|---|
| 311 | network1 = NIL(Ntk_Network_t); |
|---|
| 312 | node = NIL(Ntk_Node_t); |
|---|
| 313 | ddManager = NIL(bdd_manager); |
|---|
| 314 | synthInfo = NIL(Synth_InfoData_t); |
|---|
| 315 | |
|---|
| 316 | /* These are the default values. */ |
|---|
| 317 | timeOutPeriod = 0; |
|---|
| 318 | createdMgr = 0; |
|---|
| 319 | factoring = 0; /* Simple factoring algorithm. */ |
|---|
| 320 | divisor = 1; /* Quick divisor */ |
|---|
| 321 | unreachDC = 0; /* Do not use unreachable states as DCs */ |
|---|
| 322 | filehead = NIL(char); |
|---|
| 323 | filename = NIL(char); |
|---|
| 324 | prefix = NIL(char); |
|---|
| 325 | fp = NIL(FILE); |
|---|
| 326 | reordering = 0; |
|---|
| 327 | trySharing = 0; |
|---|
| 328 | realign = 0; |
|---|
| 329 | verbosity = 0; |
|---|
| 330 | varOrdered = 0; |
|---|
| 331 | outputOrdering = 0; |
|---|
| 332 | eqn = 0; |
|---|
| 333 | util_getopt_reset(); |
|---|
| 334 | |
|---|
| 335 | while((c = util_getopt(argc, argv, "d:ef:hi:o:r:t:vAO:R:TV:")) != EOF) { |
|---|
| 336 | switch(c) { |
|---|
| 337 | case 'd': |
|---|
| 338 | divisor = atoi(util_optarg); |
|---|
| 339 | if (divisor < 0 || divisor > 3) |
|---|
| 340 | goto usage; |
|---|
| 341 | break; |
|---|
| 342 | case 'e': |
|---|
| 343 | eqn = 1; |
|---|
| 344 | break; |
|---|
| 345 | case 'f': |
|---|
| 346 | factoring = atoi(util_optarg); |
|---|
| 347 | if (factoring < 0 || factoring > 1) |
|---|
| 348 | goto usage; |
|---|
| 349 | break; |
|---|
| 350 | case 'h': |
|---|
| 351 | goto usage; |
|---|
| 352 | case 'i': |
|---|
| 353 | prefix = util_strsav(util_optarg); |
|---|
| 354 | break; |
|---|
| 355 | case 'o': |
|---|
| 356 | filehead = util_strsav(util_optarg); |
|---|
| 357 | break; |
|---|
| 358 | case 'r': |
|---|
| 359 | unreachDC = atoi(util_optarg); |
|---|
| 360 | break; |
|---|
| 361 | case 't': |
|---|
| 362 | timeOutPeriod = atoi(util_optarg); |
|---|
| 363 | break; |
|---|
| 364 | case 'v': |
|---|
| 365 | verbosity = 1; |
|---|
| 366 | break; |
|---|
| 367 | case 'A': |
|---|
| 368 | realign = 1; |
|---|
| 369 | break; |
|---|
| 370 | case 'O': |
|---|
| 371 | outputOrdering = atoi(util_optarg); |
|---|
| 372 | if (outputOrdering < 0 || outputOrdering > 2) |
|---|
| 373 | goto usage; |
|---|
| 374 | SynthSetOutputOrdering(outputOrdering); |
|---|
| 375 | break; |
|---|
| 376 | case 'R': |
|---|
| 377 | reorder = util_strsav(util_optarg); |
|---|
| 378 | if (reorder[0] == '0' || reorder[0] == 'n') |
|---|
| 379 | reordering = 0; |
|---|
| 380 | else if (reorder[0] == '1' || reorder[0] == 'b') |
|---|
| 381 | reordering = 1; |
|---|
| 382 | else if (reorder[0] == '2' || reorder[0] == 'z') |
|---|
| 383 | reordering = 2; |
|---|
| 384 | else if (reorder[0] == '3' || reorder[0] == 'a') |
|---|
| 385 | reordering = 3; |
|---|
| 386 | else |
|---|
| 387 | goto usage; |
|---|
| 388 | break; |
|---|
| 389 | case 'T': |
|---|
| 390 | trySharing = 1; |
|---|
| 391 | break; |
|---|
| 392 | case 'V': |
|---|
| 393 | VerifyTreeMode = atoi(util_optarg); |
|---|
| 394 | break; |
|---|
| 395 | default: |
|---|
| 396 | if (util_optarg) |
|---|
| 397 | (void) fprintf(vis_stderr, |
|---|
| 398 | "** synth error: Unknown option %s\n",util_optarg); |
|---|
| 399 | else |
|---|
| 400 | (void) fprintf(vis_stderr,"** synth error: Unknown option ?\n"); |
|---|
| 401 | goto usage; |
|---|
| 402 | } |
|---|
| 403 | } |
|---|
| 404 | |
|---|
| 405 | if(Hrc_ManagerReadCurrentNode(*hmgr) == NIL(Hrc_Node_t)) { |
|---|
| 406 | (void)fprintf(vis_stderr,"** synth error: The hierarchy manager is empty."); |
|---|
| 407 | (void)fprintf(vis_stderr,"** synth error: Read in design.\n"); |
|---|
| 408 | goto endgame; |
|---|
| 409 | } |
|---|
| 410 | |
|---|
| 411 | network1 = (Ntk_Network_t *) |
|---|
| 412 | Hrc_NodeReadApplInfo(Hrc_ManagerReadCurrentNode(*hmgr), |
|---|
| 413 | NTK_HRC_NODE_APPL_KEY); |
|---|
| 414 | |
|---|
| 415 | if(network1 == NIL(Ntk_Network_t)) { |
|---|
| 416 | (void) fprintf(vis_stderr, "** synth error: There is no network. "); |
|---|
| 417 | (void) fprintf(vis_stderr,"** synth error:Use flatten_hierarchy.\n"); |
|---|
| 418 | goto endgame; |
|---|
| 419 | } |
|---|
| 420 | |
|---|
| 421 | /* Check if the current network has signals with multiple values. */ |
|---|
| 422 | if (TestIsNetworkMultipleValued(network1)) { |
|---|
| 423 | (void) fprintf(vis_stderr, |
|---|
| 424 | "** synth error: Circuit has multiple valued variables.\n"); |
|---|
| 425 | (void) fprintf(vis_stderr, |
|---|
| 426 | "** synth error: This command works with boolean signals only.\n"); |
|---|
| 427 | goto endgame; |
|---|
| 428 | } |
|---|
| 429 | |
|---|
| 430 | if (!filehead) |
|---|
| 431 | filehead = util_strsav(Ntk_NetworkReadName(network1)); |
|---|
| 432 | |
|---|
| 433 | /* Check if the output equation file already exists */ |
|---|
| 434 | if (eqn) { |
|---|
| 435 | filename = util_strcat3(filehead,".eq",""); |
|---|
| 436 | fp = Cmd_FileOpen(filename,"r",NIL(char *),1); |
|---|
| 437 | if (fp) { |
|---|
| 438 | (void) fprintf(vis_stderr, |
|---|
| 439 | "** synth error: Output equation file %s already exists.\n", |
|---|
| 440 | filename); |
|---|
| 441 | (void) fprintf(vis_stderr, |
|---|
| 442 | "** synth error: Please specify another name.\n"); |
|---|
| 443 | fclose(fp); |
|---|
| 444 | FREE(filename); |
|---|
| 445 | goto endgame; |
|---|
| 446 | } |
|---|
| 447 | FREE(filename); |
|---|
| 448 | } |
|---|
| 449 | /* Check if the output blif file already exists */ |
|---|
| 450 | filename = util_strcat3(filehead,".ml.blif",""); |
|---|
| 451 | fp = Cmd_FileOpen(filename,"r",NIL(char *),1); |
|---|
| 452 | if (fp) { |
|---|
| 453 | (void) fprintf(vis_stderr, |
|---|
| 454 | "** synth error: Output blif file %s already exists.\n", |
|---|
| 455 | filename); |
|---|
| 456 | (void) fprintf(vis_stderr,"** synth error: Please specify another name.\n"); |
|---|
| 457 | fclose(fp); |
|---|
| 458 | FREE(filename); |
|---|
| 459 | goto endgame; |
|---|
| 460 | } |
|---|
| 461 | FREE(filename); |
|---|
| 462 | |
|---|
| 463 | if(Ntk_NetworkReadNumPrimaryInputs(network1) != |
|---|
| 464 | Ntk_NetworkReadNumInputs(network1)) { |
|---|
| 465 | (void) fprintf(vis_stderr, |
|---|
| 466 | "** synth error: Pseudo inputs present in the network.\n"); |
|---|
| 467 | (void) fprintf(vis_stderr, |
|---|
| 468 | "** synth error: Cannot synthesize the network\n"); |
|---|
| 469 | goto endgame; |
|---|
| 470 | } |
|---|
| 471 | |
|---|
| 472 | ddManager = (bdd_manager *) Ntk_NetworkReadMddManager(network1); |
|---|
| 473 | if (ddManager == NIL(bdd_manager)) { |
|---|
| 474 | ddManager = (bdd_manager *)Ntk_NetworkInitializeMddManager(network1); |
|---|
| 475 | if (ddManager == NIL(bdd_manager)) { |
|---|
| 476 | (void) fprintf(vis_stderr, |
|---|
| 477 | "** synth error: Could not create Mdd Manager\n"); |
|---|
| 478 | goto endgame; |
|---|
| 479 | } |
|---|
| 480 | createdMgr = 1; |
|---|
| 481 | } |
|---|
| 482 | |
|---|
| 483 | /* Check if the network has the variables ordered. |
|---|
| 484 | * For combinational synthesis we are only interested in the primary |
|---|
| 485 | * input variables. But for sequential synthesis we need primary inputs, |
|---|
| 486 | * present state variables and next state variables (to use in |
|---|
| 487 | * reachability analysis and use the unreachable states as dont cares). |
|---|
| 488 | */ |
|---|
| 489 | |
|---|
| 490 | if (Ord_NetworkTestAreVariablesOrdered(network1, Ord_InputAndLatch_c) == |
|---|
| 491 | FALSE) { |
|---|
| 492 | Ord_NetworkOrderVariables(network1,Ord_RootsByDefault_c, |
|---|
| 493 | Ord_NodesByDefault_c, FALSE, |
|---|
| 494 | Ord_InputAndLatch_c,Ord_Unassigned_c, |
|---|
| 495 | dummy,0); |
|---|
| 496 | varOrdered = 1; |
|---|
| 497 | } |
|---|
| 498 | |
|---|
| 499 | /* Start the timer. */ |
|---|
| 500 | if (timeOutPeriod > 0){ |
|---|
| 501 | (void) signal(SIGALRM, (void(*)(int))TimeOutHandle); |
|---|
| 502 | (void) alarm(timeOutPeriod); |
|---|
| 503 | if (setjmp(timeOutEnv) > 0) { |
|---|
| 504 | (void) fprintf(vis_stderr, "** synth warning: Timeout occurred after "); |
|---|
| 505 | (void) fprintf(vis_stderr, "%d seconds.\n", timeOutPeriod); |
|---|
| 506 | alarm(0); |
|---|
| 507 | goto endgame; |
|---|
| 508 | } |
|---|
| 509 | } |
|---|
| 510 | |
|---|
| 511 | synthInfo = Synth_InitializeInfo(factoring,divisor,unreachDC, |
|---|
| 512 | reordering,trySharing,realign, |
|---|
| 513 | filehead,prefix,eqn); |
|---|
| 514 | if (!synthInfo) |
|---|
| 515 | goto endgame; |
|---|
| 516 | |
|---|
| 517 | /* Synthesize.*/ |
|---|
| 518 | initialTime = util_cpu_time(); |
|---|
| 519 | |
|---|
| 520 | result = Synth_SynthesizeNetwork(network1,NIL(graph_t), |
|---|
| 521 | NIL(st_table),synthInfo, |
|---|
| 522 | verbosity); |
|---|
| 523 | |
|---|
| 524 | finalTime = util_cpu_time(); |
|---|
| 525 | |
|---|
| 526 | if (result) { |
|---|
| 527 | (void) fprintf(vis_stdout, "%-20s%10ld\n", "analysis time =", |
|---|
| 528 | (finalTime-initialTime)/1000); |
|---|
| 529 | } else { |
|---|
| 530 | (void) fprintf(vis_stdout, "** synth error: Could not synthesize.\n"); |
|---|
| 531 | } |
|---|
| 532 | |
|---|
| 533 | /* Set the mdd id's for all the nodes to unassigned if it |
|---|
| 534 | * was specifically set in this routine. |
|---|
| 535 | */ |
|---|
| 536 | if (varOrdered) { |
|---|
| 537 | Ntk_NetworkForEachPrimaryInput(network1,gen,node) { |
|---|
| 538 | Ntk_NodeSetMddId(node,NTK_UNASSIGNED_MDD_ID); |
|---|
| 539 | } |
|---|
| 540 | Ntk_NetworkForEachLatch(network1,gen,node) { |
|---|
| 541 | Ntk_Node_t *shadow; |
|---|
| 542 | shadow = Ntk_NodeReadShadow(node); |
|---|
| 543 | Ntk_NodeSetMddId(node,NTK_UNASSIGNED_MDD_ID); |
|---|
| 544 | Ntk_NodeSetMddId(shadow,NTK_UNASSIGNED_MDD_ID); |
|---|
| 545 | } |
|---|
| 546 | } |
|---|
| 547 | |
|---|
| 548 | if (createdMgr) { |
|---|
| 549 | mdd_quit((mdd_manager *)ddManager); |
|---|
| 550 | Ntk_NetworkSetMddManager(network1,NIL(mdd_manager)); |
|---|
| 551 | } |
|---|
| 552 | |
|---|
| 553 | if (reorder) |
|---|
| 554 | FREE(reorder); |
|---|
| 555 | if (filehead) |
|---|
| 556 | FREE(filehead); |
|---|
| 557 | if (prefix) |
|---|
| 558 | FREE(prefix); |
|---|
| 559 | |
|---|
| 560 | if (synthInfo) |
|---|
| 561 | Synth_FreeInfo(synthInfo); |
|---|
| 562 | |
|---|
| 563 | alarm(0); |
|---|
| 564 | return 0; /* normal exit */ |
|---|
| 565 | |
|---|
| 566 | endgame: |
|---|
| 567 | if (varOrdered) { |
|---|
| 568 | Ntk_NetworkForEachNode(network1,gen,node) { |
|---|
| 569 | Ntk_NodeSetMddId(node,NTK_UNASSIGNED_MDD_ID); |
|---|
| 570 | } |
|---|
| 571 | } |
|---|
| 572 | |
|---|
| 573 | if (createdMgr) { |
|---|
| 574 | mdd_quit((mdd_manager *)ddManager); |
|---|
| 575 | Ntk_NetworkSetMddManager(network1,NIL(mdd_manager)); |
|---|
| 576 | } |
|---|
| 577 | |
|---|
| 578 | if (reorder) |
|---|
| 579 | FREE(reorder); |
|---|
| 580 | if(filehead) |
|---|
| 581 | FREE(filehead); |
|---|
| 582 | if(prefix) |
|---|
| 583 | FREE(prefix); |
|---|
| 584 | |
|---|
| 585 | if (synthInfo) |
|---|
| 586 | Synth_FreeInfo(synthInfo); |
|---|
| 587 | |
|---|
| 588 | return 1; |
|---|
| 589 | |
|---|
| 590 | usage: |
|---|
| 591 | (void) fprintf(vis_stderr, "usage: synthesize_network [-d divisor] [-e] [-f factoringMethod] [-h] [-i prefix] [-o fileHead] [-r reachMethod] [-t timeOut] [-v] [-A] [-O outputOrdering] [-R reorder] [-T]\n"); |
|---|
| 592 | (void) fprintf(vis_stderr, " -d n\t\tChoose a divisor function (0-4)\n"); |
|---|
| 593 | (void) fprintf(vis_stderr, " \t\t\t0: Fast divisor\n"); |
|---|
| 594 | (void) fprintf(vis_stderr, |
|---|
| 595 | " \t\t\t1: Least occuring literal divisor (default)\n"); |
|---|
| 596 | (void) fprintf(vis_stderr, " \t\t\t2: Most occuring literal divisor\n"); |
|---|
| 597 | (void) fprintf(vis_stderr, " \t\t\t3: Level-0 kernel divisor\n"); |
|---|
| 598 | (void) fprintf(vis_stderr, " -e n\t\tOutput equation format file\n"); |
|---|
| 599 | (void) fprintf(vis_stderr, " -f n\t\tChoose a factoring method(0-1)\n"); |
|---|
| 600 | (void) fprintf(vis_stderr, " \t\t\t0: Simple factoring (default)\n"); |
|---|
| 601 | (void) fprintf(vis_stderr, " \t\t\t1: Generic factoring\n"); |
|---|
| 602 | (void) fprintf(vis_stderr, " -h\t\tPrint the command usage\n"); |
|---|
| 603 | (void) fprintf(vis_stderr, " -i prefix\tPrefix of internal node names.\n"); |
|---|
| 604 | (void) fprintf(vis_stderr, |
|---|
| 605 | " -o name\tName of output file (without extension)\n"); |
|---|
| 606 | (void) fprintf(vis_stderr, |
|---|
| 607 | " -r n\t\tUse unreachable states for sequential circuits\n"); |
|---|
| 608 | (void) fprintf(vis_stderr, " \t\tas dont cares(0-3)\n"); |
|---|
| 609 | (void) fprintf(vis_stderr, |
|---|
| 610 | " \t\t\t0: Do not use unreachable states (default).\n"); |
|---|
| 611 | (void) fprintf(vis_stderr, |
|---|
| 612 | " \t\t\t1: Use normal BFS method for reachability analysis.\n"); |
|---|
| 613 | (void) fprintf(vis_stderr, |
|---|
| 614 | " \t\t\t2: Use high density method for reachability analysis.\n"); |
|---|
| 615 | (void) fprintf(vis_stderr, |
|---|
| 616 | " \t\t\t3: Use approximate unreachable states as dont cares.\n"); |
|---|
| 617 | (void) fprintf(vis_stderr, " -t time\tTime out period (in seconds)\n"); |
|---|
| 618 | (void) fprintf(vis_stderr, " -v \t\tVerbosity On.\n"); |
|---|
| 619 | (void) fprintf(vis_stderr, |
|---|
| 620 | " -A \t\tAllow realignment after BDD/ZDD reordering.\n"); |
|---|
| 621 | (void) fprintf(vis_stderr, |
|---|
| 622 | " -O n\t\tChoose an output ordering method(0-2)\n"); |
|---|
| 623 | (void) fprintf(vis_stderr, " \t\t\t0: no ordering\n"); |
|---|
| 624 | (void) fprintf(vis_stderr, " \t\t\t1: support variable set (default)\n"); |
|---|
| 625 | (void) fprintf(vis_stderr, " \t\t\t2: BDD size\n"); |
|---|
| 626 | (void) fprintf(vis_stderr, " -R n\t\tSet reordering (0-3)\n"); |
|---|
| 627 | (void) fprintf(vis_stderr, " \t\t\t0 or n: no reordering (default)\n"); |
|---|
| 628 | (void) fprintf(vis_stderr, " \t\t\t1 or b: reordering in only BDD\n"); |
|---|
| 629 | (void) fprintf(vis_stderr, " \t\t\t2 or z: reordering on only ZDD\n"); |
|---|
| 630 | (void) fprintf(vis_stderr, " \t\t\t3 or a: reordering on both\n"); |
|---|
| 631 | (void) fprintf(vis_stderr, " -T \t\tTry to share mode nodes.\n"); |
|---|
| 632 | return 1; /* error exit */ |
|---|
| 633 | } |
|---|
| 634 | |
|---|
| 635 | /**Function******************************************************************** |
|---|
| 636 | |
|---|
| 637 | Synopsis [Handler for timeout.] |
|---|
| 638 | |
|---|
| 639 | Description [This function is called when a time out occurs.] |
|---|
| 640 | |
|---|
| 641 | SideEffects [] |
|---|
| 642 | |
|---|
| 643 | SeeAlso [] |
|---|
| 644 | |
|---|
| 645 | ******************************************************************************/ |
|---|
| 646 | static void |
|---|
| 647 | TimeOutHandle(void) |
|---|
| 648 | { |
|---|
| 649 | longjmp(timeOutEnv, 1); |
|---|
| 650 | } |
|---|
| 651 | |
|---|
| 652 | |
|---|
| 653 | /**Function******************************************************************** |
|---|
| 654 | |
|---|
| 655 | Synopsis [Checks whether the network has multiple valued signals.] |
|---|
| 656 | |
|---|
| 657 | Description [Checks whether the network has multiple valued |
|---|
| 658 | signals. Returns 1 if true, else 0.] |
|---|
| 659 | |
|---|
| 660 | SideEffects [None] |
|---|
| 661 | |
|---|
| 662 | SeeAlso [] |
|---|
| 663 | |
|---|
| 664 | ******************************************************************************/ |
|---|
| 665 | static int |
|---|
| 666 | TestIsNetworkMultipleValued(Ntk_Network_t *network) |
|---|
| 667 | { |
|---|
| 668 | Ntk_Node_t *node; |
|---|
| 669 | lsGen gen; |
|---|
| 670 | Var_Variable_t *var; |
|---|
| 671 | int numValues; |
|---|
| 672 | |
|---|
| 673 | Ntk_NetworkForEachNode(network,gen,node) { |
|---|
| 674 | var = Ntk_NodeReadVariable(node); |
|---|
| 675 | numValues = Var_VariableReadNumValues(var); |
|---|
| 676 | if (numValues > 2) { |
|---|
| 677 | lsFinish(gen); |
|---|
| 678 | return 1; |
|---|
| 679 | } |
|---|
| 680 | } |
|---|
| 681 | return 0; |
|---|
| 682 | } |
|---|