Example #1
0
ostream &operator<< (ostream &o, const CXRect *rect)
{
  o << "+         CXRect::seg ("
    << rect->seg.X1 << ", "
    << rect->seg.Y1 << "), ("
    << rect->seg.X2 << ", "
    << rect->seg.Y2 << ") "
    << rect->seg.WIDTH << " "
    << layer2a(rect->seg.LAYER) << "\n";

  o << "+         CXRect::rect(" << &(rect->rect) << ")\n";
  o << "+         CXRect::grid(" << &(rect->grid) << ")\n";

  return (o);
}
Example #2
0
ostream &operator<< (ostream &o, CPowers &self)
{
    LPower::iterator  itLine, beginLine, endLine;


    o << "+ CPowers:\n";
    o << "+   ";

    if (self.type == C_HORIZONTAL) o << "horizontal";
    else                           o << "vertical  ";

    o << " " << layer2a (self.layer) << " " << UNSCALE (self.width);
    o << " [" << UNSCALE (self.AB1)
      <<  "," << UNSCALE (self.AB2) << "]\n";

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

    for (itLine = beginLine; itLine != endLine; itLine++) {
        o << "+  " << itLine->first << " " << itLine->second << "\n";
    }

    return (o);
}
Example #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;
        }
    }
}