ExpertCompleteNetList.mesa
Copyright Ó 1989 by Xerox Corporation. All rights reserved.
Christophe Cuenod May 25, 1989 1:49:46 pm PDT
Reads a set of .pcb .lib .pinlist and .keep files comming from expert and generates a .netlist file contening all the netlist information to pass to another system. The VCC and GND net contains even the power pins defined inside the parts. Removes from the nets the pins belonging to a part not mentionned inside the .keep file.
DIRECTORY
Basics USING [CompareInt, Comparison],
Commander USING [CommandProc, Register],
ExpertPCBRead USING [PCBTable, ReadPCBFile, Part],
ExpertLibRead USING [IsPinOfThisType, LibTable, ReadLibFile, PinPos, PinNumber],
ExpertPinRead USING [PinTable, PinInfo, ReadPinFile, PinInfoList],
ExpertKeepRead USING [RefDesTable, ReadKeepFile, KeepRefDes],
FS USING [Error, FileInfo, StreamOpen],
IO USING [card, Close, GetTokenRope, PutF, RIS, rope, STREAM],
List USING [CompareProc, Comparison, LORA, Merge],
Rope USING [Cat, Compare, Equal, Fetch, Length, ROPE, Substr],
SymTab USING [Create, Delete, EachPairAction, Pairs, Fetch, Store];
ExpertCompleteNetList: CEDAR PROGRAM
IMPORTS Basics, Commander, ExpertPCBRead, ExpertLibRead, ExpertPinRead, ExpertKeepRead, FS, IO, List, Rope, SymTab
~ BEGIN
PinPos: TYPE ~ ExpertLibRead.PinPos;
ROPE: TYPE ~ Rope.ROPE;
Entry: TYPE = REF EntryRep;
EntryRep: TYPE = RECORD [
refDes: ROPE,
pinNumber: CARD
];
Compare: List.CompareProc ~ {
comp: List.Comparison;
x1, x2, mul: INT;
p1, p2: INT;
r1, r2: ROPE;
len1, len2: INT;
entry1: Entry ← NARROW[ref1];
entry2: Entry ← NARROW[ref2];
r1 ← entry1.refDes;
r2 ← entry2.refDes;
p1 ← entry1.pinNumber;
p2 ← entry2.pinNumber;
len1 ← Rope.Length[r1];
len2 ← Rope.Length[r2];
x1 ← 0;
mul ← 1;
WHILE len1 # 0 AND '0 <= Rope.Fetch[r1, len1-1] AND Rope.Fetch[r1, len1-1] <= '9 DO
x1 ← x1 + mul * (Rope.Fetch[r1, len1-1] - '0);
len1 ← len1 - 1;
mul ← mul * 10;
ENDLOOP;
x2 ← 0;
mul ← 1;
WHILE len2 # 0 AND '0 <= Rope.Fetch[r2, len2-1] AND Rope.Fetch[r2, len2-1] <= '9 DO
x2 ← x2 + mul * (Rope.Fetch[r2, len2-1] - '0);
len2 ← len2 - 1;
mul ← mul * 10;
ENDLOOP;
r1 ← Rope.Substr[r1, 0, len1];
r2 ← Rope.Substr[r2, 0, len2];
comp ← Rope.Compare[r1, r2, FALSE];
IF comp # equal THEN RETURN Rope.Compare[r1, r2, FALSE];
IF x1 # x2 THEN RETURN Basics.CompareInt[x1, x2];
RETURN Basics.CompareInt[p1, p2];
};
ExpertCompleteNetListProc: Commander.CommandProc = BEGIN
FileExistence: PROC [fileName: ROPE] RETURNS [found: BOOLEANTRUE] ~ {
[] ← FS.FileInfo[fileName ! FS.Error => {
IF error.group = user THEN {
IO.PutF[cmd.out, "%g\n", IO.rope[error.explanation]];
found ← FALSE;
CONTINUE;
};
}];
};
ReducePinList: SymTab.EachPairAction~ {
pinInfoList: ExpertPinRead.PinInfoList ← NIL;
FOR l: ExpertPinRead.PinInfoList ← NARROW[val], l.rest UNTIL l = NIL DO
IF ExpertKeepRead.KeepRefDes[refDesTable, l.first.refDes] THEN {
pinInfoList ← CONS[l.first, pinInfoList];
};
ENDLOOP;
IF pinInfoList = NIL OR pinInfoList.rest = NIL THEN {
[] ← SymTab.Delete[pinTable, key];  -- Skip 0 or 1 pin net
}
ELSE [] ← SymTab.Store[pinTable, key, pinInfoList];
};
AddImplicitPins: SymTab.EachPairAction ~ {
part: ExpertPCBRead.Part;
libraryEntry: CARD;
pinNumber: NAT;
pinInfoList: ExpertPinRead.PinInfoList;
pinInfo: ExpertPinRead.PinInfo;
IF ExpertKeepRead.KeepRefDes[refDesTable, key] AND NOT Rope.Equal[key, "P1"]
AND NOT Rope.Equal[key, "G1"]THEN {
part ← NARROW[val];
libraryEntry ← part.libraryEntry;
pinNumber ← ExpertLibRead.PinNumber[libTable, libraryEntry];
FOR pinIndex: NAT IN [1.. pinNumber] DO
A ground pin is of type 5 swap 1
IF ExpertLibRead.IsPinOfThisType[libTable, libraryEntry, pinIndex, 5, 1] THEN {
pinInfo.refDes ← key;
pinInfo.pinNumber ← pinIndex;
pinInfo.symbolPinName ← "GND";
pinInfo.pageNumber ← 0;
pinInfoList ← NIL;
IF SymTab.Fetch[pinTable, "GND"].found THEN {
pinInfoList ← NARROW[SymTab.Fetch[pinTable, "GND"].val];
};
pinInfoList ← CONS[pinInfo, pinInfoList];
[] ← SymTab.Store[pinTable, "GND", pinInfoList];
pinInfoList ← NIL;
IF SymTab.Fetch[impliedPinTable, "GND"].found THEN {
pinInfoList ← NARROW[SymTab.Fetch[impliedPinTable, "GND"].val];
};
pinInfoList ← CONS[pinInfo, pinInfoList];
[] ← SymTab.Store[impliedPinTable, "GND", pinInfoList];
};
A vcc pin is of type 4 swap 1
IF ExpertLibRead.IsPinOfThisType[libTable, libraryEntry, pinIndex, 4, 1] THEN {
pinInfo.refDes ← key;
pinInfo.pinNumber ← pinIndex;
pinInfo.symbolPinName ← "VCC";
pinInfo.pageNumber ← 0;
pinInfoList ← NIL;
IF SymTab.Fetch[pinTable, "VCC"].found THEN {
pinInfoList ← NARROW[SymTab.Fetch[pinTable, "VCC"].val];
};
pinInfoList ← CONS[pinInfo, pinInfoList];
[] ← SymTab.Store[pinTable, "VCC", pinInfoList];
pinInfoList ← NIL;
IF SymTab.Fetch[impliedPinTable, "VCC"].found THEN {
pinInfoList ← NARROW[SymTab.Fetch[impliedPinTable, "VCC"].val];
};
pinInfoList ← CONS[pinInfo, pinInfoList];
[] ← SymTab.Store[impliedPinTable, "VCC", pinInfoList];
};
ENDLOOP;
};
};
CompleteNetList: SymTab.EachPairAction ~ {
i: CARD ← 0;
netNumber ← netNumber + 1;
IO.PutF[out, "\nNN %g ", IO.card[netNumber]];
IO.PutF[out2, "\n\012NN %g ", IO.card[netNumber]];
IO.PutF[out3, "NN %g ", IO.card[netNumber]];
FOR l: ExpertPinRead.PinInfoList ← NARROW[val], l.rest UNTIL l = NIL DO
IF (i MOD 5) = 0 THEN {
IO.PutF[out, "$\n"];
IO.PutF[out2, "$\n\012"];
};
i ← i + 1;
IO.PutF[out, "%-4g %-4g ",
IO.rope[l.first.refDes],
IO.card[l.first.pinNumber]
];
IO.PutF[out2, "%-4g %-4g ",
IO.rope[l.first.refDes],
IO.card[l.first.pinNumber]
];
IO.PutF[out3, "%-4g %-4g $\n",
IO.rope[l.first.refDes],
IO.card[l.first.pinNumber]
];
ENDLOOP;
};
ImpliedNetList: SymTab.EachPairAction ~ {
i: CARD ← 0;
lora, lora1, lora2: List.LORA;
l1: ExpertPinRead.PinInfoList;
l1 ← NIL;
FOR l: ExpertPinRead.PinInfoList ← NARROW[val], l.rest UNTIL l = NIL DO
l1 ← CONS[l.first, l1];
ENDLOOP;
lora ← NIL;
FOR l: ExpertPinRead.PinInfoList ← NARROW[val], l.rest UNTIL l = NIL DO
entry: Entry ← NEW[EntryRep];
entry.refDes ← l.first.refDes;
entry.pinNumber ← l.first.pinNumber;
lora1 ← CONS[entry, NIL];
lora2 ← List.Merge[lora, lora1, Compare];
lora ← lora2;
ENDLOOP;
IO.PutF[out4, "\n\n%g ", IO.rope[key]];
FOR l: List.LORA ← lora, l.rest UNTIL l = NIL DO
entry: Entry ← NARROW[l.first];
IF (i MOD 5) = 0 THEN {
IO.PutF[out4, "$\n"];
};
i ← i + 1;
IO.PutF[out4, "%-4g %-4g ",
IO.rope[entry.refDes],
IO.card[entry.pinNumber]
];
ENDLOOP;
};
netNumber: CARD;
pCBTable: ExpertPCBRead.PCBTable;
libTable: ExpertLibRead.LibTable;
pinTable, impliedPinTable: ExpertPinRead.PinTable;
refDesTable: ExpertKeepRead.RefDesTable;
out, out2, out3, out4: IO.STREAM;
stream: IO.STREAMIO.RIS[cmd.commandLine];
file: ROPEIO.GetTokenRope[stream].token;
pcbFile: ROPE ← Rope.Cat[file, ".pcb"];
libFile: ROPE ← Rope.Cat[file, ".lib"];
pinListFile: ROPE ← Rope.Cat[file, ".pinlist"];
keepFile: ROPE ← Rope.Cat[file, ".keep"];
netListFile: ROPE ← Rope.Cat[file, ".netlist"];
netListFile2: ROPE ← Rope.Cat[file, ".netlist2"];
netListFile3: ROPE ← Rope.Cat[file, ".netlist3"];
impliedNetListFile: ROPE ← Rope.Cat[file, ".impliedNetlist"];
found: BOOLEAN ← FileExistence[pcbFile];
found ← FileExistence[libFile] AND found;
found ← FileExistence[pinListFile] AND found;
found ← FileExistence[keepFile] AND found;
IF NOT found THEN GO TO fail;
IO.PutF[cmd.out, "Reading %g\n", IO.rope[pcbFile]];
pCBTable ← ExpertPCBRead.ReadPCBFile[pcbFile];
IO.PutF[cmd.out, "Reading %g\n", IO.rope[libFile]];
libTable ← ExpertLibRead.ReadLibFile[libFile];
IO.PutF[cmd.out, "Reading %g\n", IO.rope[pinListFile]];
pinTable ← ExpertPinRead.ReadPinFile[pinListFile];
impliedPinTable ← SymTab.Create[];
IO.PutF[cmd.out, "Reading %g\n", IO.rope[keepFile]];
refDesTable ← ExpertKeepRead.ReadKeepFile[keepFile];
IO.PutF[cmd.out, "Reducing the pin list (removing the unwanted parts)\n"];
[] ← SymTab.Pairs[pinTable, ReducePinList];
IO.PutF[cmd.out, "Adding the VCC and GND pins appearing only on the parts\n"];
[] ← SymTab.Pairs[pCBTable, AddImplicitPins];
IO.PutF[cmd.out, "Writing %g, %g, %g and %g\n", IO.rope[netListFile], IO.rope[netListFile2], IO.rope[netListFile3], IO.rope[impliedNetListFile]];
out ← FS.StreamOpen[netListFile, $create];
out2 ← FS.StreamOpen[netListFile2, $create];
out3 ← FS.StreamOpen[netListFile3, $create];
out4 ← FS.StreamOpen[impliedNetListFile, $create];
IO.PutF[out, "NET LIST"];
IO.PutF[out2, "NET LIST"];
IO.PutF[out3, "NET LIST\n"];
IO.PutF[out4, "NET LIST reduced to the implied VCC and GND nets\n"];
netNumber ← 1000; -- net numbering starts at 1001
[] ← SymTab.Pairs[pinTable, CompleteNetList];
[] ← SymTab.Pairs[impliedPinTable, ImpliedNetList];
IO.PutF[out, "\n"];
IO.PutF[out2, "\n\012"];
IO.PutF[out4, "\n"];
IO.Close[out];
IO.Close[out2];
IO.Close[out3];
IO.Close[out4];
EXITS fail => result ← $Failed;
END;
Commander.Register[
key: "ExpertCompleteNetList", proc: ExpertCompleteNetListProc, doc: "Takes 4 expert files ( .pcb .lib .pinlist .keep) and generates .netlist .netlist2 and netlist3 files.\n"];
END.