Beispiel #1
0
phseg_list &CIns::flatseg (phseg_list &flatSeg, phseg_list &seg)
{
  flatSeg.NAME  = seg.NAME;
  flatSeg.LAYER = seg.LAYER;
  flatSeg.WIDTH = seg.WIDTH;


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

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

  // Ensure that (X1,Y1) < (X2,Y2) and type is correct.
  if (flatSeg.X1 > flatSeg.X2) { swap (flatSeg.X1, flatSeg.X2); }
  if (flatSeg.Y1 > flatSeg.Y2) { swap (flatSeg.Y1, flatSeg.Y2); }

  if (flatSeg.Y1 == flatSeg.Y2) {
    if (flatSeg.X1 < flatSeg.X2) flatSeg.TYPE = LEFT;
    else                         flatSeg.TYPE = RIGHT;
  } else {
    if (flatSeg.Y1 < flatSeg.Y2) flatSeg.TYPE = UP;
    else                         flatSeg.TYPE = DOWN;
  }

  // Return the flattened segment;
  return (flatSeg);
}
Beispiel #2
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;
        }
    }
}