CoreRouteModel.mesa
Copyright Ó 1988 by Xerox Corporation. All rights reserved.
Don Curry July 4, 1988 6:50:22 am PDT
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
Types and constants
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;
Model Layout Proc
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: BOOLFALSE] = {
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.RectCD.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: BOOLFALSE] = {
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};
[]𡤌oreGeometry.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] ] };
Register layout atom
[] ← PWCore.RegisterLayoutAtom[$Model, ModelLayout, NIL, NIL];
END.