ExpertWrap.mesa
Copyright Ó 1988 by Xerox Corporation. All rights reserved.
Christophe Cuenod October 3, 1988 3:04:14 pm PDT
Reads a set of .pcb .lib .pinlist and .keep files comming from expert and generates a .wrap file contening all the absolute information for the wirewrap machine. Removes from the nets the pins belonging to a part not mentionned inside the .keep file.
DIRECTORY
Commander USING [CommandProc, Register],
ExpertPCBRead USING [PCBTable, ReadPCBFile, Part],
ExpertLibRead USING [FirstPinOfThisType, LibTable, ReadLibFile, RelativePinPosition, PinPos, PinNumber],
ExpertPinRead USING [PinTable, PinInfo, ReadPinFile, PinInfoList],
ExpertKeepRead USING [RefDesTable, ReadKeepFile, KeepRefDes],
FS USING [Error, FileInfo, StreamOpen],
IO USING [card, Close, GetTokenRope, int, PutF, RIS, rope, STREAM],
Rope USING [Cat, Equal, ROPE],
SymTab USING [Create, EachPairAction, Insert, Pairs, Fetch, Store];
ExpertWrap: CEDAR PROGRAM
IMPORTS Commander, ExpertPCBRead, ExpertLibRead, ExpertPinRead, ExpertKeepRead, FS, IO, Rope, SymTab
~ BEGIN
PinPos: TYPE ~ ExpertLibRead.PinPos;
ROPE: TYPE ~ Rope.ROPE;
SplitPowerNet: PROC [prefix: ROPE, powerInfo: ExpertPinRead.PinInfoList] RETURNS [splitedTable: ExpertPinRead.PinTable] ~ {
pinList: ExpertPinRead.PinInfoList;
key: ROPE;
splitedTable ← SymTab.Create[];
FOR l: ExpertPinRead.PinInfoList ← powerInfo, l.rest UNTIL l = NIL DO
key ← Rope.Cat[prefix, ".", l.first.refDes];
pinList ← NIL;
IF SymTab.Fetch[splitedTable, key].found THEN {
pinList ← NARROW[SymTab.Fetch[splitedTable, key].val];
};
pinList ← CONS[l.first, pinList];
[] ← SymTab.Store[splitedTable, key, pinList];
ENDLOOP;
};
AbsolutePinPosition: PROC [libTable: ExpertLibRead.LibTable, part: ExpertPCBRead.Part, i: NAT] RETURNS [absolutePos: PinPos] ~ {
relativePos: PinPos ← ExpertLibRead.RelativePinPosition[libTable, part.libraryEntry, i];
SELECT part.orientation FROM
= 0 => {
absolutePos.x ← part.x + relativePos.x;
absolutePos.y ← part.y + relativePos.y;
};
= 90 => {
absolutePos.x ← part.x - relativePos.y;
absolutePos.y ← part.y + relativePos.x;
};
= 180 => {
absolutePos.x ← part.x - relativePos.x;
absolutePos.y ← part.y - relativePos.y;
};
= 270 => {
absolutePos.x ← part.x + relativePos.y;
absolutePos.y ← part.y - relativePos.x;
};
ENDCASE => ERROR;
};
ExpertWrapProc: Commander.CommandProc = BEGIN
TranslateAndScale: PROC [oldPos: PinPos] RETURNS [newPos: PinPos] ~ {
newPos.x ← (oldPos.x - origin.x)/100;
newPos.y ← (oldPos.y - origin.y)/100;
};
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;
};
}];
};
AddGndPin: SymTab.EachPairAction ~ {
pinInfo: ExpertPinRead.PinInfo;
pinInfoList: ExpertPinRead.PinInfoList ← NARROW[val];
refDes: ROPE ← pinInfoList.first.refDes;
part: ExpertPCBRead.Part ← NARROW[SymTab.Fetch[pCBTable, refDes].val];
libraryEntry: CARD ← part.libraryEntry;
gndPin: NAT ← ExpertLibRead.FirstPinOfThisType[libTable, libraryEntry, 5, 1];
IF gndPin = 0 THEN {
IO.PutF[cmd.out, "Part %g has no gnd pin defined\n", IO.rope[refDes]];
RETURN;
};
pinInfo.refDes ← refDes;
pinInfo.pinNumber ← gndPin;
pinInfo.symbolPinName ← "NoName";
pinInfo.pageNumber ← pinInfoList.first.pageNumber;
pinInfoList ← CONS[pinInfo, pinInfoList];
[] ← SymTab.Store[newGndPinTable, key, pinInfoList];
};
AddVccPin: SymTab.EachPairAction ~ {
pinInfo: ExpertPinRead.PinInfo;
pinInfoList: ExpertPinRead.PinInfoList ← NARROW[val];
refDes: ROPE ← pinInfoList.first.refDes;
part: ExpertPCBRead.Part ← NARROW[SymTab.Fetch[pCBTable, refDes].val];
libraryEntry: CARD ← part.libraryEntry;
vccPin: NAT ← ExpertLibRead.FirstPinOfThisType[libTable, libraryEntry, 4, 1];
IF vccPin = 0 THEN {
IO.PutF[cmd.out, "Part %g has no vcc pin defined\n", IO.rope[refDes]];
RETURN;
};
pinInfo.refDes ← refDes;
pinInfo.pinNumber ← vccPin;
pinInfo.symbolPinName ← "NoName";
pinInfo.pageNumber ← pinInfoList.first.pageNumber;
pinInfoList ← CONS[pinInfo, pinInfoList];
[] ← SymTab.Store[newVccPinTable, key, pinInfoList];
};
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 RETURN; -- Skip 0 or 1 pin net
SELECT TRUE FROM
Rope.Equal[key, "GND"] => gndInfoList ← pinInfoList;
Rope.Equal[key, "VCC"] => vccInfoList ← pinInfoList;
Rope.Equal[key, "-5.2"] => pinInfoList ← pinInfoList;
Rope.Equal[key, "V2"] => pinInfoList ← pinInfoList;
ENDCASE => [] ← SymTab.Insert[reducedPinTable, key, pinInfoList];
};
ComputeOrigin: SymTab.EachPairAction~ {
pos: PinPos;
part: ExpertPCBRead.Part ← NARROW[val];
IF NOT ExpertKeepRead.KeepRefDes[refDesTable, key] THEN RETURN;
FOR index: NAT IN [1..ExpertLibRead.PinNumber[libTable, part.libraryEntry]] DO
pos ← AbsolutePinPosition[libTable, part, index];
origin.x ← MIN[origin.x, pos.x];
origin.y ← MIN[origin.y, pos.y];
ENDLOOP;
};
WrapNets: SymTab.EachPairAction~ {
pos: PinPos;
part: ExpertPCBRead.Part;
netNumber ← netNumber + 1;
FOR l: ExpertPinRead.PinInfoList ← NARROW[val], l.rest UNTIL l = NIL DO
part ← NARROW[SymTab.Fetch[pCBTable, l.first.refDes].val];
IF part = NIL THEN {
IO.PutF[cmd.out, "The part for symbol %g is not inside the library.\n", IO.rope[l.first.refDes]];
ERROR;
};
pos ← TranslateAndScale[AbsolutePinPosition[libTable, part, l.first.pinNumber]];
outputLines ← outputLines + 1;
IO.PutF[out, "2 NET%04g X%03gY%03g",
IO.card[netNumber],
IO.int[pos.x],
IO.int[pos.y]
];
IO.PutF[out2, "2 NET%04g X%03gY%03g",
IO.card[netNumber],
IO.int[pos.x],
IO.int[pos.y]
];
IO.PutF[out, " page %2g %4g pin %3g %g\n",
IO.card[l.first.pageNumber],
IO.rope [l.first.refDes],
IO.card[l.first.pinNumber],
IO.rope[key]
];
IO.PutF[out2, " %g pin %g\n\012",
IO.rope [l.first.refDes],
IO.card[l.first.pinNumber]
];
ENDLOOP;
};
pCBTable: ExpertPCBRead.PCBTable;
libTable: ExpertLibRead.LibTable;
gndInfoList, vccInfoList: ExpertPinRead.PinInfoList;
pinTable, reducedPinTable, gndPinTable, vccPinTable, newGndPinTable, newVccPinTable: ExpertPinRead.PinTable;
refDesTable: ExpertKeepRead.RefDesTable;
out, out2: IO.STREAM;
origin: PinPos;
outputLines: CARD ← 0;
netNumber: CARD ← 0;
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"];
wrapFile: ROPE ← Rope.Cat[file, ".wrap"];
wrapFile2: ROPE ← Rope.Cat[file, ".wrap.IBM"];
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];
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"];
reducedPinTable ← SymTab.Create[];
[] ← SymTab.Pairs[pinTable, ReducePinList];
IO.PutF[cmd.out, "Spliting the gnd and vcc nets\n"];
gndPinTable ← SplitPowerNet["GND", gndInfoList];
vccPinTable ← SplitPowerNet["VCC", vccInfoList];
IO.PutF[cmd.out, "Adding a gnd or vcc pin on each splited power net\n"];
newGndPinTable ← SymTab.Create[];
[] ← SymTab.Pairs[gndPinTable, AddGndPin];
newVccPinTable ← SymTab.Create[];
[] ← SymTab.Pairs[vccPinTable, AddVccPin];
IO.PutF[cmd.out, "Computing the origin\n"];
origin.x ← 32000; -- Starts at the top right
origin.y ← 0;
[] ← SymTab.Pairs[pCBTable, ComputeOrigin];
IO.PutF[cmd.out, "Writing %g and %g\n", IO.rope[wrapFile], IO.rope[wrapFile2]];
out ← FS.StreamOpen[wrapFile, $create];
out2 ← FS.StreamOpen[wrapFile2, $create];
[] ← SymTab.Pairs[reducedPinTable, WrapNets];
IO.PutF[out, "*****\n"];
[] ← SymTab.Pairs[newGndPinTable, WrapNets];
IO.PutF[out, "*****\n"];
[] ← SymTab.Pairs[newVccPinTable, WrapNets];
IO.Close[out];
IO.Close[out2];
IO.PutF[cmd.out, "\nNumber of nets: %g\n", IO.card[netNumber]];
IO.PutF[cmd.out, "Number of wrap points: %g\n", IO.card[2*(outputLines-netNumber)]];
IO.PutF[cmd.out, "Number of wires: %g\n\n", IO.card[outputLines-netNumber]];
EXITS fail => result ← $Failed;
END;
Commander.Register[
key: "ExpertWrap", proc: ExpertWrapProc, doc: "Takes 4 expert files ( .pcb .lib .pinlist .keep) and generates a .wrap file.\n"];
END.