<> <> <> <<>> <<>> <> <<>> 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: BOOLEAN _ TRUE] ~ { [] _ 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 <> 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]; }; <<>> <> 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; <> <> <> <> <> <<>> 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.STREAM _ IO.RIS[cmd.commandLine]; file: ROPE _ IO.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.