/*------------------------------------------------------------\
|                                                             |
| Tool    :                   LYNX                            |
|                                                             |
| File    :                  lynx.c                           |
|                                                             |
| Author  :               Jacomme Ludovic                     |
|                                                             |
| Date    :                  01.08.93                         |
|                                                             |
\------------------------------------------------------------*/
/*------------------------------------------------------------\
|                                                             |
|                         Include Files                       |
|                                                             |
\------------------------------------------------------------*/

# include <stdio.h>
# include <string.h>
# include <stdlib.h>
# include <signal.h>

# include MUT_H
# include MLO_H
# include MPH_H
# include RDS_H
# include RUT_H
# include RPR_H
# include RFM_H
# include RWI_H

# include "share.h"
# include "parse.h"
# include "mbkrds.h"
# include "cut.h"
# include "extract.h"
# include "netlist.h"
# include "lyerror.h"
# include "lynx.h" 

/*------------------------------------------------------------\
|                                                             |
|                           Constants                         |
|                                                             |
\------------------------------------------------------------*/
/*------------------------------------------------------------\
|                                                             |
|                            Types                            |
|                                                             |
\------------------------------------------------------------*/
/*------------------------------------------------------------\
|                                                             |
|                          Variables                          |
|                                                             |
\------------------------------------------------------------*/

  static rdsfig_list *LynxFigureRds;
  static phfig_list  *LynxFigureMbk;
  static lofig_list  *LynxLogicalFigure;
  static phfig_list  *LynxFigureTrace;
  static rdswindow   *LynxWindow;
  static rdsrec_list *LynxHeadEqui;

/*------------------------------------------------------------\
|                                                             |
|                          Functions                          |
|                                                             |
\------------------------------------------------------------*/
/*------------------------------------------------------------\
|                                                             |
|                           Presents                          |
|                                                             |
\------------------------------------------------------------*/

  void Presents()

  {
    fprintf( stdout, "\n" );
    fprintf( stdout, "\n               @@@@@@                                    " );
    fprintf( stdout, "\n                 @@                                      " );
    fprintf( stdout, "\n                 @@                                      " );
    fprintf( stdout, "\n                 @@        @@@@@ @@@ @@@ @@@    @@@@  @@@" );
    fprintf( stdout, "\n                 @@         @@    @   @@@   @    @@    @ " );
    fprintf( stdout, "\n                 @@          @@   @   @@    @@    @@  @  " );
    fprintf( stdout, "\n                 @@          @@  @    @@    @@     @@@   " );
    fprintf( stdout, "\n                 @@           @@ @    @@    @@     @@@   " );
    fprintf( stdout, "\n                 @@      @    @@@     @@    @@    @  @@  " );
    fprintf( stdout, "\n                 @@     @      @@     @@    @@   @    @@ " );
    fprintf( stdout, "\n               @@@@@@@@@@  @@  @     @@@@  @@@@ @@@  @@@@" );
    fprintf( stdout, "\n                           @@  @                         " );
    fprintf( stdout, "\n                            @@@                          " );
    fprintf( stdout, "\n" );
    fprintf( stdout, "\n                            Netlist Extractor" );
    fprintf( stdout, "\n" );
    fprintf( stdout, "\n                 Alliance CAD System Graal,    lynx 1.07" );
    fprintf( stdout, "\n                 Copyright (c) 1993, MASI, CAO-VLSI Team" );
    fprintf( stdout, "\n                 E-mail support:    cao-vlsi@masi.ibp.fr" );
    fprintf( stdout, "\n\n" );
  }

/*------------------------------------------------------------\
|                                                             |
|                             Main                            |
|                                                             |
\------------------------------------------------------------*/

  int main( argc, argv)

      int   argc;
      char *argv[];

  {
    long  Number;

    char *Name;
    char *LynxInputName  = (char *)NULL;
    char *LynxOutputName = (char *)NULL;

    char *LynxTraceMode  = (char *)NULL;
    char  LynxTrace      = LYNX_TRACE_NONE;

    char CoreFloat  = LYNX_FALSE;
    char Core       = LYNX_FALSE;
    char Verbose    = LYNX_FALSE;
    char Flatten    = LYNX_FALSE;
    char Transistor = LYNX_FALSE;

    Presents();

    if ( argc < 2 ) 
    {
      ErrorTooFewParameters();
    }

    mbkenv();
    rdsenv();
    loadrdsparam();
    LynxInitializeCutCxTable();

    for ( Number  = 1; 
          Number  < argc;
          Number++ ) 
    {
      if ( ! strcmp( argv[ Number ], "-c" )) Core = LYNX_TRUE;
      else 
      if ( ! strcmp( argv[ Number ], "-v" )) Verbose = LYNX_TRUE;
      else 
      if ( ! strcmp( argv[ Number ], "-t" )) Transistor = LYNX_TRUE;
      else 
      if ( ! strcmp( argv[ Number ], "-f" )) Flatten = LYNX_TRUE;
      else
      if ( LynxInputName == NULL ) LynxInputName = argv[ Number ];
      else
      if ( LynxOutputName == NULL ) LynxOutputName = argv[ Number ];
      else
      ErrorIllegalOption( argv[ Number ] );
    }

    if ( LynxInputName == NULL ) 
    {
      ErrorIllegalFileName( argv[ Number - 1 ] );
    }

    if ( LynxOutputName == NULL ) 
    {
      LynxOutputName = LynxInputName;
    }

    if ( Transistor && Flatten ) ErrorIllegalCombination();
    
    LynxTraceMode = getenv( "LYNX_TRACE" );

    if ( LynxTraceMode != (char *)NULL )
    {
      LynxTrace = LynxTraceMode[ 0 ] - '0';

      if ( LynxTrace == LYNX_TRACE_EQUI )
      {
        if ( LynxParseEqui() == LYNX_FALSE ) 
        {
          LynxTrace = LYNX_TRACE_NONE;
        }
      }

      if ( LynxTrace > LYNX_TRACE_EQUI ) 
      {
        LynxTrace = LYNX_TRACE_NONE;
      }
    }

    fprintf( stdout, "\n\n\t---> Extracts figure %s\n", LynxInputName );

    LynxFigureMbk = getphfig( LynxInputName, 'A' );

    if ( Flatten || Transistor ) 
    {
      if ( Verbose ) 
      {
        fprintf( stdout, "\n\t\t---> Flatten figure\n");
      }

      rflattenphfig( LynxFigureMbk, YES, ( Flatten ) ? YES : NO );
    }

    if ( Verbose ) 
    {
      fprintf( stdout, "\n\t\t---> Translate Mbk -> Rds\n");
    }

    LynxFigureRds = Lynxfigmbkrds( LynxFigureMbk, LYNX_MODE, 1 ); 

    if ( LynxTrace == LYNX_TRACE_MBKRDS ) 
    {
      LynxFigureTrace = addphfig( "trace_mbkrds" );
      Lynxfigrdsmbk( LynxFigureRds, LynxFigureTrace  );
      savephfig( LynxFigureTrace );
      delphfig( LynxFigureTrace->NAME );
    }

    if ( Verbose )
    {
      fprintf( stdout, "\t\t---> Delete Mbk figure\n");
    }

    delphfig( LynxFigureMbk->NAME ); 

    if ( Verbose ) 
    {
      fprintf( stdout, "\t\t---> Build windows\n");
    }
    LynxWindow = buildrdswindow( LynxFigureRds );

    if ( LynxWindow->SIZE == 0 ) 
    {
      ErrorMaskCounterNull();
    }

    if ( Verbose )
    {
      fprintf( stdout, "\t\t<--- %d\n", 
                       LynxWindow->SIZE );
      fprintf( stdout, "\n\t\t---> Rectangles    : %d",
                       LynxWindow->MASK );
      fprintf( stdout, "\n\t\t---> Figure size   : ( %6d, %6d )",
                       LynxWindow->XMIN * SCALE_X / RDS_LAMBDA, 
                       LynxWindow->YMIN * SCALE_X / RDS_LAMBDA );
      fprintf( stdout, "\n\t\t                     ( %6d, %6d )", 
                       LynxWindow->XMAX * SCALE_X / RDS_LAMBDA, 
                       LynxWindow->YMAX * SCALE_X / RDS_LAMBDA );
      fprintf( stdout, "\n\n\t\t---> Cut transistors\n");
    }
    Number = LynxCutTransistorElbow( LynxFigureRds, LynxWindow, Core );

    if ( Number == -1 )
    {
      ErrorCutTransistorElbow( Core );
    }

    if ( Verbose )
    {
      fprintf( stdout, "\t\t<--- %d", Number );
      fprintf( stdout, "\n\t\t---> Build equis\n");
    }
    Number = LynxBuildEqui( &LynxHeadEqui, LynxWindow );

    if ( LynxTrace == LYNX_TRACE_CHAIN )
    {
      LynxFigureTrace = addphfig( "trace_chain" );
      LynxDumpAllEqui( LynxFigureRds, LynxHeadEqui, LynxFigureTrace );
      savephfig( LynxFigureTrace );
      delphfig( LynxFigureTrace->NAME );
    }

    if ( Verbose )
    {
      fprintf( stdout, "\t\t<--- %d\n", Number);
      fprintf( stdout, "\t\t---> Delete windows\n");
    }
    destroyrdswindow( LynxFigureRds, LynxWindow );

    LynxLogicalFigure = addlofig( LynxOutputName );

    if ( Verbose )
    {
      fprintf( stdout, "\t\t---> Build signals\n");
    }

    Number = LynxBuildLogicalSignal( LynxFigureRds, LynxHeadEqui, 
                                     LynxLogicalFigure, Core );
    if ( Number < 0 )
    {
      Number    = -Number;
      CoreFloat =  LYNX_TRUE;
    }

    if ( Verbose )
    {
      fprintf( stdout, "\t\t<--- %d\n", Number);
      fprintf( stdout, "\t\t---> Build instances\n");
    }
    Number = LynxBuildLogicalInstance( LynxFigureRds, LynxLogicalFigure );

    if ( Verbose )
    {
      fprintf( stdout, "\t\t<--- %d\n", Number);
      fprintf( stdout, "\t\t---> Build transistors\n");
    }
    Number = LynxBuildLogicalTransistor( LynxFigureRds, LynxLogicalFigure );

    if ( Verbose )
    {
      fprintf( stdout, "\t\t<--- %d\n", Number);
      fprintf( stdout, "\t\t---> Save netlist\n\n");
    }

    delrdsfig( LynxFigureRds->NAME );

    Name = LynxVectorizeConnector( LynxLogicalFigure );

    if ( Name != (char *)NULL )
    {
      ErrorMissingConnector( Name );
    }

    savelofig( LynxLogicalFigure );

    fprintf( stdout, "\t<--- done !\n\n");

    if ( CoreFloat ) ErrorGenerateCoreFloat();

    return ( 0 );
  }
