#usage "Netzverweise\n"
"
"
"Markierung von Netzenden mit I,O und IO - "
"Verweis auf gleiche Netznamen durch Angabe der Schaltplanseite."
"
"
"Autor: Andreas Funcke"
// THIS PROGRAM IS PROVIDED AS IS AND WITHOUT WARRANTY OF ANY KIND, EXPRESSED OR IMPLIED
//---- edit the following default values to your liking ------------------------
int layer_nr = 111; // number of the new layer
string layer_name = "NETLINKS"; // name of the new layer
int text_size = 70; // mil
int text_ratio = 8; // %
int text_distance = 20; // distance from net in mil
int text_font = 1; // 0=Vector 1=Proportional 2=Fixed
int link_same_sheets = 1; // 1 for yes, 0 for no
int link_with_direction = 1; // 1 for yes, 0 for no
int link_with_name_net = 0; // 1 for yes, 0 for no
int link_with_name_bus = 0; // 1 for yes, 0 for no
int link_with_brackets = 0; // 1 for yes, 0 for no
int auto_execute_script = 1; // 1 for yes, 0 for no
////////////////////////////////////////////////////////////////////////////////
// !!! do not edit anything below !!!
////////////////////////////////////////////////////////////////////////////////
string version_num = "1.6";
string version_date = "28.10.2002";
// Deutsche Anleitung:
string dHelp = ""
"Version " + version_num + " (" + version_date + ")
"
"Funktion des ULPs:
"
"Markierung von Netzenden mit I ,O und IO - "
"Verweis auf gleiche Netz- und Busnamen durch Angabe der Schaltplanseite."
"Für die Konfiguration stehen verschiedene Variablen zur Verfügung, "
"die entweder in der DialogBox oder dauerhaft im ULP verändert werden können.
"
"Hier ein Auszug aus dem ULPs:
"
"//---- edit the following default values to your liking ------------------------
"
"int layer_nr = 111; // number of the new layer
"
"string layer_name = \"NETLINKS\"; // name of the new layer
"
"int text_size = 70; // mil
"
"int text_ratio = 8; // %
"
"int text_distance = 20; // distance from net in mil
"
"int text_font = 1; // 0=Vector 1=Proportional 2=Fixed
"
"int link_same_sheets = 1; // 1 for yes, 0 for no
"
"int link_with_direction = 1; // 1 for yes, 0 for no
"
"int link_with_name_net = 0; // 1 for yes, 0 for no
"
"int link_with_name_bus = 0; // 1 for yes, 0 for no
"
"int link_with_brackets = 0; // 1 for yes, 0 for no
"
"int auto_execute_script = 1; // 1 for yes, 0 for no
"
"Es ist auch möglich das ULP über die Befehlszeile zu konfigurieren:
"
"run netlinks_v16 111 NETLINKS 70 8 20 1 1 1 0 0 0 1
"
"Falls das ULP jedoch eine INI-Datei findet werden die Optionen aus
"
"dieser Datei entnommen. Somit hat die INI-Datei die höhere Priorität.
"
"Erklärung der einzelnen Konfigurationsmöglichkeiten:
"
"layer_nr, layer_name:
"
"Für die Erstellung der \"Links\" wird ein zusätzlicher
"
"Layer eingefügt, mit der entsprechenden Layer-Nummer
"
"und entsprechendem Layer-Namen
"
"text_size, text_ratio, text_distance, text_font:
"
"Einstellung der Textoptionen für die einzufügenden \"Links\"
"
"link_same_sheets:
"
"Wenn Wert auf 1 gesetzt ist, wird bei zwei verschiedenen
"
"Segmenten mit dem gleichen Namen auf einer Seite, die Seite
"
"auch angegeben
"
"link_with_direction:
"
"Wenn Wert auf 1 gesetzt ist, wird die Richtung des Netzes oder
"
"des Busses angegeben (<<, >>, <<>>).
"
"link_with_name_net und link_with_name_bus:
"
"Wenn Wert auf 1 gesetzt ist, wird zusätzlich zu den Seitennummern
"
"der Name des Netzes (link_with_name_net) oder Busses
"
"(link_with_name_bus) angegeben.
"
"link_with_brackets:
"
"Wenn Wert auf 1 gesetzt ist, werden die zu einem Netz oder Bus
"
"zugehörigen Seitennummern in eckigen Klammern gesetzt ([]).
"
"auto_execute_script:
"
"Wenn Wert auf 1 gesetzt ist, wird das erstellte Script automatisch
"
"nach Ende des ULPs ausgeführt."
"
";
string Fonts[] = { "Vector", "Proportional", "Fixed" };
// global variables
string netsheets[];
string netnames[];
int number_of_nets;
int number_of_sheets;
string busnames[];
string busnetnames[];
int number_of_busses;
int start_time;
string status_ulp = "Ready";
string status_number_of_nets = "-";
string status_number_of_busses = "-";
string status_sheets = "-";
// delete the NETLINKS-Layer
void delete_all_text (UL_SCHEMATIC S)
{
S.sheets(SH) {
printf("EDIT .S%d;\n", SH.number);
SH.texts(T)
if (T.layer == layer_nr)
printf("delete (%5.3f %5.3f);\n", u2mil(T.x), u2mil(T.y));
}
}
// check if the net has no conntact
int is_XY_alone_on_segment(UL_SEGMENT SEG, int cnt, int X, int Y) {
int wire_cnt=0;
SEG.wires(W) {
wire_cnt++;
if (wire_cnt != cnt)
if ( (W.x1==X && W.y1==Y) || (W.x2==X && W.y2==Y) )
return 0;
}
SEG.junctions(J)
if (J.x==X && J.y==Y)
return 0;
SEG.pinrefs(P)
if (P.pin.x==X && P.pin.y==Y)
return 0;
return 1;
}
// add link at the left side
string get_left_link(string link, string name, int direction) {
if (name != "")
name = " " + name;
if (!link_with_direction)
direction = 0;
if (link_with_brackets)
link = "[" + link + "]";
switch (direction) {
case 1: link = link + name + " >>"; break;
case 2: link = link + name + " <<"; break;
case 3: link = link + name + " <<>>"; break;
default: link = link + name;
}
return link;
}
// add link at the right side
string get_right_link(string link, string name, int direction) {
if (name != "")
name = name + " ";
if (!link_with_direction)
direction = 0;
if (link_with_brackets)
link = "[" + link + "]";
switch (direction) {
case 1: link = "<< " + name + link; break;
case 2: link = ">> " + name + link; break;
case 3: link = "<<>> " + name + link; break;
default: link = name + link;
}
return link;
}
// mark the net with text (direction and sheetnumbers)
void mark_open_nets(string link, string name, int direction, int x1, int y1, int x2, int y2) {
real angle;
real x = u2mil(x1);
real y = u2mil(y1);
if (y1 == y2) {
if (x1 < x2) {
angle = 180;
x = x - text_distance;
y = y + text_size/2;
link = get_left_link(link, name, direction);
}
else {
angle = 0;
x = x + text_distance;
y = y - text_size/2;
link = get_right_link(link, name, direction);
}
}
else {
if (x1 == x2) {
if (y1 < y2) {
angle = 270;
x = x - text_size/2;
y = y - text_distance;
link = get_left_link(link, name, direction);
}
else {
angle = 90;
x = x + text_size/2;
y = y + text_distance;
link = get_right_link(link, name, direction);
}
}
else {
// bus-connection - do not mark
return;
}
}
if (link != "")
printf("text '%s' R%1.0f (%5.3f %5.3f);\n", link, angle, x, y);
}
// check if segment is I,O or IO
int get_direction_of_segment(UL_SEGMENT SEG) {
int I_O_IO=0; // nothing=0, I=1, O=2, IO=3
SEG.pinrefs(P) {
if ( (P.pin.direction == PIN_DIRECTION_OUT)
|| (P.pin.direction == PIN_DIRECTION_OC)
|| (P.pin.direction == PIN_DIRECTION_HIZ) ) {
I_O_IO = 2;
break;
}
else
if ( (P.pin.direction == PIN_DIRECTION_IO)
|| (P.pin.direction == PIN_DIRECTION_NC)
|| (P.pin.direction == PIN_DIRECTION_PAS) )
I_O_IO = 3;
else
if ( (I_O_IO == 0) && (P.pin.direction == PIN_DIRECTION_IN) )
I_O_IO = 1;
}
return I_O_IO;
}
// look for the coresponding index in netnames
int get_netname_index(string netname) {
for (int i=0; i 0)
if (link_same_sheets || number_of_sheet!=i)
if (number_of_sheet!=i || netsheets[index][i] > 1) {
sprintf(dummy,"%d",i);
link += dummy;
link += ",";
}
// clear last ','
link = strsub(link,0,strlen(link)-1);
return link;
}
// create buslink with number of sheets
string create_buslink(int index, int sch_number) {
string link="";
int i,j;
string bus_sheet;
string dummy;
for (i=0; i<=number_of_sheets; i++)
bus_sheet[i] = 0;
for (i=0; i bus_sheet[j])
bus_sheet[j] = netsheets[i][j];
for (i=1; i<=number_of_sheets; i++)
if (bus_sheet[i] > 0)
if (link_same_sheets || sch_number!=i)
if (sch_number!=i || bus_sheet[i] > 1) {
sprintf(dummy,"%d",i);
link += dummy;
link += ",";
}
// clear last ','
link = strsub(link,0,strlen(link)-1);
return link;
}
// fill array netnames and array netsheets
void fill_netnames_and_netsheets(UL_SCHEMATIC S) {
int index;
number_of_sheets = 0;
number_of_nets = 0;
// count number of sheets
S.sheets(SCH)
number_of_sheets++;
// count number of nets and fill netnames
S.nets(N)
netnames[number_of_nets++] = N.name;
// clear netsheets
for (int i=0; i= 0)
bus_name = strsub(bus_name, pos+1);
n = strsplit(arr, bus_name, ','); // split bus_name to array
cnt=0;
for(i=0; i= 0) {
name = strsub(arr[i],0,pos1);
pos2 = strchr(arr[i],'.');
pos1 += 1;
dummy = strsub(arr[i],pos1,pos2-pos1);
start = strtol(dummy);
pos1 = pos2 + 2;
pos2 = strchr(arr[i],']');
dummy = strsub(arr[i],pos1,pos2-pos1);
end = strtol(dummy);
for(j=start;j<=end;j++) {
sprintf(dummy,"%d",j);
busnetnames[cnt++]=name+dummy;
}
}
else
busnetnames[cnt++]=arr[i];
}
return cnt;
}
// tie the busses with the netsheets
void tie_busses_to_netsheets(UL_SCHEMATIC S) {
int n;
int i,j;
int index;
number_of_busses = 0;
S.sheets(SCH)
SCH.busses(B) {
if (get_busname_index(B.name) == -1) {
busnames[number_of_busses++] = B.name;
n = extract_netnames_from_bus(B.name);
for(i=0; i= by1 && SW.y1 <= by2)
||(SW.x2 == BW.x1 && SW.y2 >= by1 && SW.y2 <= by2) )
return 1;
}
}
else {
// wire in x direction
if (BW.x1 < BW.x2) {
bx1 = BW.x1;
bx2 = BW.x2;
}
else {
bx1 = BW.x2;
bx2 = BW.x1;
}
SEG.wires(SW) {
if ( (SW.y1 == BW.y1 && SW.x1 >= bx1 && SW.x1 <= bx2)
||(SW.y2 == BW.y1 && SW.x2 >= bx1 && SW.x2 <= bx2) )
return 1;
}
}
}
return 0;
}
// check the direction of the bus
int get_direction_of_bus(int index, UL_SEGMENT BUS_SEG, UL_SHEET SCH) {
int I_O_IO=0; // nothing=0, I=1, O=2, IO=3
int i,n,direction;
n = extract_netnames_from_bus(busnames[index]);
for(i=0; i= 0)
name = strsub(busnames[index], 0, pos);
else
name = busnames[index];
}
else
name = "";
mark_open_nets(text, name, direction, W.x1, W.y1, W.x2, W.y2);
}
if (is_XY_alone_on_segment(SEG, cnt, W.x2, W.y2))
if (is_XY_bus_alone(SCH, W.x2, W.y2)) {
index = get_busname_index(B.name);
direction = get_direction_of_bus(index, SEG, SCH);
text = create_buslink(index, SCH.number);
if (link_with_name_bus) {
// cut synonym
pos = strchr(busnames[index], ':');
if (pos >= 0)
name = strsub(busnames[index], 0, pos);
else
name = busnames[index];
}
else
name = "";
mark_open_nets(text, name, direction, W.x2, W.y2, W.x1, W.y1);
}
} // wires
} // segments
} // sheets
// back to first sheet
printf("EDIT .S1;\n");
// last grid and layers
printf("grid last\n");
printf("display all -Pins\n");
end_time=time()-start_time;
printf("\n");
printf("# This file is generated by %s %s, exported from;\n", filename(argv[0]), version_num);
printf("# %s at %s;\n", S.name, t2string(end_time));
printf("# time delay: %dm %ds\n", t2minute(end_time), t2second(end_time));
printf("# %s;\n\n", EAGLE_SIGNATURE);
} // output
// save options to file
fileName = filesetext(S.name, "_netlinks.ini");
output(fileName, "wt") {
printf("# INI-File for netlinks ULP\n");
printf("# This file is generated by %s\n", filename(argv[0]));
printf("%d\n", layer_nr); // number of the new layer
printf("%s\n", layer_name); // name of the new layer
printf("%d\n", text_size); // mil
printf("%d\n", text_ratio); // %
printf("%d\n", text_distance); // distance from net in mil
printf("%d\n", text_font); // 0=Vector 1=Proportional 2=Fixed
printf("%d\n", link_same_sheets); // 1 for yes, 0 for no
printf("%d\n", link_with_direction); // 1 for yes, 0 for no
printf("%d\n", link_with_name_net); // 1 for yes, 0 for no
printf("%d\n", link_with_name_bus); // 1 for yes, 0 for no
printf("%d\n", link_with_brackets); // 1 for yes, 0 for no
printf("%d\n", auto_execute_script); // 1 for yes, 0 for no
printf("# End of INI-File\n");
}
status_ulp = "Finished";
dlgRedisplay();
if (auto_execute_script) {
// execute script after ULP
fileName = filesetext(S.name, "_netlinks.scr");
sprintf(cmd, "script '%s'", fileName);
exit(cmd);
}
else
dlgMessageBox("Netlinks finished!", "&OK");
exit(0);
} // schematic
}
// Display Help-Text
void DisplayHelp(void)
{
dlgDialog("Netlinks Hilfe") {
dlgHBoxLayout dlgSpacing(400);
dlgHBoxLayout {
dlgVBoxLayout dlgSpacing(300);
dlgTextView(dHelp);
}
dlgHBoxLayout {
dlgStretch(1);
dlgPushButton("&Close") dlgReject();
}
};
}
// Display Dialog
void DisplayDialog(void) {
int Result = dlgDialog("Netlinks V" + version_num) {
dlgHBoxLayout {
dlgVBoxLayout {
dlgGroup("Layer") {
dlgGridLayout {
dlgCell(0,0) dlgLabel("&Name: ");
dlgCell(0,1) dlgStringEdit(layer_name);
dlgCell(1,0) dlgLabel("N&umber: ");
dlgCell(1,1) dlgIntEdit(layer_nr, 100, 254);
}
}
dlgGroup("Links") {
dlgCheckBox("Sa&me Sheets",link_same_sheets);
dlgCheckBox("With Direc&tion",link_with_direction);
dlgCheckBox("With Name for &Net",link_with_name_net);
dlgCheckBox("With Name for &Bus",link_with_name_bus);
dlgCheckBox("With Bra&ckets []", link_with_brackets);
}
}
dlgVBoxLayout {
dlgGroup("Text") {
dlgGridLayout {
dlgCell(0,0) dlgLabel("S&ize: ");
dlgCell(0,1) dlgSpinBox(text_size, 10, 100);
dlgCell(0,2) dlgLabel(" mil");
dlgCell(1,0) dlgLabel("&Ratio: ");
dlgCell(1,1) dlgSpinBox(text_ratio, 0, 30);
dlgCell(1,2) dlgLabel(" %");
dlgCell(2,0) dlgLabel("&Distance: ");
dlgCell(2,1) dlgSpinBox(text_distance, 0, 1000);
dlgCell(2,2) dlgLabel(" mil");
dlgCell(3,0) dlgLabel("&Font-Name: ");
dlgCell(3,1) dlgComboBox(Fonts, text_font);
}
}
dlgGroup("Script") {
dlgSpacing(15);
dlgCheckBox("&Auto Execute",auto_execute_script);
}
}
}
dlgSpacing(15);
dlgHBoxLayout {
dlgGroup("Status") {
dlgGridLayout {
dlgCell(0,0) dlgLabel(status_ulp, 1);
dlgCell(0,1) dlgLabel(" ");
dlgCell(0,2) dlgLabel("Nets: ");
dlgCell(0,3) dlgLabel(status_number_of_nets, 1);
dlgCell(0,4) dlgLabel("Busses: ");
dlgCell(0,5) dlgLabel(status_number_of_busses, 1);
dlgCell(0,6) dlgLabel("Sheet: ");
dlgCell(0,7) dlgLabel(status_sheets, 1);
}
}
}
dlgSpacing(15);
dlgHBoxLayout {
dlgPushButton("+&Start") { status_ulp = "Running...";
dlgRedisplay();
start(); }
dlgPushButton("-&Quit") dlgReject();
dlgSpacing(30);
dlgPushButton("&Help") DisplayHelp();
}
};
if (!Result) exit(-1);
}
////////////////////////////////////////////////////////////////////////////////
// main
////////////////////////////////////////////////////////////////////////////////
void main(void) {
string lines[];
string fileName;
string a[];
int nLines;
if (!schematic) {
dlgMessageBox("This program can only work in the schematic editor.", "OK");
exit (0);
}
if (!argv[1]) {
// check for INI-File
schematic(S) { fileName = filesetext(S.name, "_netlinks.ini"); }
if (fileglob(a, fileName)) {
// get options from INI-File
nLines = fileread(lines, fileName);
layer_nr = strtol(lines[2]); // number of the new layer
layer_name = lines[3]; // name of the new layer
text_size = strtol(lines[4]); // mil
text_ratio = strtol(lines[5]); // %
text_distance = strtol(lines[6]); // distance from net in mil
text_font = strtol(lines[7]); // 0=Vector 1=Proportional 2=Fixed
link_same_sheets = strtol(lines[8]); // 1 for yes, 0 for no
link_with_direction = strtol(lines[9]); // 1 for yes, 0 for no
link_with_name_net = strtol(lines[10]); // 1 for yes, 0 for no
link_with_name_bus = strtol(lines[11]); // 1 for yes, 0 for no
link_with_brackets = strtol(lines[12]); // 1 for yes, 0 for no
auto_execute_script = strtol(lines[13]); // 1 for yes, 0 for no
}
DisplayDialog();
}
else {
// get options from command line
layer_nr = strtol(argv[1]); // number of the new layer
layer_name = argv[2]; // name of the new layer
text_size = strtol(argv[3]); // mil
text_ratio = strtol(argv[4]); // %
text_distance = strtol(argv[5]); // distance from net in mil
text_font = strtol(argv[6]); // 0=Vector 1=Proportional 2=Fixed
link_same_sheets = strtol(argv[7]); // 1 for yes, 0 for no
link_with_direction = strtol(argv[8]); // 1 for yes, 0 for no
link_with_name_net = strtol(argv[9]); // 1 for yes, 0 for no
link_with_name_bus = strtol(argv[10]); // 1 for yes, 0 for no
link_with_brackets = strtol(argv[11]); // 1 for yes, 0 for no
auto_execute_script = strtol(argv[12]); // 1 for yes, 0 for no
DisplayDialog();
}
}