<> <> <> <<>> DIRECTORY CD, CDBasics, CDInstances, CDRects, CDSimpleRules, Core, CoreGeometry, CoreOps, CoreRoute, IO, PW, PWCore, Rope, Sisyph; CoreRouteModel: CEDAR PROGRAM IMPORTS CD, CDBasics, CDInstances, CDRects, CDSimpleRules, CoreGeometry, CoreOps, CoreRoute, PW, PWCore, Rope, Sisyph = BEGIN <> CellType: TYPE = Core.CellType; Wire: TYPE = Core.Wire; technologyKey: ATOM _ $cmosB; L1: INT _ CDSimpleRules.GetTechnology[technologyKey].lambda; L2: INT _ 2*L1; L4: INT _ 2*L2; schDeco: CoreGeometry.Decoration _ Sisyph.mode.decoration; layDeco: CoreGeometry.Decoration _ PWCore.extractMode.decoration; <> ModelLayout: PWCore.LayoutProc = { AddRect: PROC[wire: Wire, ir: CD.Rect] = { IF ir.x2=ir.x1 THEN { rect: CD.Object _ CDRects.CreateRect[[L4, L4*(ir.y2-ir.y1)], verLayer]; isPin: BOOL _ ir.y1=0 OR ir.y2=max.y; AddPositionedObject[wire, rect, [ir.x1*L4-L2, ir.y1*L4], isPin]}; IF ir.y2=ir.y1 THEN { rect: CD.Object _ CDRects.CreateRect[[L4*(ir.x2-ir.x1), L4], horLayer]; isPin: BOOL _ ir.x1=0 OR ir.x2=max.x; AddPositionedObject[wire, rect, [ir.x1*L4, ir.y1*L4-L2], isPin]}}; AddVia: PROC[wire: Wire, row, col: INT] = { via: CD.Object _ CDSimpleRules.Contact[technologyKey, verLayer, horLayer]; AddPositionedObject[wire, via, [col*L4-L2, row*L4-L2]]}; AddPositionedObject: PROC [wire: Wire, obj: CD.Object, pos: CD.Position, isPin: BOOL _ FALSE] = { cdInstances _ CONS [CDInstances.NewInst[obj, [pos]], cdInstances]; IF isPin THEN { inst: CoreGeometry.Instance _ [cdInstances.first.ob, cdInstances.first.trans]; CoreGeometry.AddPins[layDeco, wire, LIST[inst]]}}; cdInstances: CD.InstanceList _ NIL; array: Array; Array: TYPE = REF ArrayRec; ArrayRec: TYPE = RECORD[SEQUENCE size: NAT OF Row]; Row: TYPE = REF RowRec; RowRec: TYPE = RECORD[SEQUENCE size: NAT OF HorVerWire]; HorVerWire: TYPE = RECORD[hor, ver: Wire]; ir: CD.Rect _ CD.InterestRect[CoreGeometry.GetObject[schDeco, cellType]]; irSize: CD.Position _ CDBasics.SizeOfRect[ir]; max: CD.Position _ [(irSize.x + L1)/L2, (irSize.y + L1)/L2]; horLayer: CD.Layer; verLayer: CD.Layer; name: IO.ROPE _ CoreOps.GetCellTypeName[cellType]; eachAtomic: PROC[wire: Wire] = { eachInstance: PROC [instance: CoreGeometry.Instance] RETURNS [quit: BOOL _ FALSE] = { bb: CD.Rect _ CoreGeometry.BBox[instance]; pos1: CD.Position _ [(bb.x1 - ir.x1 + L1)/L2, (bb.y1 - ir.y1 + L1)/L2]; pos2: CD.Position _ [(bb.x2 - ir.x1 + L1)/L2, (bb.y2 - ir.y1 + L1)/L2]; size: CD.Position _ [pos2.x - pos1.x, pos2.y - pos1.y]; IF (size.x=0) # (size.y=0) THEN FOR row: INT IN [pos1.y .. pos2.y] DO FOR col: INT IN [pos1.x .. pos2.x] DO IF size.x #0 THEN array[row][col].hor _ wire; IF size.y #0 THEN array[row][col].ver _ wire; ENDLOOP ENDLOOP}; []_CoreGeometry.EnumerateGeometry[schDeco, wire, eachInstance]}; [verLayer, horLayer] _ CoreRoute.GetCellTypePropLayer[cellType, $VerticalMetal, $met2]; array _ NEW[ArrayRec[max.y+1]]; FOR row: INT IN [0..array.size) DO array[row] _ NEW[RowRec[max.x+1]]; FOR col: INT IN [0..array[row].size) DO array[row][col] _ [NIL, NIL] ENDLOOP ENDLOOP; CoreOps.VisitRootAtomics[cellType.public, eachAtomic]; FOR row: INT IN [0..array.size) DO begin: INT _ 0; wire: Wire _ NIL; FOR col: INT IN [0..array[row].size) DO IF wire # array[row][col].hor THEN { IF wire#NIL THEN AddRect[wire, [begin, row, col-1, row]]; wire _ array[row][col].hor; begin _ col; LOOP}; IF col=(array[row].size-1) AND wire#NIL THEN AddRect[wire, [begin, row, col, row]]; ENDLOOP ENDLOOP; FOR col: INT IN [0..array[0].size) DO begin: INT _ 0; wire: Wire _ NIL; FOR row: INT IN [0..array.size) DO IF wire # array[row][col].ver THEN { IF wire#NIL THEN AddRect[wire, [col, begin, col, row-1]]; wire _ array[row][col].ver; begin _ row; LOOP}; IF row=array.size-1 AND wire#NIL THEN AddRect[wire, [col, begin, col, row]]; ENDLOOP ENDLOOP; FOR row: INT IN [0..array.size) DO FOR col: INT IN [0..array[row].size) DO IF array[row][col].hor = array[row][col].ver AND array[row][col].hor#NIL THEN AddVia[array[row][col].hor, row, col] ENDLOOP ENDLOOP; obj _ PW.CreateCell [instances: cdInstances, name: name.Cat[".mask"], ir: [0,0, max.x*L4, max.y*L4] ] }; <> [] _ PWCore.RegisterLayoutAtom[$Model, ModelLayout, NIL, NIL]; END.