File: Pga300.mesa
Christophe Cuenod December 11, 1987 4:27:22 pm PST

Enables to generate easily 300 pins PGA parts for EXPERT.
Requires 4 input files: Filename.left, Filename.top, Filename.right, Filename.bottom and generates files:
Filename.top.part, Filename.bottom.part
Filename.inner.part and Filename.outer.part
Filename.sides.part and Filename.center.part
(to be transformed by the NewPart program).
Each file has to be iCSideSize lines long exactly. Each line has to content either NC or PinName PinType (I, O, D, ...) and SwapNumber. (i.e. K5 D 5)
The pads stacks are:
- nul pin   stack 11
- pin 1   stack 28
- power or gnd  stack 30
- corners   stack 31
- remaining  stack 29
DIRECTORY
Commander USING [CommandProc, Register],
Rope USING [ROPE, Equal, Find, Length, Cat, Substr],
FS USING [StreamOpen],
IO USING [ card, Close, EndOfStream, GetTokenRope, int, PutF, PutRope, RIS, rope, STREAM];
Pga300: CEDAR PROGRAM
IMPORTS IO, Commander, Rope, FS =
BEGIN
ROPE: TYPE = Rope.ROPE;
SideRep: TYPE = ARRAY[0..iCSideSize) OF RECORD[
x: INTEGER,
y: INTEGER
];
Side: TYPE = REF SideRep;
PGAPinsRep: TYPE = ARRAY[1..pGASideSize] OF ARRAY[1..pGASideSize] OF ROPE;
PGAPins: TYPE = REF PGAPinsRep;
iCSideSize: CARD ~ 67;
pGASideSize: CARD ~ 20;
pGARows: CARD ~ 5;
BadFile: SIGNAL [];
GetLine: PROC [in: IO.STREAM, display: IO.STREAM, i: CARD, file: ROPE] RETURNS [line: ROPE] ~ {
firstToken, secondToken, thirdToken: ROPE;
firstToken ← IO.GetTokenRope[in ! IO.EndOfStream => CONTINUE].token;
IF Rope.Equal[firstToken, "NC", FALSE] THEN {
line ← firstToken;
}
ELSE {
secondToken ← IO.GetTokenRope[in ! IO.EndOfStream => CONTINUE].token;
thirdToken ← IO.GetTokenRope[in ! IO.EndOfStream => CONTINUE].token;
IF firstToken = NIL OR secondToken = NIL OR thirdToken = NIL THEN {
IO.PutF[display, "File %g is too short: line %g is missing or incomplete.\n",
IO.rope[file], IO.card[i+1]];
SIGNAL BadFile[];
};
IF NOT(Rope.Equal[secondToken, "I", FALSE] OR Rope.Equal[secondToken, "O", FALSE]
OR Rope.Equal[secondToken, "D", FALSE]) THEN {
IO.PutF[display, "File %g line %g second word has to be I,O or D instead of %g\n",
IO.rope[file], IO.card[i+1], IO.rope[secondToken]];
SIGNAL BadFile[];
};
line ← Rope.Cat[firstToken, " ", secondToken];
line ← Rope.Cat[line, " ", thirdToken];
};
};
InsertPin: PROC [x: CARD, y: CARD, dx: INT, dy: INT, pga: PGAPins, out: IO.STREAM] ~ {
name, type, swap: ROPE;
pos1, pos2, pad: INT;
IO.PutF[out, "%g %g ", IO.int[100*(x-dx-1)], IO.int[100*(y-dy-1)]];
IF Rope.Equal[pga[x][y], "NC"] THEN IO.PutF[out, "NC 1 19 256 0 "]
ELSE IF Rope.Equal[pga[x][y], "GND"] THEN IO.PutF[out, "GND 1 19 256 5 "]
ELSE IF Rope.Equal[pga[x][y], "VCC"] THEN IO.PutF[out, "VCC 1 19 256 4 "]
ELSE {
pos1 ← Rope.Find[pga[x][y], " ", 0, TRUE];
pos2 ← Rope.Find[pga[x][y], " ", pos1+1, TRUE];
name ← Rope.Substr[pga[x][y], 0, pos1];
type ← Rope.Substr[pga[x][y], pos1+1, pos2-pos1-1];
swap ← Rope.Substr[pga[x][y], pos2+1, Rope.Length[pga[x][y]]-pos2-1];
IO.PutF[out, "%g ",IO.rope[name]];
IO.PutF[out, "%g 19 1 ",IO.rope[swap]];
IF Rope.Equal[type, "I", FALSE] THEN IO.PutF[out, "1 "];
IF Rope.Equal[type, "O", FALSE] THEN IO.PutF[out, "2 "];
IF Rope.Equal[type, "D", FALSE] THEN IO.PutF[out, "3 "];
};
pad ← 29;
IF x = 1 AND y = 1 THEN pad ← 28;
IF x = 1 AND y = pGASideSize THEN pad ← 31;
IF x = pGASideSize AND y = 1 THEN pad ← 31;
IF x = pGASideSize AND y = pGASideSize THEN pad ← 31;
IF Rope.Equal[pga[x][y], "GND"] THEN pad ← 30;
IF Rope.Equal[pga[x][y], "VCC"] THEN pad ← 30;
IO.PutF[out, "%g\n", IO.int[pad]];
};
Pga300Proc: Commander.CommandProc = BEGIN
i: CARD;
x, y: CARD;
in: IO.STREAM;
out: IO.STREAM;
fault: BOOLEANFALSE;
stream: IO.STREAMIO.RIS[cmd.commandLine];
fileName: ROPEIO.GetTokenRope[stream].token;
top: Side ← NEW[SideRep];
bottom: Side ← NEW[SideRep];
left: Side ← NEW[SideRep];
right: Side ← NEW[SideRep];
pga: PGAPins ← NEW[PGAPinsRep];
top[0] ← [4,4];
top[1] ← [3,2];
top[2] ← [4,3];
top[3] ← [5,4];
top[4] ← [2,2];
top[5] ← [6,5];
top[6] ← [2,1];
top[7] ← [4,2];
top[8] ← [5,3];
top[9] ← [6,4];
top[10] ← [3,1];
top[11] ← [4,1];
top[12] ← [5,2];
top[13] ← [6,3];
top[14] ← [7,4];
top[15] ← [5,1];
top[16] ← [6,2];
top[17] ← [7,3];
top[18] ← [6,1];
top[19] ← [7,2];
top[20] ← [8,4];
top[21] ← [7,1];
top[22] ← [8,3];
top[23] ← [8,2];
top[24] ← [8,1];
top[25] ← [9,4];
top[26] ← [9,3];
top[27] ← [9,2];
top[28] ← [9,1];
top[29] ← [10,1];
top[30] ← [10,4];
top[31] ← [10,3];
top[32] ← [10,2];
top[33] ← [11,2];
top[34] ← [11,3];
top[35] ← [11,4];
top[36] ← [11,1];
top[37] ← [12,1];
top[38] ← [12,2];
top[39] ← [12,3];
top[40] ← [12,4];
top[41] ← [13,1];
top[42] ← [13,2];
top[43] ← [13,3];
top[44] ← [14,1];
top[45] ← [13,4];
top[46] ← [14,2];
top[47] ← [15,1];
top[48] ← [14,3];
top[49] ← [15,2];
top[50] ← [16,1];
top[51] ← [14,4];
top[52] ← [15,3];
top[53] ← [16,2];
top[54] ← [17,1];
top[55] ← [18,1];
top[56] ← [15,4];
top[57] ← [16,3];
top[58] ← [17,2];
top[59] ← [19,1];
top[60] ← [15,5];
top[61] ← [20,1];
top[62] ← [16,4];
top[63] ← [17,3];
top[64] ← [18,2];
top[65] ← [18,3];
top[66] ← [16,5];
FOR i IN [0..iCSideSize) DO
left[i].x ← top[iCSideSize-1-i].y;
left[i].y ← pGASideSize+1 - top[iCSideSize-1-i].x;
ENDLOOP;
FOR i IN [0..iCSideSize) DO
right[i].x ← pGASideSize+1 - top[i].y;
right[i].y ← top[i].x;
ENDLOOP;
FOR i IN [0..iCSideSize) DO
bottom[i].x ← pGASideSize+1 - top[iCSideSize-1-i].x;
bottom[i].y ← pGASideSize+1 - top[iCSideSize-1-i].y;
ENDLOOP;
FOR y IN [1..pGASideSize] DO
FOR x IN [1..pGASideSize] DO
pga[x][y] ← "NC";
ENDLOOP;
ENDLOOP;
FOR i IN [0..4) DO
pga[7+2*i][5] ← "VCC";
pga[16][7+2*i] ← "VCC";
pga[14-2*i][16] ← "VCC";
pga[5][14-2*i] ← "VCC";
pga[8+2*i][5] ← "GND";
pga[16][8+2*i] ← "GND";
pga[13-2*i][16] ← "GND";
pga[5][13-2*i] ← "GND";
ENDLOOP;
Reading Input files:
Top side :
in ← FS.StreamOpen[Rope.Cat[fileName,".top"]];
FOR i IN [0..iCSideSize) DO
pga[top[i].x][top[i].y] ← GetLine[in, cmd.out, i, Rope.Cat[fileName,".top"] ! BadFile => {
fault ← TRUE;
CONTINUE;
}];
ENDLOOP;
Bottom side :
in ← FS.StreamOpen[Rope.Cat[fileName,".bottom"]];
FOR i IN [0..iCSideSize) DO
pga[bottom[i].x][bottom[i].y] ← GetLine[in, cmd.out, i, Rope.Cat[fileName,".bottom"] ! BadFile => {
fault ← TRUE;
CONTINUE;
}];
ENDLOOP;
Left side:
in ← FS.StreamOpen[Rope.Cat[fileName,".left"]];
FOR i IN [0..iCSideSize) DO
pga[left[i].x][left[i].y] ← GetLine[in, cmd.out, i, Rope.Cat[fileName,".left"] ! BadFile => {
fault ← TRUE;
CONTINUE;
}];
ENDLOOP;
Right side:
in ← FS.StreamOpen[Rope.Cat[fileName,".right"]];
FOR i IN [0..iCSideSize) DO
pga[right[i].x][right[i].y] ← GetLine[in, cmd.out, i, Rope.Cat[fileName,".right"] ! BadFile => {
fault ← TRUE;
CONTINUE;
}];
ENDLOOP;
IF NOT fault THEN {
Writing output files (too much pins for one part => split into 2 parts
out ← FS.StreamOpen[Rope.Cat[fileName,".top.part"],$create];
IO.PutF[out, "4096 2048 -100 -100 1500 1500 700 -100 %gT PARC-%gT U\n",
IO.rope[fileName], IO.rope[fileName]];
FOR y IN [1..pGARows] DO
FOR x IN [1..pGASideSize] DO
InsertPin[x, y, 0, 0, pga, out];
ENDLOOP;
ENDLOOP;
FOR y IN [pGARows+1..pGASideSize/2] DO
FOR x IN [1..pGARows] DO
InsertPin[x, y, 0, 0, pga, out];
ENDLOOP;
FOR x IN [pGASideSize-pGARows+1..pGASideSize] DO
InsertPin[x, y, 0, 0, pga, out];
ENDLOOP;
ENDLOOP;
IO.Close[out];
cmd.out.PutRope[Rope.Cat["File ", fileName,".top.part Written\n"]];
out ← FS.StreamOpen[Rope.Cat[fileName,".bottom.part"],$create];
IO.PutF[out, "4096 2048 -100 -100 1500 1500 700 -100 %gB PARC-%gB U\n",
IO.rope[fileName], IO.rope[fileName]];
FOR y IN [pGASideSize/2+1..pGASideSize-pGARows] DO
FOR x IN [1..pGARows] DO
InsertPin[x, y, 0, pGASideSize/2, pga, out];
ENDLOOP;
FOR x IN [pGASideSize-pGARows+1..pGASideSize] DO
InsertPin[x, y, 0, pGASideSize/2, pga, out];
ENDLOOP;
ENDLOOP;
FOR y IN [pGASideSize-pGARows+1..pGASideSize] DO
FOR x IN [1..pGASideSize] DO
InsertPin[x, y, 0, pGASideSize/2, pga, out];
ENDLOOP;
ENDLOOP;
IO.Close[out];
IO.PutF[cmd.out, "File %g.bottom.part Written\n", IO.rope[fileName]];
out ← FS.StreamOpen[Rope.Cat[fileName,".inner.part"],$create];
IO.PutF[out, "4096 2048 -100 -100 1500 1500 700 -100 %gI PARC-%gI U\n",
IO.rope[fileName], IO.rope[fileName]];
FOR y IN [2..pGARows] DO
FOR x IN [2..pGASideSize-1] DO
InsertPin[x, y, 1, 1, pga, out];
ENDLOOP;
ENDLOOP;
FOR y IN [pGARows+1..pGASideSize-pGARows] DO
FOR x IN [2..pGARows] DO
InsertPin[x, y, 1, 1, pga, out];
ENDLOOP;
FOR x IN [pGASideSize-pGARows+1..pGASideSize-1] DO
InsertPin[x, y, 1, 1, pga, out];
ENDLOOP;
ENDLOOP;
FOR y IN [pGASideSize-pGARows+1..pGASideSize-1] DO
FOR x IN [2..pGASideSize-1] DO
InsertPin[x, y, 1, 1, pga, out];
ENDLOOP;
ENDLOOP;
IO.Close[out];
IO.PutF[cmd.out, "File %g.inner.part Written\n", IO.rope[fileName]];
out ← FS.StreamOpen[Rope.Cat[fileName,".outer.part"],$create];
IO.PutF[out, "4096 2048 -100 -100 1500 1500 700 -100 %gO PARC-%gO U\n",
IO.rope[fileName], IO.rope[fileName]];
FOR x IN [1..pGASideSize] DO
InsertPin[x, 1, 0, 0, pga, out];
ENDLOOP;
FOR y IN [2..pGASideSize-1] DO
InsertPin[1, y, 0, 0, pga, out];
InsertPin[pGASideSize, y, 0, 0, pga, out];
ENDLOOP;
FOR x IN [1..pGASideSize] DO
InsertPin[x, pGASideSize, 0, 0, pga, out];
ENDLOOP;
IO.Close[out];
IO.PutF[cmd.out, "File %g.outer.part Written\n", IO.rope[fileName]];
out ← FS.StreamOpen[Rope.Cat[fileName,".sides.part"],$create];
IO.PutF[out, "4096 2048 -300 -100 1800 2000 700 -100 %gS PARC-%gS U\n",
IO.rope[fileName], IO.rope[fileName]];
IO.PutF[out, "0 0 DUMMY 1 0 1 0 11\n"];
FOR y IN [1..pGASideSize] DO
InsertPin[1, y, 2, 0, pga, out];
InsertPin[2, y, 2, 0, pga, out];
InsertPin[pGASideSize-1, y, 2, 0, pga, out];
InsertPin[pGASideSize, y, 2, 0, pga, out];
ENDLOOP;
IO.Close[out];
IO.PutF[cmd.out, "File %g.sides.part Written\n", IO.rope[fileName]];
out ← FS.StreamOpen[Rope.Cat[fileName,".center.part"],$create];
IO.PutF[out, "4096 2048 -300 -100 1800 2000 1100 -100 %gC PARC-%gC U\n",
IO.rope[fileName], IO.rope[fileName]];
FOR y IN [1..pGARows] DO
FOR x IN [3..pGASideSize-2] DO
InsertPin[x, y, 2, 0, pga, out];
ENDLOOP;
ENDLOOP;
FOR y IN [pGARows+1..pGASideSize-pGARows] DO
FOR x IN [3..pGARows] DO
InsertPin[x, y, 2, 0, pga, out];
ENDLOOP;
FOR x IN [pGASideSize-pGARows+1..pGASideSize-2] DO
InsertPin[x, y, 2, 0, pga, out];
ENDLOOP;
ENDLOOP;
FOR y IN [pGASideSize-pGARows+1..pGASideSize] DO
FOR x IN [3..pGASideSize-2] DO
InsertPin[x, y, 2, 0, pga, out];
ENDLOOP;
ENDLOOP;
IO.Close[out];
IO.PutF[cmd.out, "File %g.center.part Written\n", IO.rope[fileName]];
};
END;
Commander.Register[
key: "Pga300", proc: Pga300Proc, doc: "Transform the 4 input files: \n\tFilename.left\n\tFilename.top\n\tFilename.right\n\tFilename.bottom\ninto: \n\t\tFilename.top.part & Filename.bottom.part and\n\t\tFilename.inner.part & Filename.outer.part\n(to be used by the NewPart program)."];
END.