Ejemplo n.º 1
0
CPhfig::CPhfig (string &name)
{
  phins_list *pPhins;


  cmess1 << "  o  Loading layout \"" << name << "\"...\n";
  fig = getphfig ((char *)name.c_str (), 'A');

  // Build the instances dictionnary (map).
  for (pPhins = fig->PHINS; pPhins != NULL; pPhins = pPhins->NEXT) {
    instances[pPhins->INSNAME] = pPhins;
  }
}
Ejemplo n.º 2
0
phfig_list *CIns::getmodel (void)
{
  if (!model) model = getphfig (phins->FIGNAME, 'A');

  return (model);
}
Ejemplo n.º 3
0
CPowers::CPowers ( CFig *fig
                   , long  xoff
                   , long  yoff
                   , char  atype
                   , int   alayer
                   , long  awidth
                 ) throw (except_done)
    : xoffset(xoff)
    , yoffset(yoff)
{
    LPower::iterator  itLine, beginLine, endLine;
    phins_list       *ins;
    phfig_list       *model;
    phseg_list       *seg, flatSeg;
    string            mess1,  mess2;
    char              ORIENT1, ORIENT2;
    char              segType;
    long              lbound, rbound, key;


    type  = atype;
    width = awidth;
    layer = layer2CALU (alayer);

    switch (type) {
    default:
    case C_HORIZONTAL:
        mess1   = "horizontal";
        mess2   = "EAST/WEST";
        ORIENT1 = EAST;
        ORIENT2 = WEST;

        AB1 = fig->XAB1 ();
        AB2 = fig->XAB2 ();
        break;
    case C_VERTICAL:
        mess1   = "vertical";
        mess2   = "NORTH/SOUTH";
        ORIENT1 = NORTH;
        ORIENT2 = SOUTH;

        AB1 = fig->YAB1 ();
        AB2 = fig->YAB2 ();
        break;
    }


    // Loop over all the instances.
    for (ins = fig->phfig.fig->PHINS; ins != NULL; ins = ins->NEXT) {
        model = getphfig (ins->FIGNAME, 'A');

        // Find the power segments (CALUx).
        for (seg = model->PHSEG; seg != NULL; seg = seg->NEXT) {

            // Skip no power segments.
            if (!(cmpALU (alayer, seg->LAYER) & F_CALU)) continue;
            segType = C_POWER_NONE;
            if (ISVDD (seg->NAME)) segType = C_POWER_VDD;
            if (ISVSS (seg->NAME)) segType = C_POWER_VSS;
            if (segType == C_POWER_NONE) continue;

            xyflat ( &(flatSeg.X1), &(flatSeg.Y1)
                     ,       seg->X1, seg->Y1
                     ,     ins->XINS, ins->YINS
                     ,   model->XAB1, model->YAB1
                     ,   model->XAB2, model->YAB2
                     ,   ins->TRANSF
                   );

            xyflat ( &(flatSeg.X2), &(flatSeg.Y2)
                     ,       seg->X2, seg->Y2
                     ,     ins->XINS, ins->YINS
                     ,   model->XAB1, model->YAB1
                     ,   model->XAB2, model->YAB2
                     ,   ins->TRANSF
                   );

            // Check the segment width.
            if (seg->WIDTH != width) {
                cerr << hwarn ("");
                cerr << "  " << layer2a (layer) << " \"" << seg->NAME
                     <<"\" segment at ("
                     << UNSCALE (seg->X1) << ","
                     << UNSCALE (seg->Y1) << ") doesn't have the rigth witdth :"
                     << UNSCALE (seg->WIDTH) << " instead of "
                     << UNSCALE (width) << ".\n";
                cerr << "  (instance \"" << ins->INSNAME << "\" of model \""
                     << model->NAME << "\")\n";

                continue;
            }

            // Check the segment direction & position.
            switch (type) {
            default:
            case C_HORIZONTAL:
                lbound = flatSeg.X1;
                rbound = flatSeg.X2;
                key = flatSeg.Y1;

                if (flatSeg.Y1 != flatSeg.Y2) {
                    cerr << hwarn ("");
                    cerr << "  " << layer2a (layer) << " \"" << seg->NAME
                         <<"\" segment at ("
                         << UNSCALE (seg->X1) << ","
                         << UNSCALE (seg->Y1) << ") is not " << mess1;
                    cerr << "  (instance \"" << ins->INSNAME << "\" of model \""
                         << model->NAME << "\")\n";

                    continue;
                }

                if (   (cmpALU (alayer, CALU1) & F_CALU)
                        && !fig->phfig.onslice (flatSeg.Y1,yoffset)) {
                    cerr << hwarn ("");
                    cerr << "  " << layer2a (layer) << " \"" << seg->NAME
                         <<"\" segment at ("
                         << UNSCALE (seg->X1) << ","
                         << UNSCALE (seg->Y1) << ") is not on a slice boundary.\n";
                    cerr << "  (instance \"" << ins->INSNAME << "\" of model \""
                         << model->NAME << "\")\n";
                    cerr << "  (valide slices boundaries are"
                         << " ((n * " << D::Y_SLICE << ") - " << D::WIDTH_VSS / 2 << ") or"
                         << " ((n * " << D::Y_SLICE << ") + " << D::WIDTH_VSS / 2 << ") )\n";

                    continue;
                }
                break;

            case C_VERTICAL:
                lbound = flatSeg.Y1;
                rbound = flatSeg.Y2;
                key = flatSeg.X1;

                if (flatSeg.X1 != flatSeg.X2) {
                    cerr << hwarn ("");
                    cerr << "  " << layer2a (layer) << " \"" << seg->NAME
                         <<"\" segment at ("
                         << UNSCALE (seg->X1) << ","
                         << UNSCALE (seg->Y1) << ") is not " << mess1;
                    cerr << "  (instance \"" << ins->INSNAME << "\" of model \""
                         << model->NAME << "\")\n";

                    continue;
                }
                break;
            }


            beginLine = powerLines.begin ();
            endLine = powerLines.end ();


            // Check if the power line is of the same type.
            // (no short circuits between VDD & VSS.
            itLine = powerLines.find (key);
            if (itLine != endLine) {
                if (itLine->second.type != segType) {
                    cerr << herr ("");
                    cerr << "  " << layer2a (layer) << " \"" << seg->NAME
                         <<"\" segment at ("
                         << UNSCALE (seg->X1) << ","
                         << UNSCALE (seg->Y1) << ") conflict with power line at"
                         << UNSCALE (key) << ".\n";

                    throw except_done ();
                }
            }


            // Merge the segment with the power line (at long last...).
            powerLines[key].add (lbound, rbound);
            powerLines[key].type = segType;
        }
    }
}
Ejemplo n.º 4
0
void lecture_vues(char *nom_circuit_lo, COEUR *lecoeur, lofig_list **circuit_lo,
	chain_list **liste_plotsph, int	*nbplots, chain_list **lst_conestouest)
{
	chain_list * lstph;
	phfig_list * ptfig;
	loins_list * circuit_inst;		/* instances dans le circuit logique */
	loins_list * coeur_inst = NULL;		/* instance du coeur                 */
	int	nbcoeur = 0;			/* nombres d'instances susceptibles d'etre le coeur */
	int	retour;

	*circuit_lo = getlofig(nom_circuit_lo, 'A');

	if (!(*circuit_lo)) 
		ringerreur(ERR_CIRCUITLO, nom_circuit_lo, NULL);

	/* viewlo(); */

	circuit_inst = (*circuit_lo)->LOINS;

	if (!circuit_inst) 
		ringerreur(ERR_CIRCUITINST, nom_circuit_lo, NULL);

	/* ---------------------------------------------------------------------------------------------------------- */
	/* test la coherences des modeles logiques et physiques de toutes les modeles utilisee dans la figure logique */
	/* ---------------------------------------------------------------------------------------------------------- */

	testcon_modelfig(*circuit_lo);	
   
	/* ------------------------------------------------------------------------------------------------------------- */
	/* Parcours des instances pour distinguer celles qui sont des plots et les autres (normalement 1 seule: le coeur */
	/* ------------------------------------------------------------------------------------------------------------- */

	*nbplots = 0;

	(*liste_plotsph) = NULL;   /* Initialisation de la liste de plots physiques */

	while (circuit_inst != NULL) {
		retour = incatalog(circuit_inst->FIGNAME);
		if (mode_debug) 
			printf("FIGNAME %s incatalog %d\n", circuit_inst->FIGNAME, retour);

		if (retour) {
			(*nbplots)++;

			/* -------------------------------------- */
			/* Renommage des connecteurs vdd* et vss* */
			/* -------------------------------------- */

			ajout_listeplotsph(circuit_inst->FIGNAME, liste_plotsph);
		}  else /* le coeur est reconnu */		 {
			nbcoeur++;
			coeur_inst = circuit_inst;
		}

		circuit_inst = circuit_inst->NEXT;
	}

	if (mode_debug) 
		printf("Lirevues: nb inst plots %d\n", *nbplots);

	/* -------------------------------------------- */
	/* Verification sur le nombres de coeur trouves */
	/* -------------------------------------------- */

	switch (nbcoeur) {
	case 0: 
		ringerreur(ERR_NONCOEUR, NULL, NULL); /* aucun => ringerreur */
		break;

	case 1: 
		/* ------------------------------------------------------ */
		/* un seul coeur, on charge les vues  logique et physique */
		/* ------------------------------------------------------ */

		(*lecoeur).coeur_lo = coeur_inst;
		if ((*lecoeur).coeur_lo == NULL)
			ringerreur(ERR_COEURINSTLO, coeur_inst->FIGNAME, NULL);

		ptfig = (*lecoeur).coeur_ph = getphfig(coeur_inst->FIGNAME, 'A');
		(*lecoeur).coord.xabs = 0;
		(*lecoeur).coord.yabs = 0; /* Coordonnees du coeur fixees a 0,0 par defaut */
		(*lecoeur).width = ptfig->XAB2 - ptfig->XAB1;
		(*lecoeur).height = ptfig->YAB2 - ptfig->YAB1;
		(*lecoeur).coord.piste = 0;

		(*lecoeur).rotation = NOSYM; /* pas de rotation par defaut */

		/* viewphfig((*lecoeur).coeur_ph);  */

		if ((*lecoeur).coeur_ph == NULL)
			ringerreur(ERR_COEURINSTPH, coeur_inst->FIGNAME, NULL);

		break;
	default: 
		/* ------------------------------------------ */
		/* plusieurs candidats au coeur => ringerreur */
		/* ------------------------------------------ */

		ringerreur(ERR_PLUSCOEUR, (*circuit_lo)->LOINS, NULL);
	}

	/* ----------------------------------------------------- */
	/* verification des modeles pour connexion alim internes */
	/* ----------------------------------------------------- */

	lstph = *liste_plotsph;

	while (NULL != lstph) {
		verif_con_estouest(lstph, lst_conestouest);
		lstph = lstph->NEXT;
	}

	if (mode_debug) 
		affic_listeplotsph(*liste_plotsph);

}
Ejemplo n.º 5
0
int main (int argc, char *argv[])
{
  phfig_list *pFig;
  phseg_list *pSeg;
  phvia_list *pVIA;

        long  length[_MAX_ALU_];
        long  number[_MAX_ALU_];
        long  total_length;
        long  total_number;
        long  total_VIA;
         int  i;


  mbkenv ();
  alliancebanner ( "PdV"
                 , "0.1"
                 , "Pot de Vin - Routing Evaluator"
                 , "2002"
                 , "5.0"
                 );


  if (argc < 2) {
    fprintf (stderr, "Usage : pdv <layout>\n");

    exit (1);
  }


  pFig = getphfig (argv[1], 'A');

  for (i = 0; i < _MAX_ALU_; i++) {
    length[i] = 0;
    number[i] = 0;
  }

  for (pSeg = pFig->PHSEG; pSeg != NULL; pSeg = pSeg->NEXT) {
    switch (pSeg->LAYER) {
      case ALU2:
      case CALU2: i = _ALU2_; break;
      case ALU3:
      case CALU3: i = _ALU3_; break;
      case ALU4:
      case CALU4: i = _ALU4_; break;
      case ALU5:
      case CALU5: i = _ALU5_; break;
      case ALU6:
      case CALU6: i = _ALU6_; break;
      case ALU7:
      case CALU7: i = _ALU7_; break;
      case ALU8:
      case CALU8: i = _ALU8_; break;
      default:    continue;
    }

    number[i]++;

    if (pSeg->X1 == pSeg->X2) {
      /* Horizontal segments. */
      length[i] += (pSeg->Y2 - pSeg->Y1) / SCALE_X;
    } else {
      /* Vertical segments. */
      length[i] += (pSeg->X2 - pSeg->X1) / SCALE_X;
    }
  }

  for (i = 0; i < _MAX_ALU_; i++) { if (number[i] == 0) number[i]++; }


  total_VIA = 0;
  for (pVIA = pFig->PHVIA; pVIA != NULL; pVIA = pVIA->NEXT) {
    total_VIA++;
  }

  

  printf ("\n\n");
  printf ("  Routing statistics :\n\n");

  total_length = 0;
  total_number = 0;
  for (i = 0; i < _MAX_ALU_; i++) {
    printf ("  - ALU%d length  := %10d", i+2, length[i]);
    printf ("  (average length := %d)\n", length[i] / number[i]);

    total_length += length[i];
    total_number += number[i];
  }

  printf ("\n");
  printf ("  - Total length := %10d" , total_length);
  printf ("  (average length := %d)\n", total_length / total_number);

  printf ("\n");
  printf ("  - Total VIA    := %10d\n" , total_VIA);
  printf ("\n\n");
  

  exit (0);
}