DIRECTORY Basics, CD, CDCells USING [CreateEmptyCell, SetInterestRect], CDDirectory, CDRects USING [CreateRect], Convert, IFUPW, IO, PW, Rope; IFUPWMux: CEDAR PROGRAM IMPORTS CD, CDCells, CDDirectory, CDRects, Convert, IO, IFUPW, PW, Rope EXPORTS IFUPW = BEGIN OPEN IFUPW; gnd: INT _ 6; vdd: INT _ 7; -- vdd assumed to be gnd+1 below IFUMuxRow: PUBLIC PROC [ design: CD.Design, name: PW.ROPE, leftCtl: List _ NIL, rightCtl: List _ NIL, top: LIST OF REF, in: LIST OF REF, out: LIST OF REF, bot: LIST OF REF, rp: RowParams _ IFUDataColNSeq ] RETURNS [cell: CD.Object] = { cells: PW.ListOb; ctl: List _ IFUPW.ListConcat[leftCtl, rightCtl]; FOR ii: INT DECREASING IN [0..rp.rngByte*rp.rngBit) DO byte, index: INT; [byte, index] _ IFUPW.ByteBitFromIndex[ii, rp]; cells _ CONS[ Mux[ design: design, ctl: ctl, in: ExpandList[byte, index, in], top: ExpandList[byte, index, top], out: ExpandList[byte, index, out], bot: ExpandList[byte, index, bot] ], cells]; ENDLOOP; cell _ PW.AbutListX[design, cells]; cell _ IFUPW.RenameObjAndAssignRowPins [design, cell, name, FALSE, top, bot, leftCtl, rightCtl, rp]; RETURN[cell]}; Mux: PROC [ design: CD.Design, top: List, ctl: List, in: List, out: List, bot: List] RETURNS [cell: CD.Object] = { cellName: PW.ROPE; xstrLgth: INT _ 8*lambda; xstrWth: INT _ (4+4)*lambda; tranBiasx: INT _ (xstrWth-metW)/2; xstrHt: INT _ xstrLgth + 2*difW; pFrng: INT _ (pwrW-metW)/2; topExtra: INT _ cnctSize/2 + topTail; botExtra: INT _ cnctSize/2 + botTail; pitch: Size = [metPitch, met2Pitch]; found: BOOL _ TRUE; muxEvenDn: BOOL = TRUE; range: Size; outN: PW.ROPE _ IF out=NIL THEN NIL ELSE out.first; iRect: CD.Rect; outIndex, outIndexBot: INT; top _ FixGVInList[top]; bot _ FixGVInList[bot]; range _ [MAX[ListLength[top],ListLength[bot]], ListLength[ctl]]; outIndex _ ListItemIndexMin[top, outN]; outIndexBot _ ListItemIndexMin[bot, outN]; IF outIndex # ListItemIndexMax[top, outN] OR outIndexBot # ListItemIndexMax[bot, outN] OR (outIndex#-1 AND outIndexBot#-1 AND outIndex#outIndexBot) THEN ERROR Error[IO.PutFR["Multiple column output %g- ABORT", IO.rope[outN]]]; IF outIndex = -1 THEN outIndex _ outIndexBot; cellName _ UniqueCellName["Mux", top, bot, in, out]; [found, cell] _ CDDirectory.Fetch[design, cellName]; IF found THEN RETURN[cell]; log.PutRope["."]; cell _ CDCells.CreateEmptyCell[]; IF outN#NIL AND ListItemIndexMax[top, outN]=-1 AND ListItemIndexMax[bot, outN]=-1 THEN ERROR Error[IO.PutFR ["Output signal (%g) is not in either top or bot lists - ABORT", IO.rope[outN]]]; IF outN#NIL AND ListItemIndexMax[in, outN]#-1 THEN ERROR Error[IO.PutFR ["Output signal (%g) is also used as input - ABORT", IO.rope[outN]]]; FOR i: INT IN [0..range.x) DO loc: Location _ [i*pitch.x, 0]; tIO: PW.ROPE _ ListIndexItem[top, i]; bIO: PW.ROPE _ ListIndexItem[bot, i]; topOut: BOOL _ Rope.Equal[tIO,outN]; botOut: BOOL _ Rope.Equal[bIO,outN]; tY: INT _ IF topOut THEN ListNonNILIndexMin[in] ELSE ListItemIndexMin[in,tIO]; bY: INT _ IF botOut THEN ListNonNILIndexMax[in] ELSE ListItemIndexMax[in,bIO]; tY _ tY + ((tY + (IF topOut=muxEvenDn THEN 1 ELSE 2)) MOD 2); bY _ bY + ((bY + (IF botOut=muxEvenDn THEN 1 ELSE 2)) MOD 2); IF tY=-1 AND bY=-1 THEN tY_bY_0; IF ~Rope.Equal[tIO, bIO] AND tY<=bY AND tIO#NIL AND bIO#NIL THEN ERROR Error[IO.PutFR ["2 signals (%g, %g) in same channel - ABORT", IO.rope[tIO], IO.rope[bIO]]]; IF tIO#NIL THEN AddRet[cell:cell, level: cmosMet, size: [metW, (range.y-tY) * pitch.y + topExtra ], loc: [i*pitch.x, tY * pitch.y ]]; IF bIO#NIL THEN AddRet[cell:cell, level: cmosMet, size: [metW, bY * pitch.y + botExtra ], loc: [i*pitch.x, 0 * pitch.y - botExtra ]]; ENDLOOP; FOR vgIndex: INT IN [gnd..vdd] DO AddRet[cell: cell, level: cmosMet, size: [pwrW, range.y * pitch.y + topExtra + botExtra ], loc: [vgIndex*pitch.x-pFrng, - botExtra ]] ENDLOOP; AddMetalPins [cell, top, bot, -leftTail, range.y*pitch.y+ topExtra, - botExtra, FALSE]; BEGIN xstr: CD.Object _ TransistorObject[size: [xstrWth, xstrLgth], difLayer: cmosNDif]; dcon: CD.Object _ IFUPW.Contact[cmosNDif]; pcon: CD.Object _ IFUPW.Contact[cmosPoly]; vcon: CD.Object _ IFUPW.Contact[cmosMet2]; scon: CD.Object _ IFUPW.Contact[cmosPWCont]; lstIONotGnd: BOOL _ TRUE; lstGndClear: BOOL _ TRUE; thsIONotGnd: BOOL _ TRUE; thsGndClear: BOOL _ TRUE; FOR ctlIndex: INT IN [0..range.y) DO cnctBiasx: INT _ (cnctSize-metW)/2; Include: PROC[object: CD.Object, location: Location] = {[] _ PW.IncludeInCell[cell, object, location]}; AddGndContact: PROC[updn: {up, dn}] = {IF updn=up THEN Include[scon, [gnd*pitch.x-cnctBiasx, (ctlIndex+1)*pitch.y - cnctSize/2 ]] ELSE Include[scon, [gnd*pitch.x-cnctBiasx, (ctlIndex+0)*pitch.y - cnctSize/2 ]]}; AddMux: PROC [index: Location] = { dWL: INT _ (ABS[outIndex-index.x])*pitch.x+cnctSize; pWL: INT _ (range.x-index.x)*pitch.x; minX: INT _ MIN[outIndex, index.x]; polX: INT _ MIN[outIndex, index.x]; pol: CD.Object _ CDRects.CreateRect[[pWL, polW], cmosPoly]; dif: CD.Object _ CDRects.CreateRect[[dWL, difW], cmosNDif]; dir: INT _ IF ((index.y MOD 2)=0)=muxEvenDn THEN 1 ELSE -1; yloc: INT _ index.y*pitch.y + pitch.y/2; Include[pcon, [range.x *pitch.x -cnctBiasx, yloc -cnctSize/2 ]]; Include[vcon, [range.x *pitch.x +cnctSize, yloc -cnctSize/2 ]]; Include[pol, [index.x *pitch.x -cnctBiasx, yloc -polW/2 ]]; Include[dif, [minX *pitch.x -cnctBiasx, yloc +dir*pitch.y/2 -difW/2 ]]; Include[dcon, [outIndex *pitch.x -cnctBiasx, yloc +dir*pitch.y/2 -cnctSize/2 ]]; Include[dcon, [index.x *pitch.x -cnctBiasx, yloc -dir*pitch.y/2 -cnctSize/2 ]]; Include[xstr, [index.x *pitch.x-tranBiasx, yloc -xstrLgth/2 ]]}; cName: PW.ROPE _ Convert.RopeFromInt[ctlIndex]; size: Size _ [cellWidth, met2W]; loc: Location _ [-leftTail, ctlIndex*pitch.y+pitch.y/2-met2W/2]; ioIndex: INT _ -1; AddRet[cell:cell, size:size, loc:loc, level:cmosMet2]; PutPin [cell, [met2W, met2W], loc, cmosMet2, cName]; PutPin [cell, [met2W, met2W], [cellWidth-leftTail-met2W, loc.y], cmosMet2, cName]; IF outN#NIL THEN { ioItem: PW.ROPE _ ListIndexItem[in, ctlIndex]; IF ioItem # NIL THEN { IF ioIndex < 0 THEN ioIndex _ ListItemIndexMax[top, ioItem]; IF ioIndex < 0 THEN ioIndex _ ListItemIndexMax[bot, ioItem]; IF ioIndex >=0 THEN AddMux[index: [ioIndex, ctlIndex]]}; thsIONotGnd _ ioIndex # gnd; thsGndClear _ thsIONotGnd AND ((ioIndex= 0 THEN { loc: Location _ [ioIndex*pitch.x, 0 ]; AddRet[cell:cell, size:[colRt-loc.x, polW], loc:loc, level:cmosPoly]; Put[polCtct, [loc.x, loc.y-2 ]] } }; FOR ctlIndex: INT IN [0..rangeY] DO ycen: INT _ ctlIndex*pitch.y+polW/2; ylow: INT _ ctlIndex*pitch.y-xtraY-difW; cName: PW.ROPE _ SELECT ctlIndex FROM 0 => VDD, rangeY => GND, ENDCASE => ListIndexItem[ctl, ctlIndex-1]; ioIndex: INT _ -1; size: Size _ [cellWidth, met2W]; loc: Location _ [-leftTail, ctlIndex*pitch.y+polW/2-met2W/2]; AddRet[cell:cell, size:size, loc:loc, level:cmosMet2]; PutPin [cell, [met2W, met2W], loc, cmosMet2, cName]; PutPin [cell, [met2W, met2W], [cellWidth-leftTail-met2W, loc.y], cmosMet2, cName]; IF cName = NIL THEN LOOP; IF ioIndex < 0 THEN ioIndex _ ListItemIndexMin[top, cName]; IF ioIndex < 0 THEN ioIndex _ ListItemIndexMin[bot, cName]; IF ioIndex >= 0 THEN Put[viaCtct, [ioIndex*pitch.x-2, loc.y-1]]; SELECT ctlIndex FROM 0 => { AddRet[cell:cell, size:[8,6], loc:[colLt, ycen], level:cmosMet]; AddRet[cell:cell, size:[8,6], loc:[colRt, ycen], level:cmosMet]; Put[polCtct, [colLt, ycen - 8/2 ]]; Put[polCtct, [colRt, ycen - 8/2 ]]; Put[viaCtct, [colVDD, ycen - 10/2 ]]; LOOP}; rangeY => { Put[viaCtct, [colLt-1, ycen - 10/2 ]]; Put[wCtct, [colWCnt, ylow ]]; IF lastIsXstr THEN Put[nCtct, [colLt, ylow ]] ELSE Put[met, [colLt, ylow ]]; LOOP}; ENDCASE; currIsXstr _ PW.XthBitOfN[(rangeY-1-ctlIndex)/2, val]; IF (ctlIndex MOD 2) = 0 THEN currIsXstr _ NOT currIsXstr; IF NOT currIsXstr THEN { Put[met, [colLt, ylow ]]; Put[wCtct, [colWCnt, ylow ]]; IF lastIsXstr THEN Put[nCtct, [colLt, ylow ]] } ELSE { Put[pol, [colLt, ycen - polW/2 ]]; Put[polCtct, [colPCnt, ycen - 8/2 ]]; Put[viaCtct, [colPCnt+8, ycen - 10/2 ]]; Put[nDif, [colGND+4, ycen - pitch.y/2 ]]; Put[nDif, [colGND+4, ycen + pitch.y/2-4 ]]; Put[nXstr, [colGND, ycen - 6 ]]; IF NOT lastIsXstr THEN Put[nCtct, [colLt, ylow ]]; Put[pDif, [colRt, ycen - pitch.y/2 ]]; Put[pDif, [colRt, ycen + pitch.y/2-4 ]]; Put[pXstr, [colRt-4, ycen - 6 ]]; Put[wCtct, [colWCnt, ylow ]]; IF (ctlIndex MOD 2) =1 THEN { Put[pCtct, [colRt, ylow + pitch.y ]]; Put[pCtct, [colVDD, ylow ]] } ELSE { Put[pCtct, [colRt, ylow ]]; Put[pCtct, [colVDD, ylow + pitch.y ]] }; }; lastIsXstr _ currIsXstr; ENDLOOP; END; PW.IncludeInDirectory[design, cell]; RETURN[cell]}; DecoderTest: IFUPW.UserProc = { RETURN[ Decoder[ design: design, top: LIST["A1", "A0", NIL], ctl: LIST["A0", "A0'", "A1", "A1'", "A2", "A2'", "A3", "A3'", "A4", "A4'", "A5", "A5'"], val: 33, out: LIST["Out"], bot: LIST["A1", NIL, "Out" ] ] ] }; MuxTest: IFUPW.UserProc = { RETURN[ Mux[ design: design, top: LIST["XB", "Alpha", "Beta", "Pass", NIL, "In1"], ctl: LIST["RdXBus", "Hold", "Clear", "Set", "Set1", "Set2"], in: LIST["XB", "Alpha", GND, VDD, "In1", "In2"], out: LIST["Out2"], bot: LIST["XB", "Alpha", "Beta", "Pass", "Out2", NIL, GND, VDD, "In2"] ] ]}; MuxTest: IFUPW.UserProc = { RETURN[ Mux[ design: design, top: LIST["XBus.37", NIL, NIL, NIL, NIL, NIL, "GND", "VDD", NIL, NIL, NIL, NIL, NIL], ctl: LIST["ARtOSetB", "ARtAlpB", "ARtAlp03B", "ARtAlp47B", "ARtOp47B", "ARtBetB", "ARtBet03B", "ARtBet47B", "BRtOSetB", "BRtAlpB", "BRtAlp03B", "BRtAlp47B", "BRtOp47B", "BRtBetB", "BRtBet03B", "BRtBet47B", "CRtOSetB", "CRtAlpB", "CRtAlp03B", "CRtAlp47B", "CRtOp47B", "CRtBetB", "CRtBet03B", "CRtBet47B"], in: LIST[NIL, NIL, NIL, NIL, NIL, NIL, NIL, NIL, NIL, NIL, NIL, NIL, NIL, NIL, NIL, NIL, NIL, NIL, NIL, NIL, NIL, NIL, NIL, NIL], out: LIST[NIL], bot: LIST["XBus.37", NIL, NIL] ] ]}; PW.Register[DecoderTest, "DecoderTest"]; PW.Register[MuxTest, "MuxTest"]; ÊC˜šœ™Jšœ<™Jšœœ5˜>Jšœ œ8™CJš œœœ œœœ˜=Jšœœ˜*JšœE˜EJšœD˜DJšœB˜BJšœJ˜JJšœL™LJšœP˜PJšœO˜OJšœG˜G—Jšœœœ!˜/Jšœ#˜#JšœA˜AJšœ œ˜Jšœ6˜6Jšœ<˜—šœœœ œ˜@Jšœœœ˜3Jšœœœ˜3—Jšœ˜Jšœ˜—Jšœ˜—Jšœ˜Jšœ˜—Jšœ"˜$Jšœœ˜Jš œ œœœœ ˜RJšœ<˜Jšœ œ3™>Jšœ œ3™>Jšœœ:™BJšœœ4™=Jšœœ4™=Jšœœ6™>JšœC™CJšœI™IJšœQ™QJ™Jšœ ™ šœœœ™Jšœ œ™Jšœ œ'™:Jšœ œ'™:šœœ™Jšœ&™&JšœE™EJšœ$™$——J™šœ œœ ™#Jšœœ™$Jšœœ™(šœœœœ ™%Jšœœ™ Jšœ œ™Jšœ#™*—Jšœ œ™Jšœ"™"Jšœ?™?Jšœ6™6Jšœ=™=JšœR™RJšœ œœœ™Jšœ œ(™;Jšœ œ(™;Jšœœ,™@J™šœ ™šœ™Jšœ@™@Jšœ@™@Jšœ)™)Jšœ)™)Jšœ,™,Jšœ™—šœ ™ Jšœ-™-Jšœ%™%šœ ™ Jšœ%™)Jšœ%™)—Jšœ™—Jšœ™—Jšœ œ'™6Jšœ œœœ ™9šœœ ™šœ™Jšœ!™!Jšœ#™#šœ ™Jšœ%™%——šœ™Jšœ%™%Jšœ)™)Jšœ,™,Jšœ,™,Jšœ-™-Jšœ%™%šœœ ™Jšœ$™$—Jšœ*™*Jšœ+™+Jšœ&™&Jšœ#™#šœ œ™šœ™Jšœ'™'Jšœ"™"—šœ™Jšœ ™ Jšœ*™*——Jšœ™——Jšœ™Jšœ™—Jšœ™—Jšœ"™$Jšœ™—J˜šœ0™0J™Jšœ™JšœY™YJšœ ™ Jšœ™Jšœ$™$—šœ(™(J™Jšœ6™6Jšœ>™>Jšœ5™5Jšœ™JšœN™N—šœ(™(J™JšœV™Všœ;™;Jšœ0™0—šœ0™0Jšœ0™0—šœ0™0Jšœ1™1—Jšœƒ™ƒJšœ™Jšœ%™%—J™J™Jšœ*™*Jšœ#™#J˜Jšœ˜—J™—…—ªL