/****************************************************************************/
/*                                                                          */
/*                      Chaine de CAO & VLSI   Alliance                     */
/*                                                                          */
/*    Produit : DESB  v2.n                                                  */
/*    Fichier : switch.c                                                    */
/*                                                                          */
/*    (c) copyright 1991 Laboratoire MASI equipe CAO & VLSI                 */
/*    Tous droits reserves                                                  */
/*    Support : e-mail cao-vlsi@masi.ibp.fr                                 */
/*                                                                          */
/*    Auteur(s) : Marc LAURENTIN                        le : 06/09/1991     */
/*                                                                          */
/*    Modifie par :                                     le : ../../....     */
/*    Modifie par :                                     le : ../../....     */
/*    Modifie par :                                     le : ../../....     */
/*                                                                          */
/****************************************************************************/

#include "declar.h"



void test_encr_degr();
void test_degr();


/****************************************************************************
 *                         fonction test_red_sw();                          *
 ****************************************************************************/

int test_red_sw(ptchain)
chain_list * ptchain;
{
int switch_suppr=0;
chain_list * ptchain0;
chain_list * ptchain1;

   for(ptchain0=ptchain;ptchain0!=NULL;ptchain0=ptchain0->NEXT)
   {
   ptchain1=ptchain0->NEXT;
      while(ptchain1) 
      {
      chain_list *sw0,*sw1;

      sw0=(chain_list*)ptchain0->DATA;
      sw1=(chain_list*)ptchain1->DATA;
         if (( (sw0->DATA==sw1->DATA)&&(sw0->NEXT->DATA==sw1->NEXT->DATA) )||
             ( (sw0->DATA==sw1->NEXT->DATA)&&(sw0->NEXT->DATA==sw1->DATA) ))
         {
         chain_list *ptsav;
         switch_suppr++;
         ptsav=ptchain1->NEXT;
         sw1=delchain(sw1,sw1->NEXT);
         sw1=delchain(sw1,sw1);
         ptchain0=delchain(ptchain0,ptchain1);
         ptchain1=ptsav;
         }
         else ptchain1=ptchain1->NEXT;
      }
   }
return(switch_suppr);
}
      
/****************************************************************************
 *                         fonction detec_switch();                         *
 ****************************************************************************/

long detect_switch(cone)
cone_list * cone;
{
ptype_list * user ;
list_list *path0, *path1;
link_list *link0, *link1;
chain_list *chain = NULL;
chain_list *sw_chain = NULL;
short test=0;


/*------------------ ---+
| Nettoyage des champs  |
+----------------------*/
   if((cone->TYPE & SWITCH)==SWITCH)
   {
   cone->TYPE &= ~SWITCH ;
   user=getptype(cone->USER,SWITCH);


      if(user==NULL)
      {
      dsbBug(12,"detec_switch",cone->NAME,"SWITCH",0);
      }

      cone->USER=delptype(cone->USER,SWITCH);
      }

/*------------------------------+
| On commence detect switch     |
+------------------------------*/ 

   for (path0=cone->PATH;path0;path0=path0->NEXT)
   {
      if((path0->TYPE & BLEEDER)==BLEEDER) continue ;

      for(path1=path0->NEXT;path1;path1=path1->NEXT)
      {
         if ((path1->TYPE & BLEEDER)==BLEEDER) continue ;

         if ( ((path0->TYPE & path1->TYPE & VDD)==VDD) ||
              ((path0->TYPE & path1->TYPE & VSS)==VSS) ||
              ((path0->TYPE & path1->TYPE & EXT)==EXT) )
         {
            for (link0=(link_list*)path0->DATA,link1=(link_list*)path1->DATA;
                 (link0!=NULL)&&(link1!=NULL);
                 link0=link0->NEXT,link1=link1->NEXT)
            {
               if ((char*)link0->TRANS==(char*)link1->TRANS) continue;
               else
               {
                  if ((test=test2switch(link0,link1))==0) break;
                  else
                  {
                  (link0->TYPE)|=SWITCH;
                  (link1->TYPE)|=SWITCH;
                  chain=addchain(NULL,(void*)link0->TRANS);
                  chain=addchain(chain,(void*)link1->TRANS);
                  sw_chain=addchain(sw_chain,chain);
                  }
               }
            }
         }
      }
   }
   
   if (sw_chain != NULL)
   {
   (cone->TYPE)|=SWITCH;
   test=test_red_sw(sw_chain);
   cone->USER=addptype(cone->USER,SWITCH,(void*)sw_chain);
   }
}


/****************************************************************************
 *                         fonction test2switch();                          *
 ****************************************************************************/
    /*--------------------------------------------------------------------*
     | On se contente du critere "2 transistors de type different couple" |
     |et on ne cherche pas a mettre en evidence la presence de l'inverseur|
     | sur la grille de l'un des deux.                                    |
     *--------------------------------------------------------------------*/

short  test2switch(ptlink0, ptlink1)
link_list *ptlink0,*ptlink1;
{

   if ( (((ptlink0->TYPE & TN)==TN) && ((ptlink1->TYPE & TP)==TP)) ||
     (((ptlink0->TYPE & TP)==TP) && ((ptlink1->TYPE & TN)==TN)) )
   {
      if(ptlink0->NEXT == NULL) return(0);
      if(ptlink1->NEXT == NULL) return(0);
      if(ptlink1->NEXT->TRANS==ptlink0->NEXT->TRANS) return(1);
   }
return(0);
}
