DIRECTORY CD, CDBasics, CDOrient, CoreClasses, Rope, SC, SCInstUtil, SCPrivate, SCRowUtil, SCUtil, RTBasic, RTSets; SCInstUtilImpl: CEDAR PROGRAM IMPORTS CDBasics, SC, SCInstUtil, SCRowUtil, SCUtil, Rope, RTBasic, RTSets EXPORTS SCInstUtil SHARES SC = BEGIN defltLgOrien: PUBLIC SCPrivate.Orientation _ 1; defltBpOrien: PUBLIC ARRAY SC.Side OF SCPrivate.Orientation _ [3, 1, 4, 2]; InstWidth: PUBLIC PROCEDURE[inst: SCPrivate.Instance] RETURNS[width: SC.Number] = BEGIN orien: SCPrivate.OrientationOrNone _ inst.curOrien; SELECT orien FROM 0, 1, 3, 5, 6 => width _ inst.object.size.p; 2, 4, 7, 8 => width _ inst.object.size.q; ENDCASE; END; InstHeight: PUBLIC PROCEDURE[inst: SCPrivate.Instance] RETURNS[height: SC.Number] = BEGIN orien: SCPrivate.OrientationOrNone _ inst.curOrien; SELECT orien FROM 0, 1, 3, 5, 6 => height _ inst.object.size.q; 2, 4, 7, 8 => height _ inst.object.size.p; ENDCASE; END; BpHeight: PUBLIC PROCEDURE[inst: SCPrivate.Instance] RETURNS[height: SC.Number] = { IF inst.whichClass # io THEN SC.Error[programmingError, Rope.Cat["Instance: ", inst.name, " should be an IO"]]; SELECT inst.curSide FROM top, bottom => height _ InstHeight[inst]; left, right => height _ InstWidth[inst]; ENDCASE => SC.Error[programmingError, NIL]}; BpWidth: PUBLIC PROCEDURE[inst: SCPrivate.Instance] RETURNS[width: SC.Number] = { IF inst.whichClass # io THEN SC.Error[programmingError, Rope.Cat["Instance: ", inst.name, " should be an IO"]]; SELECT inst.curSide FROM top, bottom => width _ InstWidth[inst]; left, right => width _ InstHeight[inst]; ENDCASE => SC.Error[programmingError, NIL]}; MinMaxBPOffset: PUBLIC PROCEDURE[handle: SC.Handle, side: SC.Side] RETURNS [minOffset, maxOffset: SC.Number] = { InstProc: SCRowUtil.EachInstProc = { minOffset _ MIN[minOffset, instance.offset]; maxOffset _ MAX[maxOffset, instance.offset]}; minOffset _ LAST[INT]; maxOffset _ -minOffset; [] _ SCRowUtil.EnumerateAllInstsOnSide[handle, side, InstProc]}; BpOffsets: PUBLIC PROCEDURE[handle: SC.Handle, side: SC.Side, pos1, pos2: SCPrivate.ZMaxPosSr] = { layoutData: SCPrivate.LayoutData _ NARROW[handle.layoutData]; bpRow: SCPrivate.BpRow _ layoutData.bpRows[side]; offset: SC.Number; posA: SCPrivate.ZMaxPosSr _ MIN[pos1, pos2]; posB: SCPrivate.ZMaxPosSr _ MAX[pos1, pos2]; IF posA <= 1 THEN {posA _ 1; offset _ 0} ELSE {inst: SCPrivate.Instance _ bpRow.bpsOnSide[posA-1]; IF side = bottom OR side = right THEN offset _ inst.offset + InstWidth[inst] + bpRow.bpSpacing ELSE offset _ inst.offset + bpRow.bpSpacing}; IF posB = 0 OR posB > bpRow.nBpsOnSide THEN posB _ bpRow.nBpsOnSide; FOR posIndex: SCPrivate.ZMaxPosSr IN [posA .. posB] DO inst: SCPrivate.Instance _ bpRow.bpsOnSide[posIndex]; width: SC.Number _ BpWidth[inst]; IF side = bottom OR side = right THEN inst.offset _ offset ELSE inst.offset _ offset + width; offset _ offset + width + bpRow.bpSpacing; ENDLOOP}; CheckBpOffsets: PUBLIC PROCEDURE[handle: SC.Handle, side: SC.Side] = { layoutData: SCPrivate.LayoutData _ NARROW[handle.layoutData]; bpRow: SCPrivate.BpRow _ layoutData.bpRows[side]; offset: SC.Number _ 0; FOR posIndex: SCPrivate.ZMaxPosSr IN [1 .. bpRow.nBpsOnSide] DO inst: SCPrivate.Instance _ bpRow.bpsOnSide[posIndex]; width: SC.Number _ BpWidth[inst]; IF side = bottom OR side = right THEN { IF inst.offset # offset THEN SC.Error[programmingError, "Not suppose to happen"]} ELSE { IF inst.offset # offset + width THEN SC.Error[programmingError, "Not suppose to happen"]}; offset _ offset + width + bpRow.bpSpacing; ENDLOOP}; BpPos: PUBLIC PROCEDURE[handle: SC.Handle, inst: SCPrivate.Instance] RETURNS[result: SC.Number] = { layoutData: SCPrivate.LayoutData _ NARROW[handle.layoutData]; bpRow: SCPrivate.BpRow _ layoutData.bpRows[inst.curSide]; IF inst.whichClass # io THEN SC.Error[programmingError, "objet must be of type io"]; SELECT inst.curSide FROM right => result _ bpRow.sideOrg.q + inst.offset; bottom => result _ bpRow.sideOrg.p + inst.offset; left => result _ bpRow.sideOrg.q - inst.offset; top => result _ bpRow.sideOrg.p - inst.offset; ENDCASE}; InstPosOf: PUBLIC PROCEDURE[handle: SC.Handle, inst: SCPrivate.Instance, pin: SCPrivate.ObjectPin] RETURNS[pos: SCPrivate.PQPos] = { x, y, xPos, yPos: SC.Number; layoutData: SCPrivate.LayoutData _ NARROW[handle.layoutData]; SELECT pin.pinPos.side FROM bottom => {x _ pin.pinPos.location; y _ pin.pinPos.depth}; right => {x _ InstWidth[inst] - pin.pinPos.depth; y _ pin.pinPos.location}; top => {x _ InstWidth[inst] - pin.pinPos.location; y _ InstHeight[inst] - pin.pinPos.depth}; left => {x _ pin.pinPos.depth; y _ InstHeight[inst] - pin.pinPos.location}; ENDCASE; SELECT inst.curOrien FROM 1 => {xPos _ x; yPos _ y}; 2 => {xPos _ y; yPos _ InstWidth[inst] - x}; 3 => {xPos _ InstWidth[inst] - x; yPos _ InstHeight[inst] - y}; 4 => {xPos _ InstHeight[inst] - y; yPos _ x}; 5 => {xPos _ InstWidth[inst] - x; yPos _ y}; 6 => {xPos _ x; yPos _ InstHeight[inst] - y}; 7 => {xPos _ y; yPos _ x}; 8 => {xPos _ InstHeight[inst] - y; yPos _ InstWidth[inst] - x}; ENDCASE; SELECT inst.whichClass FROM logic, ft => { lgRow: SCPrivate.LgRow _ layoutData.lgRows.rows[inst.curRow]; pos _ [lgRow.rowOrg.p + inst.offset + xPos, lgRow.rowOrg.q + yPos]}; io => { bpRow: SCPrivate.BpRow _ layoutData.bpRows[inst.curSide]; SELECT inst.curSide FROM right => pos _ [bpRow.sideOrg.p + xPos, bpRow.sideOrg.q + inst.offset + yPos]; bottom => pos _ [bpRow.sideOrg.p + inst.offset + xPos, bpRow.sideOrg.q + yPos]; left => pos _ [bpRow.sideOrg.p + xPos, bpRow.sideOrg.q - inst.offset + yPos]; top => pos _ [bpRow.sideOrg.p - inst.offset + xPos, bpRow.sideOrg.q + yPos]; ENDCASE}; ENDCASE}; PosOf: PUBLIC PROCEDURE[inst: SCPrivate.Instance, pin: SCPrivate.ObjectPin] RETURNS [pinDes: SCInstUtil.PinDescription] = { x, y: SC.Number; SELECT pin.pinPos.side FROM bottom => {x _ pin.pinPos.location; y _ pin.pinPos.depth}; right => {x _ InstWidth[inst] - pin.pinPos.depth; y _ pin.pinPos.location}; top => {x _ InstWidth[inst] - pin.pinPos.location; y _ InstHeight[inst] - pin.pinPos.depth}; left => {x _ pin.pinPos.depth; y _ InstHeight[inst] - pin.pinPos.location}; ENDCASE; SELECT inst.curOrien FROM 1 => {pinDes.xPos _ x; pinDes.yPos _ y}; 2 => {pinDes.xPos _ y; pinDes.yPos _ InstWidth[inst] - x}; 3 => {pinDes.xPos _ InstWidth[inst] - x; pinDes.yPos _ InstHeight[inst] - y}; 4 => {pinDes.xPos _ InstHeight[inst] - y; pinDes.yPos _ x}; 5 => {pinDes.xPos _ InstWidth[inst] - x; pinDes.yPos _ y}; 6 => {pinDes.xPos _ x; pinDes.yPos _ InstHeight[inst] - y}; 7 => {pinDes.xPos _ y; pinDes.yPos _ x}; 8 => {pinDes.xPos _ InstHeight[inst] - y; pinDes.yPos _ InstWidth[inst] - x}; ENDCASE; pinDes.sideOn _ SCUtil.SideTranslate[pin.pinPos.side, inst.curOrien]}; RotateRect: PUBLIC PROCEDURE[inst: SCPrivate.Instance, defRect: SC.Rect] RETURNS [SC.Rect] = { newRect: SC.Rect; SELECT inst.curOrien FROM 1 => {newRect.x1 _ defRect.x1; newRect.y1 _ defRect.y1; newRect.x2 _ defRect.x2; newRect.y2 _ defRect.y2}; 2 => {newRect.x1 _ defRect.y1; newRect.y1 _ InstWidth[inst] - defRect.x1; newRect.x2 _ defRect.y2; newRect.y2 _ InstWidth[inst] - defRect.x2}; 3 => {newRect.x1 _ InstWidth[inst] - defRect.x1; newRect.y1 _ InstHeight[inst] - defRect.y1; newRect.x2 _ InstWidth[inst] - defRect.x2; newRect.y2 _ InstHeight[inst] - defRect.y2}; 4 => {newRect.x1 _ InstHeight[inst] - defRect.y1; newRect.y1 _ defRect.x1; newRect.x2 _ InstHeight[inst] - defRect.y2; newRect.y2 _ defRect.x2}; 5 => {newRect.x1 _ InstWidth[inst] - defRect.x1; newRect.y1 _ defRect.y1; newRect.x2 _ InstWidth[inst] - defRect.x2; newRect.y2 _ defRect.y2}; 6 => {newRect.x1 _ defRect.x1; newRect.y1 _ InstHeight[inst] - defRect.y1; newRect.x2 _ defRect.x2; newRect.y2 _ InstHeight[inst] - defRect.y2}; 7 => {newRect.x1 _ defRect.y1; newRect.y1 _ defRect.x1; newRect.x2 _ defRect.y2; newRect.y2 _ defRect.x2}; 8 => {newRect.x1 _ InstHeight[inst] - defRect.y1; newRect.y1 _ InstWidth[inst] - defRect.x1; newRect.x2 _ InstHeight[inst] - defRect.y2; newRect.y2 _ InstWidth[inst] - defRect.x2}; ENDCASE; RETURN[CDBasics.NormalizeRect[newRect]]}; LgOffsets: PUBLIC PROCEDURE[handle: SC.Handle, row: SCPrivate.ZMaxRowSr, pos1, pos2: SCPrivate.ZMaxPosSr] = { layoutData: SCPrivate.LayoutData _ NARROW[handle.layoutData]; lgRows: SCPrivate.LgRows _ layoutData.lgRows; lgRow: SCPrivate.LgRow _ lgRows.rows[row]; offset: SC.Number; posA: SCPrivate.ZMaxPosSr _ MIN[pos1, pos2]; posB: SCPrivate.ZMaxPosSr _ MAX[pos1, pos2]; IF posA <= 1 THEN {posA _ 1; offset _ 0} ELSE {inst: SCPrivate.Instance _ lgRow.lgsOnRow[posA-1]; offset _ inst.offset + InstWidth[inst]}; IF posB = 0 OR posB > lgRow.nLgsOnRow THEN posB _ lgRow.nLgsOnRow; FOR posIndex: SCPrivate.MaxPosSr IN [posA .. posB] DO inst: SCPrivate.Instance _ lgRow.lgsOnRow[posIndex]; SELECT inst.whichClass FROM ft, logic => {inst.offset _ offset; offset _ offset + InstWidth[inst]}; ENDCASE; ENDLOOP; IF posB = lgRow.nLgsOnRow THEN {lgRow.size.p _ offset; IF lgRow.size.p >= lgRows.maxRowWidth THEN {lgRows.maxRowWidth _ lgRow.size.p; lgRows.numMaxRows _ 1} ELSE [lgRows.maxRowWidth, lgRows.numMaxRows] _ SCRowUtil.FindMaxRow[handle]}}; AllOffsets: PUBLIC PROCEDURE [handle: SC.Handle] = { RowRroc: SCRowUtil.EachRowProc = { LgOffsets[handle, row, 0, SCPrivate.maxPos]}; SideProc: SCRowUtil.EachSideProc = { BpOffsets[handle, side, 0, SCPrivate.maxPos]}; [] _ SCRowUtil.EnumerateRows[handle, RowRroc]; [] _ SCRowUtil.EnumerateSides[handle, SideProc]}; AsgnChanPos: PUBLIC PROCEDURE[handle: SC.Handle] = BEGIN EachSide: SCRowUtil.EachSideProc = { IF bpRow.dimInvalid THEN SCRowUtil.ComputeSideHeight[handle, side]; sideDim[side] _ bpRow.size.p + (bpRow.nBpsOnSide -1) * bpRow.bpSpacing}; EachRow: SCRowUtil.EachRowProc = { IF lgRow.dimInvalid THEN SCRowUtil.ComputeRowHeight[handle, lgRow.rowNum]}; layoutData: SCPrivate.LayoutData _ NARROW[handle.layoutData]; parms: SCPrivate.Parms _ NARROW[handle.parms]; lgRows: SCPrivate.LgRows _ layoutData.lgRows; bpRows: SCPrivate.BpRows _ layoutData.bpRows; sideChans: SCPrivate.SideChans _ layoutData.sideChans; rowChans: SCPrivate.RowChans _ layoutData.rowChans; nChans: SCPrivate.MaxChanSr _ rowChans.count; pitch: SC.Number _ RTBasic.IRSize[parms.ftObject.cdOb].x; sideDim: ARRAY SC.Side OF SC.Number; upperActiveLimit, rightActiveLimit, realTotHeight: SC.Number; [] _ SCRowUtil.EnumerateSides[handle, EachSide]; [] _ SCRowUtil.EnumerateRows[handle, EachRow]; rowChans.chans[1].chanPos _ bpRows[bottom].size.q; sideChans[left].sideChanPos _ bpRows[left].size.q; lgRows.horzRowOrg _ bpRows[left].size.q + sideChans[left].sideChanResult; lgRows.rows[1].rowOrg.p _ lgRows.horzRowOrg + ((lgRows.maxRowWidth - lgRows.rows[1].size.p)/2)/pitch*pitch; lgRows.rows[1].rowOrg.q _ rowChans.chans[1].chanPos + rowChans.chans[1].chanResult; FOR chan: SCPrivate.MaxChanSr IN [2 .. nChans] DO rowChans.chans[chan].chanPos _ lgRows.rows[chan-1].rowOrg.q + lgRows.rows[chan-1].size.q; IF chan <= lgRows.count THEN { lgRows.rows[chan].rowOrg.q _ rowChans.chans[chan].chanPos + MAX[rowChans.chans[chan].chanWidth, rowChans.chans[chan].minChanWidth]; lgRows.rows[chan].rowOrg.p _ lgRows.horzRowOrg + ((lgRows.maxRowWidth - lgRows.rows[chan].size.p)/2)/pitch*pitch}; ENDLOOP; sideChans[right].sideChanPos _ lgRows.horzRowOrg + lgRows.maxRowWidth; upperActiveLimit _ rowChans.chans[nChans].chanPos + MAX[rowChans.chans[nChans].chanWidth, rowChans.chans[nChans].minChanWidth]; layoutData.totHeight _ realTotHeight _ upperActiveLimit + bpRows[top].size.q; rightActiveLimit _ sideChans[right].sideChanPos + MAX[sideChans[right].sideChanWidth, sideChans[right].minSideChanWidth]; layoutData.totWidth _ rightActiveLimit + bpRows[right].size.q; bpRows[bottom].sideOrg.q _ 0; bpRows[bottom].sideOrg.p _ lgRows.horzRowOrg + (lgRows.maxRowWidth - sideDim[bottom]) / 2; bpRows[right].sideOrg.p _ rightActiveLimit; bpRows[right].sideOrg.q _ (realTotHeight - sideDim[right])/ 2; bpRows[top].sideOrg.p _ lgRows.horzRowOrg + (lgRows.maxRowWidth + sideDim[top])/ 2; bpRows[top].sideOrg.q _ upperActiveLimit; bpRows[left].sideOrg.p _ 0; bpRows[left].sideOrg.q _ (realTotHeight +sideDim[left])/ 2; END; ChansForInsts: PUBLIC PROCEDURE[handle: SC.Handle, insts: SCPrivate.InstanceList] RETURNS [touchesChan: SCPrivate.ChanSet _ RTSets.RTMdSetEmpty] = { layoutData: SCPrivate.LayoutData _ NARROW[handle.layoutData]; FOR instList: SCPrivate.InstanceList _ insts, instList.rest WHILE instList # NIL DO inst: SCPrivate.Instance _ instList.first; SELECT inst.whichClass FROM ft, logic => {IF inst.curRow > 0 THEN {touchesChan _ RTSets.RTMdSetUnion[touchesChan, RTSets.RTMdSetGenerateElement[(inst.curRow+1)-1]]; touchesChan _ RTSets.RTMdSetUnion[touchesChan , RTSets.RTMdSetGenerateElement[(inst.curRow)-1]]}}; io => {IF inst.curSide = bottom THEN touchesChan _ RTSets.RTMdSetUnion[touchesChan, RTSets.RTMdSetGenerateElement[(1)-1]]; IF inst.curSide = top THEN touchesChan _ RTSets.RTMdSetUnion[touchesChan, RTSets.RTMdSetGenerateElement[(layoutData.rowChans.count)-1]]}; ENDCASE; ENDLOOP}; CheckInst: PUBLIC PROCEDURE[handle: SC.Handle, inst: SCPrivate.Instance] = { layoutData: SCPrivate.LayoutData _ NARROW[handle.layoutData]; SELECT inst.whichClass FROM logic, ft => {row: SC.Number _ inst.curRow; pos: SC.Number _ inst.curPos; lgRow: SCPrivate.LgRow _ layoutData.lgRows.rows[row]; IF row <= 0 OR row > layoutData.rowChans.count THEN {IF ~(row = 0 AND pos = 0 AND inst.whichClass = ft) THEN SC.Error[programmingError, " "]} ELSE IF pos <= 0 OR pos > lgRow.nLgsOnRow THEN SC.Error[programmingError, " "] ELSE {trialInst: SCPrivate.Instance _ lgRow.lgsOnRow[pos]; IF inst # trialInst THEN SC.Error[programmingError, " "]}}; io => {side: SC.Side _ inst.curSide; pos: SC.Number _ inst.curPos; bpRow: SCPrivate.BpRow _ layoutData.bpRows[side]; IF side = none THEN SC.Error[programmingError, " "] ELSE IF pos <= 0 OR pos > bpRow.nBpsOnSide THEN SC.Error[programmingError, " "] ELSE {trialInst: SCPrivate.Instance _ bpRow.bpsOnSide[pos]; IF inst # trialInst THEN SC.Error[programmingError, " "]}}; ENDCASE}; CheckInsts: PUBLIC PROCEDURE[handle: SC.Handle] = { EachInst: SCInstUtil.EachInstanceProc = { CheckInst[handle, instance]}; [] _ SCInstUtil.EnumerateAllInstances[handle, EachInst]}; EnumerateAllInstances: PUBLIC PROC [handle: SC.Handle, eachInstance: SCInstUtil.EachInstanceProc] RETURNS [quit: BOOL] = { structureData: SCPrivate.StructureData _ NARROW[handle.structureData]; quit _ EnumerateInstances[handle, 1, structureData.instances.count, eachInstance]}; EnumerateInstances: PUBLIC PROC [handle: SC.Handle, startInst, stopInst: SCPrivate.MaxInstanceSr, eachInstance: SCInstUtil.EachInstanceProc] RETURNS [quit: BOOL _ FALSE] = { structureData: SCPrivate.StructureData _ NARROW[handle.structureData]; FOR inst: SCPrivate.MaxInstanceSr IN [startInst .. stopInst] WHILE ~quit DO quit _ eachInstance[structureData.instances.inst[inst]]; ENDLOOP}; EnumeratePinsOnInst: PUBLIC PROC [instance: SCPrivate.Instance, eachPin: SCInstUtil.EachPinProc] RETURNS [quit: BOOL _ FALSE] = { FOR pin: NAT IN [0 .. instance.pinNets.size) WHILE ~quit DO quit _ eachPin[instance, pin, instance.pinNets.n[pin]]; ENDLOOP}; DefineInstance: PUBLIC PROCEDURE [handle: SC.Handle, instanceName: Rope.ROPE, object: SCPrivate.Object, coreInstance: CoreClasses.CellInstance, equivName: Rope.ROPE _ NIL] RETURNS [instance: SCPrivate.Instance _ NIL] = { structureData: SCPrivate.StructureData _ NARROW[handle.structureData]; instances: SCPrivate.Instances _ structureData.instances; object.numTimesUsed _ object.numTimesUsed + 1; SELECT object.typeClass FROM logic => {instance _ NEW[logic SCPrivate.InstanceRec]; instance.whichClass _ logic; instances.numLogics _ instances.numLogics + 1}; ft => {instance _ NEW[ft SCPrivate.InstanceRec]; instance.whichClass _ ft; instances.numFts _ instances.numFts + 1}; io => {instance _ NEW[io SCPrivate.InstanceRec]; instance.equivPortClass _ equivName; instance.whichClass _ io; instances.numIOs _ instances.numIOs + 1}; ENDCASE => SC.Error[callingError, Rope.Cat["Feedthrus not allowed in input: ", instance.name, ", object: ", object.name, "\n"]]; instance.name _ instanceName; instance.object _ object; instance.pinNets _ NEW[SCPrivate.PinNetsRec[object.numPins]]; instances.count _ instances.count + 1; instance.num _ instances.count; instances.inst[instances.count] _ instance}; NumInstsOnList: PUBLIC PROCEDURE [instances: SCPrivate.InstanceList] RETURNS [count: SCPrivate.ZMaxInstanceSr _ 0] = { FOR instList: SCPrivate.InstanceList _ instances, instList.rest WHILE instList # NIL DO count _ count + 1; ENDLOOP}; CDOrien: PUBLIC PROCEDURE[instance: SCPrivate.Instance] RETURNS [orien: CD.Orientation] = { SELECT instance.curOrien FROM 0 => orien _ CDOrient.original; 1 => orien _ CDOrient.original; 2 => orien _ CDOrient.rotate270; 3 => orien _ CDOrient.rotate180; 4 => orien _ CDOrient.rotate90; 5 => orien _ CDOrient.mirrorX; 6 => orien _ CDOrient.rotate180X; 7 => orien _ CDOrient.rotate270X; 8 => orien _ CDOrient.rotate90X; ENDCASE}; END. ΚSCInstUtilImpl.mesa Copyright c 1986 by Xerox Corporation. All rights reserved. Preas April 9, 1986 3:26:51 pm PST compoments utility routines -- InstWidth - find width of component at current orientation -- InstHeight - find height of component at current orientation -- BpHeight - find height of bp when considering side it is on -- BpWidth - find width of bp when considering side it is on -- MinMaxBPOffset - find min and max offsets of bonding pads on side -- BpOffsets - find offsets of bonding pads on side -- BpPos - find position of inst on side -- PosOf- find the position (side, x, and y) of a component on a pin -- RotateRect- Rotate a rectangle of a cell -- LgOffsets- determine offsets of components in row -- AllOffsets - determine all component offsets -- AsgnChanPos - assign current positions to horizontal and vertical channels -- CheckInsts - check row and position of comps -- CheckInst - check row and position of a inst -- EnumeratePinsOnInst - enumerate the net pins on an instance find width of component at current orientation find current orientation now get width based on orientation find height of component at current orientation find current orientation now get height based on orientation find height of bp when considering its side (this is, the dimension perpendicular to side) find height of bp when considering side it is on this is along to side find offsets of bonding pads on side find offsets of bonding pads on side check offsets of bonding pads on side find position of inst on side assumes that channel and bp positions have been assigned. find position of pin on an inst assumes that channel and instance positions have been assigned. this code is copied from PosOf for efficiency first find the position at normal orientation now rotate the pin position to current orien find the position (side, x, and y) of a component on a pin first find the position at normal orientation now rotate the pin position to current orien find the position of a rotated rectangle wintin a component now rotate the pin position to current orien determine offsets of components in row compute offsets of all comps on row update max row widths determine all component offsets assign current positions to horizontal and vertical channels compute the minimum channel dimensions row 1 and channel 1 data now the interior channels now the right side get total height and width now update the side orgs update right side data update top side data update left side data find chans that these comps touch check row and position of a inst check row and position of a inst define a component (an instance of object) construct he instance record initialize the nets connected to these pins get the CD orientation Κ­˜šœ™Icodešœ Οmœ1™Jšœžœ2™J˜šΟk ˜ JšŸœ˜J˜ J˜ J˜ Jšœ˜JšŸœ˜Jšœ ˜ Jšœ ˜ Jšœ ˜ J˜J˜Jšœ˜J˜—šžœŸœŸ˜JšŸœ Ÿœ6˜JJšŸœ ˜JšŸœŸœ˜ J˜JšŸ˜JšœŸœ˜/Jš œŸœŸœŸœŸœ&˜KJ˜—˜Jšœ.™.š ž œŸœŸ œŸœŸœ ˜RJ˜JšŸ˜Jšœ™Jšœ3˜3J˜Jšœ"™"šŸœŸ˜Jšœ,˜,Jšœ)˜)JšŸœ˜—JšŸœ˜J˜—Jšœ/™/š ž œŸœŸ œŸœ Ÿœ ˜TJ˜JšŸ˜Jšœ™šœ3˜3J˜—Jšœ$™$šŸœŸ˜Jšœ-˜-Jšœ*˜*JšŸœ˜—JšŸœ˜J˜—Jšœ+™+Jšœ/™/š žœŸœŸ œŸœ Ÿœ ˜SJ˜šŸœŸ˜JšŸœP˜RJ˜—šŸœŸ˜Jšœ)˜)Jšœ(˜(JšŸœŸœŸœ˜,J˜——Jšœ0™0Jšœ™š žœŸœŸ œŸœŸœ ˜QJ˜šŸœŸ˜JšŸœP˜RJ˜—šŸœŸ˜Jšœ'˜'Jšœ(˜(JšŸœŸœŸœ˜,—J™—Jšœ%™%šžœŸœŸ œ ŸœŸœŸœŸœ ˜pJ˜šžœ˜$Jšœ Ÿœ˜,Jšœ Ÿœ˜-J˜—Jšœ ŸœŸœ˜Jšœ˜Jšœ@˜@J˜—Jšœ%™%š ž œŸœŸ œ ŸœŸœ+˜bJ˜Kšœ#Ÿœ˜=Kšœ1˜1JšœŸœ˜JšœŸœ ˜,JšœŸœ ˜,JšŸœ Ÿœ˜(šŸ˜Jšœ4˜4JšŸœŸœŸœ9˜^JšŸœ)˜-—JšŸœ ŸœŸœ˜DJ˜šŸœŸœŸœ˜7Jšœ5˜5JšœŸœ˜!JšŸœŸœŸœ˜:JšŸœ˜"Jšœ*˜*JšŸœ˜ —J˜—Jšœ&™&š žœŸœŸ œ ŸœŸœ ˜FJ˜Kšœ#Ÿœ˜=Kšœ1˜1JšœŸœ ˜J˜šŸœŸœŸœ˜@Jšœ5˜5JšœŸœ˜!šŸœŸœŸœ˜'KšŸœŸœ5˜Q—šŸœ˜JšŸœŸœ6˜Z—Jšœ*˜*JšŸœ˜ —J˜—Jšœ™Jšœ9™9š žœŸœŸ œ Ÿœ#Ÿœ Ÿœ ˜cJ˜Kšœ#Ÿœ˜=Kšœ9˜9šŸœŸ˜JšŸœ5˜7—šŸœŸ˜Jšœ0˜0Jšœ1˜1Jšœ/˜/Jšœ.˜.JšŸœ˜ —J˜—Jšœ™Jšœ?™?š ž œŸœŸ œ Ÿœ=Ÿœ˜„J˜JšœŸœ˜Kšœ#Ÿœ˜=J™Jšœžœ™-Jšœ.™.šŸœŸ˜Jšœ:˜:JšœK˜KJšœ\˜\JšœK˜KšŸœ˜ J˜——Jšœ-™-šŸœŸ˜Jšœ˜Jšœ,˜,Jšœ?˜?Jšœ-˜-Jšœ,˜,Jšœ-˜-Jšœ˜Jšœ?˜?JšŸœ˜J˜—šŸœŸ˜šœ˜Kšœ=˜=JšœD˜D—šœ˜Kšœ9˜9šŸœŸ˜JšœN˜NJšœO˜OJšœM˜MJšœL˜LJšŸœ˜ ——JšŸœ˜ —J˜—J˜Jšœ;™;šžœŸœŸ œ4˜KJšŸœ(˜/J˜JšœŸœ˜J™Jšœ.™.šŸœŸ˜Jšœ:˜:JšœK˜KJšœ\˜\JšœK˜KšŸœ˜ J˜——Jšœ-™-šŸœŸ˜Jšœ(˜(Jšœ:˜:JšœM˜MJšœ;˜;Jšœ:˜:Jšœ;˜;Jšœ(˜(JšœM˜MJšŸœ˜—J˜JšœF˜FJ˜—Jšœ;™;šž œŸœŸ œ$Ÿœ˜HJšŸœŸœ ˜J˜Jšœ-™-Jšœ Ÿœ˜šŸœŸ˜šœ˜Jšœ2˜2Jšœ2˜2—šœ˜JšœD˜DJšœD˜D—šœ˜JšœW˜WJšœW˜W—šœ˜JšœE˜EJšœE˜E—šœ˜JšœD˜DJšœD˜D—šœ˜JšœE˜EJšœE˜E—šœ˜Jšœ2˜2Jšœ2˜2—šœ˜JšœW˜WJšœW˜W—JšŸœ˜—JšŸœ#˜)J˜—Jšœ'™'šž œŸœŸ œ ŸœG˜mJ˜Jšœ#™#Jšœ#Ÿœ˜=Jšœ-˜-Jšœ*˜*JšœŸœ˜JšœŸœ ˜,JšœŸœ ˜,JšŸœ Ÿœ˜(šŸ˜Jšœ3˜3Jšœ(˜(—JšŸœ ŸœŸœ˜BJ˜šŸœŸœŸœ˜6Jšœ4˜4šŸœŸ˜JšœG˜GJšŸœ˜—JšŸœ˜J˜—Jšœ™šŸœŸ˜Jšœ˜šŸœ$Ÿ˜*Jšœ:˜:—JšŸœK˜O—J˜—Jšœ ™ šž œŸœŸ œ Ÿœ ˜4J˜šžœ˜"Jšœ-˜-—šžœ˜$Jšœ.˜.—Jšœ.˜.Jšœ1˜1J˜—Jšœ=™=šž œŸœŸ œ Ÿœ ˜3J˜JšŸ˜Jšœ&™&šžœ˜$JšŸœŸœ+˜CJšœH˜HJ˜—šžœ˜"JšŸœŸœ3˜KJ˜—Jšœ#Ÿœ˜=JšœŸœ˜.Jšœ-˜-Jšœ-˜-Jšœ6˜6Jšœ3˜3Jšœ-˜-Jšœ9˜9Jš œ ŸœŸœŸœŸœ˜$Jšœ3Ÿœ˜=J˜Jšœ0˜0J˜Jšœ.˜.J˜Jšœ™Jšœ2˜2Jšœ2˜2J˜JšœI˜IJšœk˜kJšœS˜SJ˜Jšœ™šŸœŸœŸœ˜2JšœY˜YšŸœŸœ˜Jšœ<ŸœD˜ƒJšœr˜r—šŸœ˜J˜—Jšœ™šœF˜FJ˜—Jšœ™J˜Jšœ4ŸœH˜JšœM˜MJ˜šœ1˜1JšŸœD˜G—J˜Jšœ>˜>J˜Jšœ™Jšœ˜šœZ˜ZJ˜—Jšœ™Jšœ+˜+šœ>˜>J˜—Jšœ™JšœS˜Sšœ)˜)J˜—Jšœ™Jšœ˜Jšœ;˜;JšŸœ˜—J˜—Jšœ"™"šž œŸœŸ œ Ÿœ'˜QJšŸœ;˜BJ˜Jšœ#Ÿœ˜=šŸœ9Ÿœ ŸœŸœ˜TJšœ*˜*šŸœŸ˜šœŸœŸ˜%šœb˜bJšœb˜b——šœŸœŸ˜$JšœU˜UšŸœŸ˜Jšœn˜n——JšŸœ˜—JšŸœ˜ —J˜—Jšœ!™!šž œŸœŸ œ Ÿœ&˜LJšœ#Ÿœ˜=šŸœŸ˜šœ ˜ KšœŸœ˜KšœŸœ˜Kšœ5˜5šŸœ Ÿœ!Ÿ˜3šœŸœ Ÿœ ŸœŸ˜8KšŸœ˜ ——šŸœŸœ ŸœŸ˜.KšŸœ˜—šŸ˜Jšœ5˜5šŸœŸ˜KšŸœ ˜"———šœ˜KšœŸœ˜KšœŸœ˜Kšœ1˜1šŸœ Ÿ˜KšŸœ˜—šŸœŸœ ŸœŸ˜/KšŸœ˜—šŸ˜Jšœ6˜6šŸœŸ˜KšŸœ ˜"———JšŸœ˜ —J˜—Jšœ!™!šž œŸœŸ œ Ÿœ ˜3J˜šžœ!˜)Jšœ˜—Kšœ9˜9K˜—š žœŸœŸœ Ÿœ4ŸœŸœ˜zJ˜Jšœ)Ÿœ˜FJšœS˜SK˜—šžœŸœŸœ ŸœbŸœŸœŸœ˜­J˜Jšœ)Ÿœ˜FšŸœŸœŸœŸ˜KJšœ8˜8KšŸœ˜ —K˜—š žœŸœŸœAŸœŸœŸœ˜K˜š ŸœŸœŸœŸœŸœ˜