DIRECTORY CD, CDBasics, CoreClasses, CoreFlat, RefTab, Rope, RTBasic, RTSets, SC, SCInstUtil, SCPrivate, SCRowUtil, SCUtil; SCInstUtilImpl: CEDAR PROGRAM IMPORTS CDBasics, CoreFlat, RefTab, Rope, RTBasic, RTSets, SC, SCInstUtil, SCRowUtil, SCUtil EXPORTS SCInstUtil SHARES SC = BEGIN defltLgOrien: PUBLIC SCPrivate.Orientation _ 1; defltBpOrien: PUBLIC ARRAY SC.Side OF SCPrivate.Orientation _ [3, 1, 4, 2]; InstWidth: PUBLIC PROC[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 PROC[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 PROC[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 PROC[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 PROC[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 _ FIRST[INT]; [] _ SCRowUtil.EnumerateAllInstsOnSide[handle, side, InstProc]}; BpOffsets: PUBLIC PROC[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 PROC[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 PROC[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 left, right => result _ bpRow.sideOrg.q + inst.offset; bottom, top => result _ bpRow.sideOrg.p + inst.offset; ENDCASE}; InstPosOf: PUBLIC PROC[handle: SC.Handle, inst: SCPrivate.Instance, pin: SCPrivate.ObjectPin] RETURNS[pos: RTBasic.PQPos] = { layoutData: SCPrivate.LayoutData _ NARROW[handle.layoutData]; xy: CD.Position _ SELECT pin.pinPos.side FROM bottom => [pin.pinPos.location, pin.pinPos.depth], right => [InstWidth[inst] - pin.pinPos.depth, pin.pinPos.location], top => [pin.pinPos.location, InstHeight[inst] - pin.pinPos.depth], left => [pin.pinPos.depth, pin.pinPos.location], ENDCASE => SC.Error[programmingError, "No suppose to happen"]; xyPos: CD.Position _ SELECT inst.curOrien FROM 1 => [xy.x, xy.y], -- original 2 => [xy.y, InstWidth[inst] - xy.x], -- rotate270 3 => [InstWidth[inst] - xy.x, InstHeight[inst] - xy.y], -- rotate180 4 => [InstHeight[inst] - xy.y, xy.x], -- rotate90 5 => [InstWidth[inst] - xy.x, xy.y], -- mirrorX 6 => [xy.x, InstHeight[inst] - xy.y], -- rotate180X 7 => [xy.y, xy.x], -- rotate270X 8 => [InstHeight[inst] - xy.y, InstWidth[inst] - xy.x], -- rotate90X ENDCASE => SC.Error[programmingError, "No suppose to happen"]; SELECT inst.whichClass FROM logic, ft => { lgRow: SCPrivate.LgRow _ layoutData.lgRows.rows[inst.curRow]; pos _ [lgRow.rowOrg.p + inst.offset + xyPos.x, lgRow.rowOrg.q + xyPos.y]}; io => { bpRow: SCPrivate.BpRow _ layoutData.bpRows[inst.curSide]; pos _ SELECT inst.curSide FROM left, right => [bpRow.sideOrg.p + xyPos.x, bpRow.sideOrg.q + inst.offset + xyPos.y], bottom, top => [bpRow.sideOrg.p + inst.offset + xyPos.x, bpRow.sideOrg.q + xyPos.y], ENDCASE => SC.Error[programmingError, "No suppose to happen"]}; ENDCASE}; PosOf: PUBLIC PROC[inst: SCPrivate.Instance, pin: SCPrivate.ObjectPin] RETURNS [pinDes: SCInstUtil.PinDescription] = { xy: CD.Position _ SELECT pin.pinPos.side FROM bottom => [pin.pinPos.location, pin.pinPos.depth], right => [InstWidth[inst] - pin.pinPos.depth, pin.pinPos.location], top => [pin.pinPos.location, InstHeight[inst] - pin.pinPos.depth], left => [pin.pinPos.depth, pin.pinPos.location], ENDCASE => SC.Error[programmingError, "No suppose to happen"]; xyOrien: CD.Position _ SELECT inst.curOrien FROM 1 => [xy.x, xy.y], -- original 2 => [xy.y, InstWidth[inst] - xy.x], -- rotate270 3 => [InstWidth[inst] - xy.x, InstHeight[inst] - xy.y], -- rotate180 4 => [InstHeight[inst] - xy.y, xy.x], -- rotate90 5 => [InstWidth[inst] - xy.x, xy.y], -- mirrorX 6 => [xy.x, InstHeight[inst] - xy.y], -- rotate180X 7 => [xy.y, xy.x], -- rotate270X 8 => [InstHeight[inst] - xy.y, InstWidth[inst] - xy.x], -- rotate90X ENDCASE => SC.Error[programmingError, "No suppose to happen"]; pinDes _ [xyOrien.x, xyOrien.y, SCUtil.SideTranslate[pin.pinPos.side, inst.curOrien]]}; RotateRect: PUBLIC PROC[inst: SCPrivate.Instance, defRect: SC.Rect] RETURNS [SC.Rect] = { newRect: SC.Rect; SELECT inst.curOrien FROM 1 => -- original {newRect.x1 _ defRect.x1; newRect.y1 _ defRect.y1; newRect.x2 _ defRect.x2; newRect.y2 _ defRect.y2}; 2 => -- rotate270 {newRect.x1 _ defRect.y1; newRect.y1 _ InstWidth[inst] - defRect.x1; newRect.x2 _ defRect.y2; newRect.y2 _ InstWidth[inst] - defRect.x2}; 3 => -- rotate180 {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 => -- rotate90 {newRect.x1 _ InstHeight[inst] - defRect.y1; newRect.y1 _ defRect.x1; newRect.x2 _ InstHeight[inst] - defRect.y2; newRect.y2 _ defRect.x2}; 5 => -- mirrorX {newRect.x1 _ InstWidth[inst] - defRect.x1; newRect.y1 _ defRect.y1; newRect.x2 _ InstWidth[inst] - defRect.x2; newRect.y2 _ defRect.y2}; 6 => -- rotate180X {newRect.x1 _ defRect.x1; newRect.y1 _ InstHeight[inst] - defRect.y1; newRect.x2 _ defRect.x2; newRect.y2 _ InstHeight[inst] - defRect.y2}; 7 => -- rotate270X {newRect.x1 _ defRect.y1; newRect.y1 _ defRect.x1; newRect.x2 _ defRect.y2; newRect.y2 _ defRect.x2}; 8 => -- rotate90X {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 => SC.Error[programmingError, "No suppose to happen"]; RETURN[CDBasics.ReInterpreteRect[newRect]]}; LgOffsets: PUBLIC PROC[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 PROC [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 PROC[handle: SC.Handle] = BEGIN EachSide: SCRowUtil.EachSideProc = { IF bpRow.dimInvalid THEN SCRowUtil.ComputeSideHeight[handle, side]; sideDim[side] _ MAX[0, 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; [] _ SCRowUtil.EnumerateSides[handle, EachSide]; [] _ SCRowUtil.EnumerateRows[handle, EachRow]; rowChans.chans[1].chanPos _ 0; sideChans[left].sideChanPos _ 0; lgRows.horzRowOrg _ 0; 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; 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 + rowChans.chans[chan].chanWidth; 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; layoutData.totHeight _ rowChans.chans[nChans].chanPos; -- + rowChans.chans[nChans].chanWidth; layoutData.totWidth _ sideChans[right].sideChanPos; bpRows[bottom].sideOrg.q _ 0; bpRows[bottom].sideOrg.p _ lgRows.horzRowOrg + (lgRows.maxRowWidth - sideDim[bottom]) / 2; bpRows[right].sideOrg.p _ layoutData.totWidth; bpRows[right].sideOrg.q _ (layoutData.totHeight - sideDim[right])/ 2; bpRows[top].sideOrg.p _ lgRows.horzRowOrg + (lgRows.maxRowWidth - sideDim[top])/ 2; bpRows[top].sideOrg.q _ layoutData.totHeight; bpRows[left].sideOrg.p _ 0; bpRows[left].sideOrg.q _ (layoutData.totHeight - sideDim[left])/ 2; END; ChansForInsts: PUBLIC PROC[handle: SC.Handle, insts: SCPrivate.InstanceList] RETURNS [touchesChan: SCPrivate.ChanSet _ RTSets.RTLgSetEmpty] = { 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.RTLgSetUnion[touchesChan, RTSets.RTLgSetGenerateElement[(inst.curRow+1)-1]]; touchesChan _ RTSets.RTLgSetUnion[touchesChan , RTSets.RTLgSetGenerateElement[(inst.curRow)-1]]}}; io => {IF inst.curSide = bottom THEN touchesChan _ RTSets.RTLgSetUnion[touchesChan, RTSets.RTLgSetGenerateElement[(1)-1]]; IF inst.curSide = top THEN touchesChan _ RTSets.RTLgSetUnion[touchesChan, RTSets.RTLgSetGenerateElement[(layoutData.rowChans.count)-1]]}; ENDCASE; ENDLOOP}; CheckInst: PUBLIC PROC[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 PROC[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 PROC [handle: SC.Handle, instanceName: Rope.ROPE, object: SCPrivate.Object, 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[SCPrivate.InstanceRec]; instance.whichClass _ logic; instances.numLogics _ instances.numLogics + 1}; ft => {instance _ NEW[SCPrivate.InstanceRec]; instance.whichClass _ ft; instances.numFts _ instances.numFts + 1}; io => {instance _ NEW[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 PROC [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 PROC[instance: SCPrivate.Instance] RETURNS [orien: CD.Orientation] = { SELECT instance.curOrien FROM 0 => orien _ SC.Error[programmingError, "Not suppose to happen"]; 1 => orien _ original; 2 => orien _ rotate270; 3 => orien _ rotate180; 4 => orien _ rotate90; 5 => orien _ mirrorX; 6 => orien _ rotate180X; 7 => orien _ rotate270X; 8 => orien _ rotate90X; ENDCASE}; FindSourceInstance: PUBLIC PROC [handle: SC.Handle, flatCT: CoreFlat.FlatCellType] RETURNS [instance: SCPrivate.Instance] ~ { structureData: SCPrivate.StructureData = NARROW [handle.structureData]; instance _ NARROW [RefTab.Fetch[structureData.sourceInstances, flatCT].val]; IF instance=NIL THEN SC.Error[callingError, Rope.Cat["Unable to find instance for source cell : ", CoreFlat.InstancePathRope[handle.coreCellType, flatCT.path]]]; }; DefineSourceInstance: PUBLIC PROC [handle: SC.Handle, flatCT: CoreFlat.FlatCellType, instance: SCPrivate.Instance] ~ { structureData: SCPrivate.StructureData = NARROW [handle.structureData]; IF NOT RefTab.Insert[structureData.sourceInstances, flatCT, instance] THEN SC.Error[callingError, Rope.Cat["Trying to register twice cell instance : ", CoreFlat.InstancePathRope[handle.coreCellType, flatCT.path]]]; }; END. SCInstUtilImpl.mesa Copyright Ó 1986, 1987 by Xerox Corporation. All rights reserved. Bryan Preas, January 19, 1987 12:18:55 pm PST Jean-Marc Frailong October 14, 1987 12:52:56 pm PDT Christian Le Cocq January 4, 1988 9:42:54 am 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 {instance _ NEW[logic SCPrivate.InstanceRec]; {instance _ NEW[ft SCPrivate.InstanceRec]; {instance _ NEW[io SCPrivate.InstanceRec]; initialize the nets connected to these pins get the CD orientation Find the instance for a source flat cell from the global table, scream if not found. Êó˜codešœ™KšœB™BKšœ*Ïk™-K™3K™0—K˜Kšœ™KšÏc=™=Kšž?™?Kšž>™>Kšž<™™>K˜š ˜ KšœBœ+˜qK˜—šÏnœœ˜Kšœ4œ˜\Kšœ ˜Kšœœ˜ K˜Kš˜Kšœœ˜/Kš œœœœœ&˜KK˜—Kšœ.™.š Ÿ œœœœœ ˜MK˜Kš˜Kšœ™Kšœ3˜3K˜Kšœ"™"šœ˜Kšœ,˜,Kšœ)˜)Kšœ˜—Kšœ˜K˜—Kšœ/™/š Ÿ œœœœ œ ˜OK˜Kš˜Kšœ™šœ3˜3K˜—Kšœ$™$šœ˜Kšœ-˜-Kšœ*˜*Kšœ˜—Kšœ˜K˜—Kšœ+™+Kšœ/™/š Ÿœœœœ œ ˜NK˜šœ˜KšœP˜RK˜—šœ˜Kšœ)˜)Kšœ(˜(Kšœœœ˜,K˜——Kšœ0™0Kšœ™š Ÿœœœœœ ˜LK˜šœ˜KšœP˜RK˜—šœ˜Kšœ'˜'Kšœ(˜(Kšœœœ˜,—K™—Kšœ%™%šŸœœœ œœœœ ˜kK˜šŸœ˜$Kšœ œ˜,Kšœ œ˜-K˜—Kšœ œœ˜Kšœ œœ˜Kšœ@˜@K˜—Kšœ%™%š Ÿ œœœ œœ+˜]K˜Kšœ#œ˜=Kšœ1˜1Kšœœ˜Kšœœ ˜,Kšœœ ˜,Kšœ œ˜(š˜Kšœ4˜4Kšœœœ9˜^Kšœ)˜-—Kšœ œœ˜DK˜šœœœ˜7Kšœ5˜5Kšœœ˜!Kšœœœ˜:Kšœ˜"Kšœ*˜*Kšœ˜ —K˜—Kšœ&™&š Ÿœœœ œœ ˜AK˜Kšœ#œ˜=Kšœ1˜1Kšœœ ˜K˜šœœœ˜@Kšœ5˜5Kšœœ˜!šœœœ˜'Kšœœœ2˜Q—šœ˜Kšœœœ3˜Z—Kšœ*˜*Kšœ˜ —K˜—Kšœ™Kšœ9™9š Ÿœœœ œ#œ œ ˜^K˜Kšœ#œ˜=Kšœ9˜9šœ˜Kšœ5˜7—šœ˜Kšœ6˜6Kšœ6˜6Kšœ˜ —K˜—Kšœ™Kšœ?™?š Ÿ œœœ œ=œ˜}K˜Kšœ#œ˜=K™Kšœ-™-Kšœ.™.šœœ œ˜-Kšœ2˜2KšœC˜CKšœB˜BKšœ0˜0šœœ2˜?K˜——Kšœ-™-šœœ œ˜.Kšœž ˜Kšœ&ž ˜2Kšœ9ž ˜EKšœ'ž ˜2Kšœ&ž ˜0Kšœ'ž ˜4Kšœž ˜!Kšœ9ž ˜EKšœœ1˜>K˜—šœ˜šœ˜Kšœ=˜=KšœJ˜J—šœ˜Kšœ9˜9šœœ˜KšœT˜TKšœT˜TKšœœ2˜?——Kšœ˜ —K˜—Kšœ;™;šŸœœœ4˜FKšœ(˜/K˜Kšœ.™.šœ˜-Kšœ2˜2KšœC˜CKšœB˜BKšœ0˜0šœœ2˜?K˜——Kšœ-™-šœœ˜0Kšœž ˜Kšœ%ž ˜1Kšœ9ž ˜EKšœ'ž ˜2Kšœ&ž ˜0Kšœ'ž ˜4Kšœž ˜!Kšœ9ž ˜EKšœœ1˜>—K˜KšœW˜WK˜—Kšœ;™;šŸ œœœ$œ˜CKšœœ ˜K˜Kšœ-™-Kšœ œ˜šœ˜šœž ˜Kšœ2˜2Kšœ2˜2—šœž ˜KšœD˜DKšœD˜D—šœž ˜KšœW˜WKšœW˜W—šœž ˜KšœE˜EKšœE˜E—šœž ˜KšœD˜DKšœD˜D—šœž ˜KšœE˜EKšœE˜E—šœž ˜Kšœ2˜2Kšœ2˜2—šœž ˜KšœW˜WKšœW˜W—Kšœœ1˜>—Kšœ&˜,K˜—Kšœ'™'šŸ œœœ œG˜hK˜Kšœ#™#Kšœ#œ˜=Kšœ-˜-Kšœ*˜*Kšœœ˜Kšœœ ˜,Kšœœ ˜,Kšœ œ˜(š˜Kšœ3˜3Kšœ(˜(—Kšœ œœ˜BK˜šœœœ˜6Kšœ4˜4šœ˜KšœG˜GKšœ˜—Kšœ˜K˜—Kšœ™šœ˜Kšœ˜šœ$˜*Kšœ:˜:—KšœK˜O—K˜—Kšœ ™ šŸ œœœ œ ˜/K˜šŸœ˜"Kšœ-˜-—šŸœ˜$Kšœ.˜.—Kšœ.˜.Kšœ1˜1K˜—Kšœ=™=šŸ œœœ œ ˜.K˜Kš˜Kšœ&™&šŸœ˜$Kšœœ+˜CKšœœ=˜PK˜—šŸœ˜"Kšœœ3˜KK˜—Kšœ#œ˜=Kšœœ˜.Kšœ-˜-Kšœ-˜-Kšœ6˜6Kšœ3˜3Kšœ-˜-Kšœœ0˜9Kš œ œœœœ˜$K˜Kšœ0˜0K˜Kšœ.˜.K˜Kšœ™Kšœ˜Kšœ ˜ K˜Kšœ˜Kšœk˜kKšœ4˜4Kšœ™šœœœ˜2KšœY˜Yšœœ˜Kšœ[˜[Kšœr˜r—šœ˜K˜—Kšœ™šœF˜FK˜—Kšœ™K˜Kšœ7ž&˜]K˜Kšœ3˜3K˜Kšœ™Kšœ˜šœZ˜ZK˜—Kšœ™Kšœ.˜.šœE˜EK˜—Kšœ™KšœS˜Sšœ-˜-K˜—Kšœ™Kšœ˜KšœC˜CKšœ˜—K˜—Kšœ"™"šŸ œœœ œ'˜LKšœ;˜BK˜Kšœ#œ˜=šœ9œ œœ˜TKšœ*˜*šœ˜šœœ˜%šœb˜bKšœb˜b——šœœ˜$KšœU˜Ušœ˜Kšœn˜n——Kšœ˜—Kšœ˜ —K˜—Kšœ!™!šŸ œœœ œ&˜GKšœ#œ˜=šœ˜šœ ˜ Kšœœ˜Kšœœ˜Kšœ5˜5šœ œ!˜3šœœ œ œ˜8Kšœ˜ ——šœœ œ˜.Kšœ˜—š˜Kšœ5˜5šœ˜Kšœ ˜"———šœ˜Kšœœ˜Kšœœ˜Kšœ1˜1šœ ˜Kšœ˜—šœœ œ˜/Kšœ˜—š˜Kšœ6˜6šœ˜Kšœ ˜"———Kšœ˜ —K˜—Kšœ!™!šŸ œœœ œ ˜.K˜šŸœ!˜)Kšœ˜—Kšœ9˜9K˜—š Ÿœœœ œ4œœ˜zK˜Kšœ)œ˜FKšœS˜SK˜—šŸœœœ œbœœœ˜­K˜Kšœ)œ˜Fšœœœ˜KKšœ8˜8Kšœ˜ —K˜—š ŸœœœAœœœ˜K˜š œœœœœ˜