DIRECTORY Basics, CD, CDCells USING [CreateEmptyCell], CDDirectory, CMos, CMosContacts, IFUPW, PW, PWBasics, Rope; IFUPWDriverGate: CEDAR PROGRAM IMPORTS CDCells, CMosContacts, CMos, IFUPW, PW, PWBasics, Rope EXPORTS IFUPW = BEGIN OPEN IFUPW; rngByte: INT = 4; rngBit: INT = 8; IFUTriDriverRow: PUBLIC PROC [ design: CD.Design, enable: PW.ROPE, disable: PW.ROPE, top: LIST OF REF, in: LIST OF REF, out: LIST OF REF, bot: LIST OF REF, seq: BOOL _ FALSE ] RETURNS [cell: PW.ObjName] = { cells: LIST OF PW.ObjName; FOR ii: INT DECREASING IN [0..rngByte*rngBit) DO index: INT _ IF seq THEN ii MOD rngBit ELSE ii / rngByte; byte: INT _ IF seq THEN ii / rngBit ELSE ii MOD rngByte; cells _ CONS[ TriDriver[ design: design, top: ExpandList[byte, index, top], in: ExpandList[byte, index, in], enable: enable, disable: disable, out: ExpandList[byte, index, out], bot: ExpandList[byte, index, bot]], cells]; ENDLOOP; RETURN[PW.AbutListX[cells]]}; TriDriver: PROC [ design: CD.Design, enable: PW.ROPE, disable: PW.ROPE, top: List, in: List, out: List, bot: List ] RETURNS [PW.ObjName] = { topTail: INT = 4; botTail: INT = 2; pitch: Size = [mPitch, pBigPitch]; cell: CD.ObPtr _ CDCells.CreateEmptyCell[]; rangeX: INT _ nofVWires; inN: PW.ROPE _ IF in=NIL THEN NIL ELSE in.first; outN: PW.ROPE _ IF out=NIL THEN NIL ELSE out.first; FOR i: INT IN [0..rangeX) DO Add: PROC[bindex, tindex, toptail, bottail: INT] = { loc.y _ bindex*pitch.y - bottail; size.y _ (tindex-bindex)*pitch.y + toptail + bottail; IF size.y>0 THEN AddRet[cell:cell, size:size, loc:loc, level: CMos.met]}; size: Size _ [6, 0]; loc: Location _ [i*pitch.x, 0]; tIO: PW.ROPE _ ListIndexItem[top, i]; bIO: PW.ROPE _ ListIndexItem[bot, i]; IF tIO#NIL THEN SELECT TRUE FROM Rope.Equal[tIO, bIO] => {Add[0, 4, 4+topTail, botTail]}; Rope.Equal[tIO, outN] => {Add[1, 4, 4+topTail, 0]}; Rope.Equal[tIO, inN] => {Add[3, 4, 4+topTail, 0]} ENDCASE => ERROR; -- top not connected anywhere ABORT; IF bIO#NIL THEN SELECT TRUE FROM Rope.Equal[bIO, tIO] => LOOP; Rope.Equal[bIO, inN] => {Add[0, 3, 0, botTail]}; Rope.Equal[bIO, outN] => {Add[0, 1, 0, botTail]}; ENDCASE => ERROR; -- bottom not connected anywhere ABORT ENDLOOP; FOR i: INT IN [0..rangeX) DO tName: PW.ROPE _ ListIndexItem[top, i]; bName: PW.ROPE _ ListIndexItem[bot, i]; size: Size _ [6, 6]; loc: Location _ [i*pitch.x, 4*pitch.y+4+topTail-size.y]; IF tName #NIL THEN PutPin [cell, size, loc, CMos.met, tName]; IF bName #NIL THEN PutPin [cell, size, [loc.x, -botTail], CMos.met, bName]; ENDLOOP; AddRet[cell:cell, size:[cellWidth, 4], loc:[-leftTail, 64], level: CMos.pol]; AddRet[cell:cell, size:[cellWidth,16], loc:[-leftTail, 48], level: CMos.met2]; AddRet[cell:cell, size:[cellWidth,16], loc:[-leftTail, 12], level: CMos.met2]; AddRet[cell:cell, size:[cellWidth, 4], loc:[-leftTail, 0], level: CMos.pol]; PutPin [cell, [4, 4], [-leftTail, 64], CMos.pol, enable]; PutPin [cell, [4, 4], [cellWidth-leftTail-4, 64], CMos.pol, enable]; PutPin [cell, [4,16], [-leftTail, 48], CMos.met2, "VDD"]; PutPin [cell, [4,16], [cellWidth-leftTail-4, 48], CMos.met2, "VDD"]; PutPin [cell, [4,16], [-leftTail, 12], CMos.met2, "GND"]; PutPin [cell, [4,16], [cellWidth-leftTail-4, 12], CMos.met2, "GND"]; PutPin [cell, [4, 4], [-leftTail, 0], CMos.pol, disable]; PutPin [cell, [4, 4], [cellWidth-leftTail-4, 0], CMos.pol, disable]; FOR i: INT IN [0..rangeX) DO AddPCnt: PROC = {[] _ PWBasics.IncludeApplication [cell, CMosContacts.CreatePolyCon[l: 8], [loc.x, loc.y-2]]}; loc: Location _ [i * pitch.x, 0]; size: Size _ [(rangeX-i) * pitch.x, 4]; ioT: PW.ROPE _ ListIndexItem[top, i]; ioB: PW.ROPE _ ListIndexItem[bot, i]; loc.y _ 3*pitch.y; IF inN#NIL THEN IF Rope.Equal[inN, ioT] OR Rope.Equal[inN, ioB] THEN {AddPCnt[]; AddRet[cell:cell, size:size, loc:loc, level:CMos.pol]}; loc.y _ 1*pitch.y; IF outN#NIL THEN IF Rope.Equal[outN, ioT] OR Rope.Equal[outN, ioB] THEN {AddPCnt[]; AddRet[cell:cell, size:size, loc:loc, level:CMos.pol]}; ENDLOOP; IF NOT inN=NIL THEN [] _ PWBasics.IncludeApplication[ cell: cell, subcell: PWBasics.ObjFromName[design, "GVTriStateDriver"], location: [rangeX*pitch.x, 0]]; PWBasics.RepositionCell[design, cell]; RETURN[PWBasics.NameFromObj[cell]]}; IFUGateRow: PUBLIC PROC [ design: CD.Design, top: LIST OF REF, type: LIST OF REF, in1: LIST OF REF, in2: LIST OF REF, out: LIST OF REF, bot: LIST OF REF, seq: BOOL _ FALSE ] RETURNS [cell: PW.ObjName] = { cells: LIST OF PW.ObjName; FOR ii: INT DECREASING IN [0..rngByte*rngBit) DO index: INT _ IF seq THEN ii MOD rngBit ELSE ii / rngByte; byte: INT _ IF seq THEN ii / rngBit ELSE ii MOD rngByte; cells _ CONS[ Gate[ design: design, type: ExpandList[byte, index, type], top: ExpandList[byte, index, top], in1: ExpandList[byte, index, in1], in2: ExpandList[byte, index, in2], out: ExpandList[byte, index, out], bot: ExpandList[byte, index, bot]], cells]; ENDLOOP; RETURN[PW.AbutListX[cells]]}; Gate: PROC [ design: CD.Design, top: List, type: List, in1: List, in2: List, out: List, bot: List ] RETURNS [PW.ObjName] = { topTail: INT = 4; botTail: INT = 2; pitch: Size = [mPitch, pBigPitch]; cell: CD.ObPtr _ CDCells.CreateEmptyCell[]; rangeX: INT _ MAX[ListLength[top], ListLength[bot]]; in1N: PW.ROPE _ IF in1=NIL THEN NIL ELSE in1.first; in2N: PW.ROPE _ IF in2=NIL THEN NIL ELSE in2.first; outN: PW.ROPE _ IF out=NIL THEN NIL ELSE out.first; FOR i: INT IN [0..rangeX) DO Add: PROC[bindex, tindex, toptail, bottail: INT] = { loc.y _ bindex*pitch.y - bottail; size.y _ (tindex-bindex)*pitch.y + toptail + bottail; IF size.y>0 THEN AddRet[cell:cell, size:size, loc:loc, level: CMos.met]}; size: Size _ [6, 0]; loc: Location _ [i*pitch.x, 0]; tIO: PW.ROPE _ ListIndexItem[top, i]; bIO: PW.ROPE _ ListIndexItem[bot, i]; IF tIO#NIL THEN SELECT TRUE FROM Rope.Equal[tIO, bIO] => {Add[0, 2, 4+topTail, botTail]}; Rope.Equal[in2N, tIO] => {Add[0, 2, 4+topTail, 0]}; Rope.Equal[outN, tIO] => {Add[1, 2, 4+topTail, 0]}; Rope.Equal[in1N, tIO] => {Add[2, 2, 4+topTail, 0]}; ENDCASE => ERROR; -- top not connected anywhere ABORT; IF bIO#NIL THEN SELECT TRUE FROM Rope.Equal[bIO, tIO] => LOOP; Rope.Equal[in1N, bIO] => {Add[0, 2, 0, botTail]}; Rope.Equal[outN, bIO] => {Add[0, 1, 0, botTail]}; Rope.Equal[in2N, bIO] => {Add[0, 0, 0, botTail]}; ENDCASE => ERROR; -- bottom not connected anywhere ABORT ENDLOOP; FOR i: INT IN [0..rangeX) DO tName: PW.ROPE _ ListIndexItem[top, i]; bName: PW.ROPE _ ListIndexItem[bot, i]; size: Size _ [6, 6]; loc: Location _ [i*pitch.x, 2*pitch.y+4+topTail-size.y]; IF tName #NIL THEN PutPin [cell, size, loc, CMos.met, tName]; IF bName #NIL THEN PutPin [cell, size, [loc.x, -botTail], CMos.met, bName]; ENDLOOP; AddRet[cell:cell, size:[cellWidth,18], loc:[-leftTail, 22], level: CMos.met2]; AddRet[cell:cell, size:[cellWidth,18], loc:[-leftTail, -4], level: CMos.met2]; PutPin [cell, [4,18], [-leftTail, 22], CMos.met2, "VDD"]; PutPin [cell, [4,18], [cellWidth-leftTail-4, 22], CMos.met2, "VDD"]; PutPin [cell, [4,18], [-leftTail, -4], CMos.met2, "GND"]; PutPin [cell, [4,18], [cellWidth-leftTail-4, -4], CMos.met2, "GND"]; FOR i: INT IN [0..rangeX) DO AddPCnt: PROC = {[] _ PWBasics.IncludeApplication [cell, CMosContacts.CreatePolyCon[l: 8], [loc.x, loc.y-2]]}; loc: Location _ [ i * pitch.x, 0]; size: Size _ [(rangeX-i) * pitch.x, 4]; ioT: PW.ROPE _ ListIndexItem[top, i]; ioB: PW.ROPE _ ListIndexItem[bot, i]; loc.y _ 2*pitch.y; IF in1N#NIL THEN IF Rope.Equal[in1N, ioT] OR Rope.Equal[in1N, ioB] THEN {AddPCnt[]; AddRet[cell:cell, size:size, loc:loc, level:CMos.pol]}; loc.y _ 1*pitch.y; IF outN#NIL THEN IF Rope.Equal[outN, ioT] OR Rope.Equal[outN, ioB] THEN {AddPCnt[]; AddRet[cell:cell, size:size, loc:loc, level:CMos.pol]}; loc.y _ 0*pitch.y; IF in2N#NIL THEN IF Rope.Equal[in2N, ioT] OR Rope.Equal[in2N, ioB] THEN {AddPCnt[]; AddRet[cell:cell, size:size, loc:loc, level:CMos.pol]}; ENDLOOP; IF type#NIL THEN { inv: BOOL _ Rope.Find[s1: type.first, s2: "INV", case: FALSE]#-1; nor: BOOL _ Rope.Find[s1: type.first, s2: "NOR", case: FALSE]#-1; nand: BOOL _ Rope.Find[s1: type.first, s2: "NAND", case: FALSE]#-1; [] _ PWBasics.IncludeApplication[ cell: cell, subcell: PWBasics.ObjFromName[design, (SELECT TRUE FROM nor => "BasicNOR", nand => "BasicNAND", ENDCASE => "BasicINV")], location: [rangeX*pitch.x, -4]] }; PWBasics.RepositionCell[design, cell]; RETURN[PWBasics.NameFromObj[cell]]}; TDrive: PW.UserProc = { RETURN[ TriDriver[ design: design, enable: "PhB", disable: "PhB'", top: LIST["XB", "Alpa", "Beta", "Pass", "In"], in: LIST["In"], out: LIST["XB"], bot: LIST["XB", "Alpa", "Beta", "Pass"]] ]}; GateNor: PW.UserProc = { RETURN[ Gate[ design: design, top: LIST["XBus.00", "Match.0", "Comp.0", "Match.1"], type: LIST["NOR"], in1: LIST["Match.0"], in2: LIST["Match.1"], out: LIST["Comp.0"], bot: LIST["XBus.00", "Match.0", "Comp.0", "Match.1"] ] ]}; GateNand: PW.UserProc = { RETURN[ Gate[ design: design, top: LIST["XBus.00", "Match.0", "Comp.0", "Match.1"], type: LIST["NAND"], in1: LIST["Match.0"], in2: LIST["Match.1"], out: LIST["Comp.0"], bot: LIST["XBus.00", "Match.0", "Comp.0", "Match.1"] ] ]}; GateInv: PW.UserProc = { RETURN[ Gate[ design: design, top: LIST["XBus.00", "Match.0", "nMatch.0"], type: LIST["INV"], in1: LIST["Match.0"], in2: NIL, out: LIST["nMatch.0"], bot: LIST["XBus.00", "Match.0", "nMatch.0"] ] ]}; PW.Register[GateNor, "GateNor"]; PW.Register[GateNand, "GateNand"]; PW.Register[GateInv, "GateInv"]; PW.Register[TDrive, "TDrive"]; END. ºIFUPWDriverGate.mesa, Copyright c 1985 by Xerox Corporation. All rights reserved. RemoveButton CD; CreateButton L Compile Latch; Run Latch Last Edited by Curry, April 29, 1985 1:55:50 pm PDT in, top, out and bot share a common format. IF a top level item is a rope then a byte and bit index are appended to each rope. IF a top level item is a List of rope then a bit index is appended to each rope. IF a top level item is a List of List of rope then each rope is used as is. Metal wires Insert Metal Pins Enables and power Wires Insert Enable and power Pins Poly connections Cell Metal wires Insert Metal Pins Enables and power Wires Insert Enable and power Pins Poly connections Cell Ê 7˜šÐbl™Jšœ<™˜>JšœF˜FJšœ>˜>JšœF˜FJšœ@˜@JšœH˜H—Jš¡™šžœžœžœ ž˜š œžœ$˜1Jšœ<˜<—Jšœ!˜!Jšœ(˜(Jšœžœžœ˜%Jšœžœžœ˜%Jšœ˜š žœžœžœžœžœ˜@JšžœD˜H—Jšœ˜šžœž œžœ˜CJšžœD˜H—Jšžœ˜—Jš¡™šžœžœ žœ"˜5Jšœ ˜ Jšœ:˜:Jšœ˜—Jšœ&˜&Jšžœ˜$—J˜J˜šŸ œžœžœ˜Jšœžœ˜Jšœžœžœžœ˜Jšœžœžœžœ˜Jšœžœžœžœ˜Jšœžœžœžœ˜Jšœžœžœžœ˜Jšœžœžœžœ˜šœžœžœ˜Jšžœžœ ˜—Jšœžœžœžœ ˜š žœžœž œžœž˜0Jš œžœžœžœžœžœ˜9Jš œžœžœžœ žœžœ ˜8šœžœ˜Jšœ˜Jšœ%˜%Jšœ#˜#Jšœ#˜#Jšœ#˜#Jšœ#˜#Jšœ,˜,—Jšžœ˜—Jšžœžœ˜J˜—šŸœžœ˜ Jšœžœ˜Jšœ ˜ Jšœ ˜ Jšœ ˜ Jšœ ˜ Jšœ ˜ šœ ˜ Jšžœžœ ˜—Jšœ žœ˜Jšœ žœ˜Jšœ%˜%Jšœžœ#˜-Jšœ žœžœ#˜6Jšœžœžœžœžœžœžœžœ ˜5Jšœžœžœžœžœžœžœžœ ˜5Jšœžœžœžœžœžœžœžœ ˜5J˜Jš  ™ šžœžœžœ ž˜š œžœ#žœ˜4Jšœ!˜!Jšœ5˜5Jšžœ žœ9˜I—Jšœ˜Jšœ˜Jšœžœžœ˜&Jšœžœžœ˜&š žœžœžœžœžœž˜ Jšœ8˜8Jšœ3˜3Jšœ3˜3Jšœ3˜3Jšžœžœ¢$˜:—š žœžœžœžœžœž˜ Jšœžœ˜Jšœ1˜1Jšœ1˜1Jšœ1˜1Jšžœžœ¢&˜<—Jšžœ˜—Jš¡™šžœžœžœ ž˜Jšœžœžœ˜'Jšœžœžœ˜'Jšœ˜Jšœ8˜8Jšžœžœžœ.˜@Jšžœžœžœ9˜KJšžœ˜—š¡™JšœN˜NJšœN˜N—š¡™Jšœ>˜>JšœF˜FJšœ>˜>JšœF˜F—Jš¡™šžœžœžœ ž˜š œžœ$˜1Jšœ<˜<—Jšœ$˜$Jšœ(˜(Jšœžœžœ˜%Jšœžœžœ˜%Jšœ˜š žœžœžœžœžœ˜CJšžœD˜H—Jšœ˜š žœžœžœžœžœ˜CJšžœD˜H—Jšœ˜š žœžœžœžœžœ˜CJšžœD˜H—Jšžœ˜—Jš¡™šžœžœžœ˜Jšœžœ.žœ˜AJšœžœ.žœ˜AJšœžœ/žœ˜CJšœ!˜!Jšœ ˜ šœ'žœžœž˜7Jšœ(žœ˜@—Jšœ"˜"—Jšœ&˜&Jšžœ˜$—J˜J™š¡œžœžœ¡ œ˜*J˜Jšœ˜Jšœ˜Jšœžœ&˜0Jšœžœ˜Jšœžœ˜Jšœžœ#˜-—š¡œžœžœ˜&Jšœ˜Jšœžœ.˜8Jšœžœ˜Jšœžœ ˜Jšœžœ ˜Jšœžœ ˜Jšœžœ3˜=—š¡œžœžœ˜'Jšœ˜Jšœžœ.˜8Jšœžœ ˜Jšœžœ ˜Jšœžœ ˜Jšœžœ ˜Jšœžœ3˜=—š¡œžœžœ˜&Jšœ˜Jšœžœ$˜.Jšœžœ˜Jšœžœ ˜Jšœ ˜ Jšœžœ ˜Jšœžœ)˜3—J˜Jšžœ"˜$Jšžœ$˜&Jšžœ"˜$Jšžœ!˜#J˜Jšžœ˜—J™—…—%r5c