[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 | } |
---|