/********************************************************************
*                                                                   *
* Laboratoire MASI CAO-VLSI, UPMC, Copyright 1991 1992 1993 1994    *
*                                                                   *
* Software support Email : cao-vlsi@masi.ibp.fr                     *
*                                                                   *
* Authors : Zouina AKTOUF &                                         *
*           El Arabi RHOMARI &                                      *
*           Jose MARTINS DOS SANTOS                                 *
*                                                                   *
* Supervision & Modifications : Lotfi BEN AMMAR                     *
*                                                                   *
********************************************************************/
/************************************************************************
*	          fichier : dpr_R.c	                                        *
*	version : 3.0			                                            *
*	date    : 16/03/93		                                            *
************************************************************************/
#include "dpr_R.h"

 extern void                 init();           /* actually in util_P.c      */
 extern DPP_GET_INDEX_LIST  *hierarchy();      /* actually in util_P.c      */
 extern void                 table();          /* actually in util_P.c      */
 extern char                 get_MBK_SEPAR();  /* actually in util_P.c      */
 extern DPP_GET_INDEX_LIST  *place();          /* actually in util_P.c      */
 extern void                 place_no_index(); /* actually in util_P.c      */
 extern void                 verif_tableau();  /* actually in util_P.c      */
 extern void                 place_con();      /* actually in figure_P.c    */
 extern void                 verif_datapath(); /* actually in util_P.c      */
 extern void                 opti1();          /* actually in optim_P.c     */
 extern void                 opti2();          /* actually in optim_P.c     */
 extern void                 coord();          /* actually in coord_P.c     */
 extern void                 create_physical();/* actually in coord_P.c     */

 extern void                 move_globalcon(); /* actually in mvcon_I.c     */

 extern FIGURE              *loaddprfig();     /* actually in load_R.c      */
 extern int                  optiplace();      /* actually in optiplace_R.c */
 extern void                 placeconpere();   /* actually in sig_R.c       */
 extern void                 dprlin();         /* actually in dprlin_R.c    */
 extern void                 dprrout();        /* actually in router_R.c    */
 extern void                 dprchannel();     /* actually in chanrout_R.c  */
 extern void                 dprchannelbis();  /* actually in chanrout_R.c  */
 extern void                 dprsave();        /* actually in save_R.c      */

 main(argc,argv)
 int argc;
 char *argv[];

 {
 char		*source;
 char		*result;
 char		*ptoption;
 FIGURE	    *ptfig_dpr;
 NUMTRACK   *ptlist_num;
 long        t1=0,t2=0;
 char       *date1,*date2;
 int         option_o=TRUE;
 int         option_h=FALSE;
 int         i=0;
 int         flag;
 lofig_list *ptmbk_lofig;
 DPP_GET_INDEX_LIST *ptindex;
 int         nbl=0,nbc=0;
 char        separ_car;
 phfig_list *ptmbk_phfig;
 DPP_GET_INDEX_LIST *pt_indexe;
 int         option_o1=0,option_o2=0;
 int         place_op=FALSE;
 int         optim_op1=FALSE;
 int         optim_op2=FALSE;
 int         optim_op3=FALSE;
 int         route_op=FALSE;

 alliancebanner("DPR",DPR_VERSION,"DataPath Router","91-93",ALLIANCE_VERSION);

 date1 = mbkalloc(26);
 date2 = mbkalloc(26);

 mbkenv();

 if ((argc<3)||(argc>7))
    {
    printf("Usage: dpr <source> [-p [-o1/-o2]] [-r <result> [-o3]]\n");
    printf("\nWhere:\n");
    printf("<source> : the name of the input netlist and\n");
    printf("           the corresponding placement result.\n");
    printf("[-p]     : this option activates the placement step.\n");
    printf("[-o1]    : this option optimizes the column ordering using\n");
    printf("           a first algorithm within the placement step.\n");
    printf("[-o2]    : this option optimizes the column ordering using\n");
    printf("           a second algorithm within the placement step.\n");
    printf("[-r]     : this option activates the routing step.\n");
    printf("<result> : the name of the routed datapath,\n");
    printf("           it must be given explicitly when the routing step is activated.\n");
    printf("[-o3]    : this option optimizes the column ordering using\n");
    printf("           a third algorithm within the routing step.\n");
    exit(1);
    }
 for (i=2;i<argc;i++)
     {
     ptoption = namealloc(argv[i]);
     if (ptoption==namealloc("-p"))
        {
        place_op = TRUE;
        }
     else
        {
        if (ptoption==namealloc("-r"))
           {
           route_op = TRUE;
           result = argv[i+1];
           if (result==NULL)
              {
              printf("Usage: dpr <source> [-p [-o1/-o2]] [-r <result> [-o3]]\n");
              printf("\nWhere:\n");
              printf("<source> : the name of the input netlist and\n");
              printf("           the corresponding placement result.\n");
              printf("[-p]     : this option activates the placement step.\n");
              printf("[-o1]    : this option optimizes the column ordering using\n");
              printf("           a first algorithm within the placement step.\n");
              printf("[-o2]    : this option optimizes the column ordering using\n");
              printf("           a second algorithm within the placement step.\n");
              printf("[-r]     : this option activates the routing step.\n");
              printf("<result> : the name of the routed datapath,\n");
              printf("           it must be given explicitly when the routing step is activated.\n");
              printf("[-o3]    : this option optimizes the column ordering using\n");
              printf("           a third algorithm within the routing step.\n");
              exit(1);
              }
           i++;
           }
        else
           {
           if (ptoption==namealloc("-o1"))
              {
              optim_op1 = TRUE;
              if (optim_op2==TRUE)
                 {
                 printf("Usage: dpr <source> [-p [-o1/-o2]] [-r <result> [-o3]]\n");
                 printf("\nWhere:\n");
                 printf("Only one of the options [-o1] [-o2] can be used, but not both!\n");
                 exit(1);
                 }
              }
           else
              {
              if (ptoption==namealloc("-o2"))
                 {
                 optim_op2 = TRUE;
                 if (optim_op1==TRUE)
                    {
                    printf("Usage: dpr <source> [-p [-o1/-o2]] [-r <result> [-o3]]\n");
                    printf("\nWhere:\n");
                    printf("Only one of the options [-o1] [-o2] can be used, but not both!\n");
                    exit(1);
                    }
                 }
              else
                 {
                 if (ptoption==namealloc("-o3"))
                    {
                    optim_op3 = TRUE;
                    }
                 else
                    {
                    printf("Usage: dpr <source> [-p [-o1/-o2]] [-r <result> [-o3]]\n");
                    printf("\nWhere:\n");
                    printf("<source> : the name of the input netlist and\n");
                    printf("           the corresponding placement result.\n");
                    printf("[-p]     : this option activates the placement step.\n");
                    printf("[-o1]    : this option optimizes the column ordering using\n");
                    printf("           a first algorithm within the placement step.\n");
                    printf("[-o2]    : this option optimizes the column ordering using\n");
                    printf("           a second algorithm within the placement step.\n");
                    printf("[-r]     : this option activates the routing step.\n");
                    printf("<result> : the name of the routed datapath,\n");
                    printf("           it must be given explicitly when the routing step is activated.\n");
                    printf("[-o3]    : this option optimizes the column ordering using\n");
                    printf("           a third algorithm within the routing step.\n");
                    exit(1);
                    }
                 }
              }
           }
        }
     }
 
 if ((place_op==FALSE)&&(route_op==FALSE))
    {
    printf("Usage: dpr <source> [-p [-o1/-o2]] [-r <result> [-o3]]\n");
    printf("\nWhere:\n");
    printf("At least one of the options [-p] [-r] must be used\n");
    exit(1);
    }

 if ((place_op==FALSE)&&((optim_op1==TRUE)||(optim_op2==TRUE)))
    {
    printf("Usage: dpr <source> [-p [-o1/-o2]] [-r <result> [-o3]]\n");
    printf("\nWhere:\n");
    printf("Options [-o1] and [-o2] can not be used without the placement option [-p]\n");
    exit(1);
    }
 
 if ((route_op==FALSE)&&(optim_op3==TRUE))
    {
    printf("Usage: dpr <source> [-p [-o1/-o2]] [-r <result> [-o3]]\n");
    printf("\nWhere:\n");
    printf("Option [-o3] can not be used without the routing option [-r]\n");
    exit(1);
    }

 source=argv[1];

 if (place_op==TRUE)
    {
    /* Placement */
    printf("          ***  PLACEMENT STEP  ***\n");
    t1 = time(&t1);
    date1 =(char *)ctime(&t1);

    flag = LSB;
    printf("* Initializing the symbolic Array *\n");
    init();  /* initialisation du tableau utilise par le placeur */
    ptmbk_lofig = getlofig(source,'A');
    printf("* Checking hierarchical constraints *\n");
    ptindex = hierarchy(ptmbk_lofig);
    printf("* Tow dimensional array construction *\n");
    table(ptmbk_lofig,&nbl,&nbc);
    printf("Number of slices: %d; Number of columns: %d\n",nbl,nbc);
    printf("* Symbolic placement *\n");
    separ_car = get_MBK_SEPAR();
    ptmbk_phfig = addphfig(ptmbk_lofig->NAME);
    rflattenlofig(ptmbk_lofig,YES,YES);
    pt_indexe = place(ptmbk_lofig,ptindex,nbl,nbc,separ_car,flag);
    place_no_index(ptmbk_lofig,pt_indexe,separ_car,flag,nbl,nbc);
    printf("* External terminal placement *\n");
    /*verif_tableau(nbl,nbc);*/
    place_con(ptmbk_lofig,nbl,nbc);
    /*verif_datapath();*/
    if (optim_op1==1)
       {
       printf("* Placement optimization (first algo) *\n");
       opti1(nbl,nbc);
       }
    if (optim_op2==1)
       {
       printf("* Placement optimization (second algo) *\n");
       opti2(nbl,nbc);
       }
    printf("* Computing instance coordinates *\n");
    coord(ptmbk_phfig,nbl,nbc);
    printf("* Saving physical figure %s *\n",source);
    create_physical(ptmbk_phfig,nbl,nbc);

    t2 = time(&t2);
    date2 =(char *)ctime(&t2);
    printf("* Total placement time: %ld seconds *\n",t2-t1);
    printf("\n");
    }

 if ((place_op==TRUE)||(route_op==TRUE))
    {
    /* deplacement (eventuel) de connecteurs globaux d'apres le fichier .dpr*/
    printf("* Moving external terminals according to the .dpr file *\n");
    move_globalcon(source);
    }

 if (route_op==TRUE)
    {
    /* Routage */
    printf("          ***  ROUTING STEP  ***\n");
    t1 = time(&t1);
    date1 =(char *)ctime(&t1);

    printf("* Loading the physical and logical views *\n");
    ptfig_dpr = loaddprfig(source);
    if (optim_op3==TRUE)
       {
       printf("* Optimizing column ordering (third algo) *\n");
       (void ) optiplace(ptfig_dpr);
       }
    dprlin(ptfig_dpr);
    placeconpere(ptfig_dpr);
    printf("* Global routing *\n");
    dprrout(ptfig_dpr,option_o);
    printf("* Channel routing *\n");
    dprchannel(ptfig_dpr,&ptlist_num);
    printf("* Saving physical figure %s *\n",result);
    dprsave(ptfig_dpr,result,ptlist_num,option_h);

    t2 = time(&t2);
    date2 =(char *)ctime(&t2);
    printf("* Total routing time: %ld seconds *\n",t2-t1);
    }

 exit(0);
 }
