<> <> <> <> <> <> DIRECTORY CD, CDBasics, CDRects, CDCells, CDOps, SCLibGen, CDGenerate, CDDirectory, CDProperties, CDRemote, CDSimpleRules, CDSymbolicObjects, CDUtil, Rope; SCLibGenImpl: CEDAR PROGRAM IMPORTS CD, CDBasics, CDRects, CDCells, CDOps, CDGenerate, CDDirectory, CDProperties, CDRemote, CDSimpleRules, CDSymbolicObjects, CDUtil, Rope EXPORTS SCLibGen = BEGIN SetUpTech: PROC [t: CD.Technology] = { lambda _ t.lambda; met _ CD.FetchLayer[t, $met]; met2 _ CD.FetchLayer[t, $met2]; }; seeMeProc: PROC[CD.Object] _ NIL; SeeMe: PUBLIC PROC [p: PROC[CD.Object]] = {seeMeProc_p}; met, met2: CD.Layer; gDesign: CD.Design; cell: CD.Object; ptype: BOOL; originP, pitchP, bottomContactN, topContactP, m2ContP, heightP: CD.Position; topPinR, botPinR, vddPinR, gndPinR: CD.Rect; lambda, pitch, metWidth, limitPy, limitNy: CD.Number; sizeOb, p1Ob, p2Ob, p3Ob, p4Ob, contactNOb, contactPOb, contactM2Ob, xViaOb: CD.Object; topPinOb, botPinOb, vddPinOb, gndPinOb: CD.Object; specialOb, specialDNOb, specialDPOb: CD.Object; pinOrder: Rope.ROPE; GetP1: CDGenerate.GeneratorProc = { ob _ CDUtil.PartialCopy[ob: sizeOb, design: design, instances: LIST["B", "T", "TN", "TP"], remove: FALSE, prop: $X, name: "=template="]; CDCells.SetSimplificationTreshhold[ob, 0.05, FALSE]; }; GetP2: CDGenerate.GeneratorProc = { ob _ CDUtil.PartialCopy[ob: sizeOb, design: design, instances: LIST["B", "T", "TP"], remove: FALSE, prop: $X, name: "=template="]; CDCells.SetSimplificationTreshhold[ob, 0.05, FALSE]; }; GetP3: CDGenerate.GeneratorProc = { ob _ CDUtil.PartialCopy[ob: sizeOb, design: design, instances: LIST["B", "T", "TN"], remove: FALSE, prop: $X, name: "=template="]; CDCells.SetSimplificationTreshhold[ob, 0.05, FALSE]; }; GetP4: CDGenerate.GeneratorProc = { ob _ CDUtil.PartialCopy[ob: sizeOb, design: design, instances: LIST["B"], remove: FALSE, prop: $X, name: "=template="]; CDCells.SetSimplificationTreshhold[ob, 0.05, FALSE]; }; SetUpInput: PROC [design: CD.Design] = { GetLib: PROC [name: Rope.ROPE] RETURNS [ob: CD.Object] = { ob _ CDGenerate.FetchNCall[stdCellInput, design, name]; IF ob=NIL THEN ERROR }; SetUpTech[design.technology]; gDesign _ design; sizeOb _ GetLib["size"]; specialOb _ GetLib["special"]; specialDNOb _ GetLib["specialDN"]; specialDPOb _ GetLib["specialDP"]; p1Ob _ CDGenerate.FetchNCall[stdCell, design, "=p1="]; p2Ob _ CDGenerate.FetchNCall[stdCell, design, "=p2="]; p3Ob _ CDGenerate.FetchNCall[stdCell, design, "=p3="]; p4Ob _ CDGenerate.FetchNCall[stdCell, design, "=p4="]; contactNOb _ GetLib["contactN"]; contactPOb _ GetLib["contactP"]; contactM2Ob _ GetLib["contactM2"]; xViaOb _ GetLib["xVia"]; topPinOb _ FetchPin[sizeOb, "topPin"].ob; botPinOb _ FetchPin[sizeOb, "botPin"].ob; vddPinOb _ FetchPin[sizeOb, "Vdd"].ob; gndPinOb _ FetchPin[sizeOb, "Gnd"].ob; metWidth _ CDSimpleRules.MinWidth[met]; GetNumbers[sizeOb]; }; FetchPin: PROC [cell: CD.Object, name: Rope.ROPE] RETURNS [inst: CD.Instance] = { il: CD.InstanceList _ CDSymbolicObjects.FindSymbolicObs[cell, name]; IF il=NIL OR il.rest#NIL OR il.first.ob=NIL THEN ERROR; RETURN [il.first] }; GetNumbers: PROC [ob: CD.Object] = BEGIN GetOPoint: PROC [name: Rope.ROPE] RETURNS [p: CD.Position] = { r: CD.Rect _ CDSymbolicObjects.Denotes[FetchPin[ob, name]]; p _ [r.x1, r.y1]; }; GetRect: PROC [name: Rope.ROPE] RETURNS [r: CD.Rect] = { r _ CDBasics.MoveRect[ CDSymbolicObjects.Denotes[FetchPin[ob, name]], CDBasics.NegOffset[originP] ] }; GetPoint: PROC [name: Rope.ROPE] RETURNS [p: CD.Position] = { p _ CDBasics.SubPoints[GetOPoint[name], originP]; }; originP _ GetOPoint["origin"]; pitchP _ GetPoint["pitch"]; bottomContactN _ GetPoint["bottomContactN"]; topContactP _ GetPoint["topContactP"]; m2ContP _ GetPoint["m2c"]; heightP _ GetPoint["height"]; limitPy _ GetPoint["limitP"].y; limitNy _ GetPoint["limitN"].y; topPinR _ GetRect["topPin"]; botPinR _ GetRect["botPin"]; vddPinR _ GetRect["Vdd"]; gndPinR _ GetRect["Gnd"]; pitch _ pitchP.x; END; ContactM2: PUBLIC PROC [pos1, pos2, pos3, pos4, pos5, pos6, pos7, pos8, pos9, pos10, pos11, pos12, pos13, pos14, pos15, pos16, pos17, pos18, pos19, pos20, pos21, pos22: INT _ -1] = { Incl: PROC [n: INT_-1] = { IF n>=0 THEN { [] _ CDCells.IncludeOb[cell: cell, ob: contactM2Ob, trans: [[x: m2ContP.x+(n-1)*pitch, y: m2ContP.y]] ]; } }; Incl[pos1]; Incl[pos2]; Incl[pos3]; Incl[pos4]; Incl[pos5]; Incl[pos6]; Incl[pos7]; Incl[pos8]; Incl[pos9]; Incl[pos10]; Incl[pos11]; Incl[pos12]; Incl[pos13]; Incl[pos14]; Incl[pos15]; Incl[pos16]; Incl[pos17]; Incl[pos18]; Incl[pos19]; Incl[pos20]; Incl[pos21]; Incl[pos22]; }; Pins: PUBLIC PROC [cnt: INT _ 1, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22: Rope.ROPE _ NIL] = { pos: INT _ 0; SignalPin: PROC [n: Rope.ROPE _ NIL] = { IF ~Rope.IsEmpty[n] THEN { rob: CD.Object; i: CD.Instance; <<>> i _ NEW[CD.InstanceRep_ [ ob: botPinOb, trans: CDOps.FitObjectI[ob: botPinOb, location: [x: botPinR.x1+pos*pitch, y: botPinR.y1], orientation: CDSymbolicObjects.OrientFromDirection[south]] ]]; CDSymbolicObjects.SetLayer[i, met2]; CDSymbolicObjects.SetName[i, n]; [] _ CDCells.IncludeInstance[cell: cell, inst: i, mode: dontResize]; <<--for aid to the Spinifex to Thyme extraction>> rob _ CDRects.CreateRect[CD.InterestSize[botPinOb], met2]; i _ NEW[CD.InstanceRep_ [ ob: rob, trans: CDOps.FitObjectI[ob: rob, location: [x: botPinR.x1+pos*pitch, y: botPinR.y1], orientation: CDSymbolicObjects.OrientFromDirection[south]] ]]; CDProperties.PutProp[i, $SignalName, n]; CDProperties.PutProp[i, $Export, $TRUE]; [] _ CDCells.IncludeInstance[cell: cell, inst: i, mode: dontResize]; i _ NEW[CD.InstanceRep_ [ ob: botPinOb, trans: CDOps.FitObjectI[ob: topPinOb, location: [x: topPinR.x1+pos*pitch, y: topPinR.y2-CD.InterestSize[topPinOb].x], orientation: CDSymbolicObjects.OrientFromDirection[north]] ]]; CDSymbolicObjects.SetLayer[i, met2]; CDSymbolicObjects.SetName[i, n]; [] _ CDCells.IncludeInstance[cell: cell, inst: i, mode: dontResize]; }; pos _ pos+1; }; i: CD.Instance; gnd: Rope.ROPE = "Gnd"; vdd: Rope.ROPE = "Vdd"; <<--bottomLeft>> i _ NEW[CD.InstanceRep_ [ ob: gndPinOb, trans: CDOps.FitObjectI[ob: gndPinOb, location: [x: gndPinR.x1, y: gndPinR.y1], orientation: CDSymbolicObjects.OrientFromDirection[west]] ]]; CDSymbolicObjects.SetLayer[i, met]; CDSymbolicObjects.SetName[i, "Gnd"]; [] _ CDCells.IncludeInstance[cell: cell, inst: i, mode: dontResize]; <<--for aid to the Spinifex to Thyme extraction>> i _ CDCells.IncludeOb[cell: cell, ob: CDRects.CreateRect[CDBasics.SizeOfRect[gndPinOb.bbox], met], trans: [[x: gndPinR.x1, y: gndPinR.y1]], mode: dontResize ].newInst; CDProperties.PutProp[i, $SignalName, gnd]; CDProperties.PutProp[i, $Export, $TRUE]; <<>> <<--bottomRight>> i _ NEW[CD.InstanceRep_ [ ob: gndPinOb, trans: CDOps.FitObjectI[ob: gndPinOb, location: [x: gndPinR.x1+cnt*pitch-CDBasics.SizeOfRect[gndPinOb.bbox].x, y: gndPinR.y1], orientation: CDSymbolicObjects.OrientFromDirection[east]] ]]; CDSymbolicObjects.SetLayer[i, met]; CDSymbolicObjects.SetName[i, "Gnd"]; [] _ CDCells.IncludeInstance[cell: cell, inst: i, mode: dontResize]; <<--topLeft>> i _ NEW[CD.InstanceRep_ [ ob: vddPinOb, trans: CDOps.FitObjectI[ob: vddPinOb, location: [x: vddPinR.x1, y: vddPinR.y1], orientation: CDSymbolicObjects.OrientFromDirection[west]] ]]; CDSymbolicObjects.SetLayer[i, met]; CDSymbolicObjects.SetName[i, "Vdd"]; [] _ CDCells.IncludeInstance[cell: cell, inst: i, mode: dontResize]; <<>> <<--for aid to the Spinifex to Thyme extraction>> i _ CDCells.IncludeOb[cell: cell, ob: CDRects.CreateRect[CD.InterestSize[vddPinOb], met], trans: [[x: vddPinR.x1, y: vddPinR.y1]], mode: dontResize ].newInst; CDProperties.PutProp[i, $SignalName, vdd]; CDProperties.PutProp[i, $Export, $TRUE]; <<--topRight>> i _ NEW[CD.InstanceRep_ [ ob: vddPinOb, trans: CDOps.FitObjectI[ob: vddPinOb, location: [x: vddPinR.x1+cnt*pitch-CD.InterestSize[vddPinOb].x, y: vddPinR.y1], orientation: CDSymbolicObjects.OrientFromDirection[east]] ]]; CDSymbolicObjects.SetLayer[i, met]; CDSymbolicObjects.SetName[i, "Vdd"]; [] _ CDCells.IncludeInstance[cell: cell, inst: i, mode: dontResize]; SignalPin[p1]; SignalPin[p2]; SignalPin[p3]; SignalPin[p4]; SignalPin[p5]; SignalPin[p6]; SignalPin[p7]; SignalPin[p8]; SignalPin[p9]; SignalPin[p10]; SignalPin[p11]; SignalPin[p12]; SignalPin[p13]; SignalPin[p14]; SignalPin[p15]; SignalPin[p16]; SignalPin[p17]; SignalPin[p18]; SignalPin[p19]; SignalPin[p20]; SignalPin[p21]; SignalPin[p22]; [] _ CDCells.ResizeCell[cell: cell, design: NIL]; }; MakeCont: PUBLIC PROC [row: INT, start: INT _ 0, n: INT _ 1, back: BOOL _ FALSE] = { ct: CD.Object _ IF ptype THEN contactPOb ELSE contactNOb; ibase: CD.Position _ CD.InterestBase[ct]; yStep: CD.Number _ IF ptype THEN -CD.InterestSize[ct].y ELSE CD.InterestSize[ct].y; x: CD.Number _ bottomContactN.x+(row-1)*pitch; y: CD.Number _ (IF ptype THEN topContactP.y ELSE bottomContactN.y)+(start-1)*yStep; IF back THEN y_y-yStep/2; WHILE n>0 DO [] _ CDCells.IncludeOb[cell: cell, ob: ct, trans: [[x: x-ibase.x, y: y-ibase.y]]]; y _ y+yStep; n _ n-1; ENDLOOP; }; MakeVia: PUBLIC PROC [row: INT, start: INT_0, n: INT _ 1, back: BOOL _ FALSE] = { ct: CD.Object _ IF ptype THEN contactPOb ELSE contactNOb; yStep: CD.Number _ IF ptype THEN -CD.InterestSize[ct].y ELSE CD.InterestSize[ct].y; x: CD.Number _ bottomContactN.x+(row-1)*pitch; y: CD.Number _ (IF ptype THEN topContactP.y ELSE bottomContactN.y)+(start-1)*yStep; IF back THEN y_y-yStep/2; WHILE n>0 DO [] _ CDCells.IncludeOb[cell: cell, ob: xViaOb, trans: [[x: x, y: y]]]; y _ y+yStep; n _ n-1; ENDLOOP; }; ContactSize: PROC [ptype: BOOL_FALSE] RETURNS [s: CD.Position] = { ct: CD.Object _ IF ptype THEN contactPOb ELSE contactNOb; RETURN [CD.InterestSize[ct]] }; HorizontalM: PUBLIC PROC [rowL, rowR: INT, h: INT, back: BOOL_FALSE, shortStart: BOOL_TRUE, shortEnd: BOOL_TRUE] = { m: CD.Object; y1: CD.Number; x1: CD.Number _ bottomContactN.x+(rowL-1)*pitch; x2: CD.Number _ bottomContactN.x+(rowR-1)*pitch; x1 _ x1 + (IF shortStart THEN ContactSize[ptype].x-metWidth ELSE 0); x2 _ x2 + (IF shortEnd THEN metWidth ELSE ContactSize[ptype].x); IF ptype THEN { y1 _ topContactP.y-(h-1)*ContactSize[ptype].y; IF back THEN y1 _ y1+ContactSize[ptype].y-metWidth; } ELSE { y1 _ bottomContactN.y+(h-1)*ContactSize[ptype].y; IF ~back THEN y1 _ y1+ContactSize[ptype].y-metWidth; }; m _ CDRects.CreateRect[[x2-x1, metWidth], met]; [] _ CDCells.IncludeOb[cell: cell, ob: m, trans: [[x: x1, y: y1]]]; }; PassMetall: PUBLIC PROC [row: INT] = { m: CD.Object; x1: CD.Number _ bottomContactN.x+(row-1)*pitch; y1, y2: CD.Number; y2 _ topContactP.y-(8-1)*ContactSize[ptype].y+metWidth; y1 _ bottomContactN.y+4*ContactSize[ptype].y-metWidth; m _ CDRects.CreateRect[[metWidth, y2-y1], met]; [] _ CDCells.IncludeOb[cell: cell, ob: m, trans: [[x: x1, y: y1]]]; }; PassMs: PUBLIC PROC [r1, r2, r3, r4, r5, r6: INT _ -1] = { IF r1>=0 THEN PassMetall[r1]; IF r2>=0 THEN PassMetall[r2]; IF r3>=0 THEN PassMetall[r3]; IF r4>=0 THEN PassMetall[r4]; IF r5>=0 THEN PassMetall[r5]; IF r6>=0 THEN PassMetall[r6]; }; VerticalM: PUBLIC PROC [row: INT, h1, h2: INT, front: BOOL_FALSE] = { m: CD.Object; x1: CD.Number _ bottomContactN.x+(row-1)*pitch; y1, y2: CD.Number; IF ~front THEN x1 _ x1+ContactSize[ptype].x-metWidth; IF ptype THEN { h2 _ MIN[h2, 9]; y2 _ topContactP.y-(h1-1)*ContactSize[ptype].y; y1 _ topContactP.y-(h2-1)*ContactSize[ptype].y; } ELSE { h2 _ MIN[h2, 5]; y1 _ bottomContactN.y+h1*ContactSize[ptype].y; y2 _ bottomContactN.y+h2*ContactSize[ptype].y; }; y1 _ y1-metWidth; y2 _ y2+metWidth; IF ptype THEN y1 _ MAX[limitPy, y1] ELSE y2 _ MIN[y2, limitNy]; m _ CDRects.CreateRect[[metWidth, y2-y1], met]; [] _ CDCells.IncludeOb[cell: cell, ob: m, trans: [[x: x1, y: y1]]]; }; Setup: PUBLIC PROC [design: CD.Design, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21, x22: Rope.ROPE_NIL] = { SetUpInput[design]; pinOrder _ NIL; ptype _ TRUE; cell _ GetBasis[LIST[x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21, x22]]; }; SetN: PUBLIC PROC [] = { ptype _ FALSE }; PinOrder: PUBLIC PROC [r: Rope.ROPE_NIL] = { pinOrder _ r }; Finish: PUBLIC PROC [name: Rope.ROPE_NIL] RETURNS [ob: CD.Object] = { p: PROC[CD.Object] _ seeMeProc; cell _ CDUtil.Flatten[cell, NIL, NIL]; [] _ CDCells.ResizeCell[NIL, cell]; [] _ CDDirectory.Include[design: gDesign, object: cell, alternateName: name]; CDProperties.PutProp[cell, $PinOrder, pinOrder]; IF p#NIL THEN p[cell]; ob _ cell; }; GetBasis: PROC [contents: LIST OF Rope.ROPE] RETURNS [cell: CD.Object] = { cnt: INT _ 0; SubCell: PROC [n: Rope.ROPE _ NIL] = { IF ~Rope.IsEmpty[n] THEN { ib: CD.Position; subOb: CD.Object; SELECT TRUE FROM Rope.Equal[n, "p1"] => subOb _ p1Ob; Rope.Equal[n, "p2"] => subOb _ p2Ob; Rope.Equal[n, "p3"] => subOb _ p3Ob; Rope.Equal[n, "p4"] => subOb _ p4Ob; Rope.Equal[n, "weakP1"] => subOb _ specialOb; Rope.Equal[n, "connectDiffN"] => {subOb _ specialDNOb; cnt _ cnt-1}; Rope.Equal[n, "connectDiffP"] => {subOb _ specialDPOb; cnt _ cnt-1}; ENDCASE => ERROR; ib _ CD.InterestBase[subOb]; [] _ CDCells.IncludeOb[cell: cell, ob: subOb, trans: [[x: cnt*pitch-ib.x, y: -ib.y]]]; cnt _ cnt+1; }; }; cell _ CDCells.CreateEmptyCell[]; CDCells.SetSimplificationTreshhold[cell, 0.125, FALSE]; FOR l: LIST OF Rope.ROPE _ contents, l.rest WHILE l#NIL DO SubCell[l.first]; ENDLOOP }; CreateAll: CDGenerate.GeneratorProc = BEGIN child: CD.Object; cnt: INT _ 0; x, y: CD.Number _ 0; ob _ CDCells.CreateEmptyCell[]; FOR l: LIST OF RegPair _ contents, l.rest WHILE l#NIL DO child _ CDGenerate.FetchNCall[stdCell, design, l.first.name]; IF child=NIL THEN ERROR; [] _ CDCells.IncludeOb[cell: ob, ob: child, trans: [[x: x, y: y]]]; cnt _ cnt+1; x _ x+CD.InterestSize[child].x+2*pitch; IF cnt>8 THEN {x _ 0; y _ y+CD.InterestSize[child].y+4*pitch; cnt _ 0}; ENDLOOP; [] _ CDDirectory.Include[design: design, object: ob, alternateName: "All-Standard-Cells"]; END; Reset: PUBLIC PROC [] = { contents _ NIL; stdCell.Clear[]; Register["=p1=", GetP1]; Register["=p2=", GetP2]; Register["=p3=", GetP3]; Register["=p4=", GetP4]; }; RegPair: TYPE = RECORD[name: Rope.ROPE, proc: CDGenerate.GeneratorProc]; Register: PUBLIC PROC [name: Rope.ROPE, proc: CDGenerate.GeneratorProc] = { [] _ stdCell.Register[name, proc]; contents _ CONS[[name, proc], contents]; }; input: Rope.ROPE _ "StdCellBase"; user: CDGenerate.Context _ CDGenerate.AssertContext["USER"]; stdCell: CDGenerate.Context _ CDGenerate.AssertContext["STDCELLGEN"]; stdCellInput: CDGenerate.Context _ CDRemote.GetContext[input]; contents: LIST OF RegPair _ NIL; [] _ user.Register["CreateStandardCells", CreateAll, FALSE]; Reset[]; END.