#usage "FastPlacer" "

" "FastPlacer assists you in good placing of the components before routing or autorouting. " "It is especially useful when you are designing multilayer boards where GND and supply nets are typically " "laid out in internal layers. But designs using double sided board with one side covered with groundplane " "are equally good candidates for FastPlacer. " "FastPlacer runs in board editor mode, not in schematic. It is a pure graphic design tool. " "

" "How you use FastPlacer:" "

" "You use FastPlacer after having set up your schematic, and before beginning to design the board. " "Call it by typing 'RUN FastPlacer' at the command line; the ULP " "will then make the following 3 function key assignments for you because they are necessary for speedy working." "

" " ASSIGN F12 'RATSNEST; RUN FastPlacer; MOVE'" "

" " ASSIGN S+F12 'RUN FastPlacer end'" "

" " ASSIGN C+F12 'RUN FastPlacer toggle'" "

" "It's recommended to issue the RATSNEST command before each run of FastPlacer; the 1st of the above assignments " "does this automatically. Equally, after FastPlacer, a MOVE command is appended automatically, to allow you " "to immediately go ahead moving more components after updating the display with F12. The version with the argument " "\"end\" is for terminating the placement session and cleaning up; the version with \"toggle\" is for having " "a look at the original situation in the layer 19 'unrouted'." "

" "In your schematic, leave all important signal nets in the class 0 (\"default\"), all others (like " "power supply and GND nets) you place in other classes (define a class 1 (\"Power nets\"), e.g. for this). " "Then go to the Board mode (or create the board). Usually it displays a distracting huge mess " "of yellow air wires running all over the place. Run FastPlacer and you'll be amazed to see the " "picture cleared up, leaving only the essential signal nets you have allowed to remain in the class 0 before." "

" "Placing the components goes as usual, with the exception that the air wires don't follow the " "components immediately. Instead you run FastPlacer (hit F12) whenever you feel having made a progress " "in placing components. While placing, just disregard all the GND and supply nets " "although it makes good sense to keep them in mind. For example it is wise to line up all OpAmps in rows " "with all in the same orientation; This radically eases power supply routing later on. " "

" "After placing, run FastPlacer once again but this time with the argument \"end\" (hit SHIFT+F12). This cleans up " "and prepares everything for subsequent routing (manual or auto). " "

" "If, during a placement session, you like to see all of the original air wires, just hit CONTROL+F12. " "This toggles back and forth between a display with the original layer 19 'unrouted' and with the new " "layer '__SignalWires'. " "

" "What FastPlacer does:" "

" "It simply hides the layer 19 'unrouted' and presents instead a newly created layer where it " "copies only the air wires belonging to the class 0 'default' signal nets. " "The new layer, once created, will be reused on further runs of this ULP. " "This layer can be emptied and deleted from the layer stack at any time without further consequences, " "either by hand, or simply by hitting SHIFT+F12. " "This ULP does not affect your schematic in any way nor does it interfere with EAGLE's " "routing or autorouting functionality. " "

" "What FastPlacer cannot do:" "

" "FastPlacer is a rather crude substitute for a quite simple thing: one should be able to select whether " "air wires belonging to nets of certain classes should be displayed or not. Excluding GND and supply nets " "from the air wire display greatly helps the designer focus on his main task of laying out his signal " "paths in an orderly and straightforward manner. FastPlacer lets you make these exclusions, but it cannot " "give you the feel of rubberbands always following the components like in the original air wire display. " "

" "THIS PROGRAM IS PROVIDED AS IS AND WITHOUT WARRANTY OF ANY KIND, EXPRESSED OR IMPLIED" "

" "Author: Luc Eberhard eol.eberhard@bluewin.ch / October 2006" // THIS PROGRAM IS PROVIDED AS IS AND WITHOUT WARRANTY OF ANY KIND, EXPRESSED OR IMPLIED // Declarations int x1[], y1[], x2[], y2[]; // arrays for buffering positions of all signal wire segments int i,j; // counting variables int iBoxResult; int iFast; int iLNSignalWires; int iLastNumber; string sCommand; string sInstruction; string sMessage; // main if (board) board(B) { // Set grid units to mm sprintf(sInstruction, "GRID MM;\nSET WIRE_BEND 2;\n"); sCommand = sInstruction; // Look for a preexisting special layer named "__SignalWires" // If the layer is found, determine whether it is currently visible or not. iFast = 2; iLNSignalWires = 0; B.layers(L) { if (L.name == "__SignalWires") { iLNSignalWires = L.number; iFast = L.visible; } } // If the version with 'toggle' is called and the special layer exists, then toggle its visibility // with the one of the layer 19 'unrouted'. if ((argc == 2) && (argv[1] == "toggle")) { if (iFast == 1) sprintf(sInstruction,"DISPLAY UNROUTED -__SignalWires;\n"); if (iFast == 0) sprintf(sInstruction,"DISPLAY -UNROUTED __SignalWires;\n"); if (iFast < 2) sCommand += sInstruction; sprintf(sInstruction, "GRID LAST;\n"); sCommand += sInstruction; exit (sCommand); } // If no special layer is found, we are running the first time and look for a free layer position // (something above LAYER_USER (100)) and create the layer from scratch. Color is to be light magenta // line style solid. // If the layer already exists, we clean it up (delete all wire segments) to prepare it for copying if (!iLNSignalWires) { if ((argc == 2) && (argv[1] == "end")) { sprintf(sInstruction, "GRID LAST;\n"); sCommand += sInstruction; exit (""); } iLastNumber = LAYER_USER; B.layers(L) { if (L.number > (iLastNumber+1)) { if (!iLNSignalWires) iLNSignalWires = iLastNumber+1; iLastNumber=L.number; } } sprintf (sMessage,"You started the FastPlacer ULP the first time:\n\ A new layer called \"__SignalWires\" with the number %d will be created now. OK?\n\ If you say NO here, the ULP terminates without further action.\0",iLNSignalWires); if (dlgMessageBox(sMessage, "&Yes", "&No") == 1) { sprintf(sInstruction, "GRID LAST;\n"); sCommand += sInstruction; exit (""); } sprintf (sInstruction, "LAYER %d __SignalWires;\n",iLNSignalWires); sCommand += sInstruction; sprintf (sInstruction, "SET COLOR_LAYER %d 13;\n",iLNSignalWires); sCommand += sInstruction; sprintf (sInstruction, "SET FILL_LAYER %d 1;\n",iLNSignalWires); sCommand += sInstruction; sprintf (sInstruction, "ASSIGN F12 'RATSNEST; RUN FastPlacer; MOVE';\n"); sCommand += sInstruction; sprintf (sInstruction, "ASSIGN S+F12 'RUN FastPlacer end';\n"); sCommand += sInstruction; sprintf (sInstruction, "ASSIGN C+F12 'RUN FastPlacer toggle';\n"); sCommand += sInstruction; } else { sprintf(sInstruction, "DISPLAY NONE __SignalWires;\n"); sCommand += sInstruction; B.wires(W) { if (W.layer == iLNSignalWires) { sprintf(sInstruction, "DELETE (%.4f %.4f);\n",u2mm(W.x1+W.x2)/2, u2mm(W.y1+W.y2)/2); sCommand += sInstruction; } } } // At this point we have our special layer named "__SignalWires" cleaned up. // If the ULP was called with the argument "end" this signifies the user wants to get rid // of this layer so we remove it and terminate the ULP. The remaining layers are shown so as to // prepare for routing by hand or by auto router. if ((argc == 2) && (argv[1] == "end")) { sprintf(sInstruction,"LAYER -%d;\n",iLNSignalWires); sCommand += sInstruction; sprintf(sInstruction, "DISPLAY TOP BOTTOM PADS VIAS TPLACE BPLACE TNAMES BNAMES DIMENSION -TVALUES -BVALUES UNROUTED;\n"); sCommand += sInstruction; sprintf(sInstruction, "GRID LAST;\n"); sCommand += sInstruction; exit(sCommand); } // The user has chosen to go ahead: so we copy all class 0 (default) air wires from the currently invisible // layer 19 (unrouted) to the layer "__SignalWires". This will reproduce the subset of those air wires the // user wants to see for effective placement of components. All other cluttering stuff is left aside. j=1; B.signals(S) { if (S.class.name == "default") { S.wires(W) { if (W.layer == 19) { x1[j] = W.x1; // get endpoint coordinates of all wire segments out there y1[j] = W.y1; // but only of those which belong to class 0 x2[j] = W.x2; y2[j] = W.y2; ++j; } } } } // we come up here with a subset of j wire segments; now start drawing sprintf(sInstruction, "CHANGE LAYER %d;\n",iLNSignalWires); sCommand += sInstruction; for (i = 1; i < j; ++i) { sprintf(sInstruction, "WIRE %.4f (%.4f %.4f) (%.4f %.4f);\n", u2mm(20), u2mm(x1[i]), u2mm(y1[i]), u2mm(x2[i]), u2mm(y2[i]) ); sCommand += sInstruction; } // Set the right selection of layers to visible for further placement of components sprintf(sInstruction, "DISPLAY TOP BOTTOM PADS VIAS TPLACE BPLACE DIMENSION TNAMES BNAMES -TVALUES -BVALUES -UNROUTED -TDOCU -BDOCU __SignalWires;\n"); sCommand += sInstruction; // Reset the grid to the units it had before sprintf(sInstruction, "GRID LAST;\n"); sCommand += sInstruction; // Tranfer control back to EAGLE with the string of instructions built up so far exit(sCommand); } else dlgMessageBox("start this ULP in a Board", "OK");