<> <> << Enables to generate easily 300 pins PGA parts for EXPERT.>> <<>> <> << Filename.top.part, Filename.bottom.part>> <> <> <<(to be transformed by the NewPart program).>> <<>> <> <<>> <<>> <> <<- 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: BOOLEAN _ FALSE; stream: IO.STREAM _ IO.RIS[cmd.commandLine]; fileName: ROPE _ IO.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; <<>> <> <<>> <<>> <> 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; <> 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; <> 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; <> 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 { <<>> < 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.