DIRECTORY Basics, CD, CDBasics, CDCells, CDSimpleRules, CedarProcess, CMosB, Core, CoreClasses, CoreGeometry, CoreOps, CoreProperties, CoreRoute, DABasics, IntHashTable, IO, PWCore, RefTab, Rope, Route, Sisyph, SymTab, TerminalIO; CoreRouteMosaic: CEDAR PROGRAM IMPORTS Basics, CD, CDBasics, CDCells, CDSimpleRules, CedarProcess, CMosB, CoreGeometry, CoreOps, CoreProperties, CoreRoute, DABasics, IntHashTable, IO, PWCore, RefTab, Rope, Route, Sisyph, SymTab, TerminalIO = BEGIN MosaicForm: TYPE = REF MosaicFormRec; MosaicFormRec: TYPE = RECORD[ data: CoreClasses.RecordCellType, cellType: CellType, horizLayer: CD.Layer, vertLayer: CD.Layer, ignoreNWell: REF, seq: SEQUENCE size: NAT OF MosaicRow]; MosaicRow: TYPE = REF MosaicRowRec; MosaicRowRec: TYPE = RECORD[SEQUENCE size: NAT OF MosaicCell]; MosaicCell: TYPE = RECORD[schPos, layPos: CD.Position, ctInst: INT, sBox: CD.Object]; PPDist: TYPE = RECORD[schP1, schP2, layDist: INT]; LocSchLay: TYPE = RECORD[sch, lay: INT]; RowCol: TYPE = RECORD[row, col: INT]; WirePin: TYPE = CoreRoute.WirePin; WirePins: TYPE = CoreRoute.WirePins; WirePinAry: TYPE = ARRAY Side OF WirePins; Side: TYPE = CoreGeometry.Side; CellType: TYPE = Core.CellType; Wire: TYPE = Core.Wire; Wires: TYPE = Core.Wires; NetInfo: TYPE = REF NetInfoRec; NetInfoRec: TYPE = RECORD [ trunkSize: INT _ 0, pins: LIST OF PinInfo _ NIL]; PinInfo: TYPE = RECORD [ side: Side, min: CD.Number _ 0, max: CD.Number _ 0, layer: CD.Layer]; technologyKey: ATOM _ $cmosB; wireWidthProp: ATOM _ $w; mosaicLayoutProp: ATOM _ $Mosaic; mosaicFormProp: ATOM _ $MosaicForm; lambda: INT _ CDSimpleRules.GetTechnology[technologyKey].lambda; Signal: SIGNAL[msg: IO.ROPE] = CODE; MosaicAttributes: PWCore.AttributesProc = { frm: MosaicForm _ CreateMosaicForm[cellType]; ShowMosaicForm[frm]; CheckInterfaces[frm]; BuildSBoxs[frm]}; MosaicLayout: PWCore.LayoutProc = { frm: MosaicForm _ NARROW[CoreProperties.GetCellTypeProp[cellType, mosaicFormProp]]; iList: CD.InstanceList; ctInsts: CoreClasses.CellInstances; maxLay: CD.Position _ frm[frm.size-1][frm[0].size-1].layPos; FOR row: INT DECREASING IN [0..frm.size-1) DO FOR col: INT DECREASING IN [0..frm[row].size-1) DO IF OriginRowColOf[frm, row, col] # [row, col] THEN LOOP; IF IsSBox[frm, row, col] THEN { inst: CD.Instance _ NewInstance[frm[row][col].sBox, frm[row][col].layPos]; iList _ CONS[inst, iList]} ELSE { ctInst: CoreClasses.CellInstance _ frm.data[frm[row][col].ctInst]; inst: CD.Instance _ NewInstance[PWCore.Layout[ctInst.type], frm[row][col].layPos]; ctInsts _ CONS[ctInst, ctInsts]; iList _ CONS[inst, iList]} ENDLOOP ENDLOOP; FOR i: NAT IN [0..frm.data.size) DO frm.data[i] _ ctInsts.first; ctInsts _ ctInsts.rest ENDLOOP; obj _ CDCells.CreateCell[il: iList, ir: [0, 0, maxLay.x, maxLay.y]]; CDCells.ToSequenceMode[obj]}; NewInstance: PROC[obj: CD.Object, irLoc: CD.Position] RETURNS[inst: CD.Instance] = { base: CD.Position _ CDBasics.BaseOfRect[CD.InterestRect[obj]]; pos: CD.Position _ CDBasics.SubPoints[irLoc, base]; inst _ NEW[CD.InstanceRep _ [obj, [pos]] ]}; MosaicDecorate: PWCore.DecorateProc = { WireToLabels: PROC [wire: Wire] RETURNS [labels: LIST OF Route.Label _ NIL] = {RETURN[LIST[CoreRoute.LabelInternal[form.data.internal, wire]]]}; form: MosaicForm _ NARROW[CoreProperties.GetCellTypeProp[cellType, mosaicFormProp]]; CoreRoute.DecorateRoutedArea[ cellType: cellType, obj: obj, wireToLabels: WireToLabels]; form.cellType _ NIL; form.data _ NIL; CoreProperties.PutCellTypeProp[cellType, mosaicFormProp, NIL]}; CreateMosaicForm: PROC[cellType: CellType] RETURNS[frm: MosaicForm] = { RoundedIR: PROC[index: INT] RETURNS[ir: CD.Rect] = { ir _ CoreRoute.SchMappedIR[data[index]]; ir.x1 _ (ir.x1/lambda)*lambda; ir.x2 _ (ir.x2/lambda)*lambda; ir.y1 _ (ir.y1/lambda)*lambda; ir.y2 _ (ir.y2/lambda)*lambda}; data: CoreClasses.RecordCellType _ NARROW [cellType.data]; xs: LIST OF PPDist; ys: LIST OF PPDist; locsX: LIST OF LocSchLay; locsY: LIST OF LocSchLay; FOR i: NAT IN [0..data.size) DO ir: CD.Rect _ RoundedIR[i]; laySize: CD.Position; laySize _ CD.InterestSize[PWCore.Layout[data[i].type]]; xs _ CONS[[ir.x1, ir.x2, laySize.x], xs]; ys _ CONS[[ir.y1, ir.y2, laySize.y], ys] ENDLOOP; locsX _ ConsolidatePPDs[xs]; locsY _ ConsolidatePPDs[ys]; frm _ NEW[MosaicFormRec[SizeLocSchLayList[locsY]]]; CoreProperties.PutCellTypeProp[cellType, mosaicFormProp, frm]; frm.cellType _ cellType; frm.data _ data; [frm.vertLayer, frm.horizLayer] _ CoreRoute.GetCellTypePropLayer[cellType, $VerticalMetal]; frm.ignoreNWell _ CoreProperties.GetCellTypeProp[cellType, $IgnoreNWell]; FOR row: INT IN [0..frm.size) DO xlist: LIST OF LocSchLay _ locsX; frm[row] _ NEW[MosaicRowRec[SizeLocSchLayList[locsX]]]; FOR col: INT IN [0..frm[row].size) DO frm[row][col].schPos _ [xlist.first.sch, locsY.first.sch]; frm[row][col].layPos _ [xlist.first.lay, locsY.first.lay]; frm[row][col].ctInst _ -1; xlist _ xlist.rest ENDLOOP; locsY _ locsY.rest ENDLOOP; FOR i: NAT IN [0..data.size) DO ir: CD.Rect _ RoundedIR[i]; ir.x2 _ ir.x2 - lambda; -- 2* lambda/2 ir.y2 _ ir.y2 - lambda; -- 2* lambda/2 FOR row: INT IN [0..frm.size-1) DO FOR col: INT IN [0..frm[row].size-1) DO IF ~CDBasics.InsidePos[frm[row][col].schPos, ir] THEN LOOP; IF frm[row][col].ctInst#-1 THEN ERROR; frm[row][col].ctInst _ i ENDLOOP ENDLOOP ENDLOOP}; ConsolidatePPDs: PROC[list: LIST OF PPDist] RETURNS[locs: LIST OF LocSchLay] = { GetNode: PROC[schLoc: INT] RETURNS[node: REF Node] = { node _ NARROW[IntHashTable.Fetch[nodeTab, schLoc].value]; IF node=NIL THEN {node _ NEW[Node_[]]; []_IntHashTable.Store[nodeTab, schLoc, node]}}; SetLayLoc: PROC[schLoc, layLoc: INT] = { node: REF Node _ GetNode[schLoc]; IF node.layLoc#-1 THEN {IF node.layLoc=layLoc THEN RETURN ELSE ERROR}; node.layLoc _ layLoc; locs _ CONS[[schLoc, layLoc], locs]; FOR lst: LIST OF LocSchLay _ locs, lst.rest WHILE lst#NIL AND lst.rest#NIL DO TwoLocSchLays: TYPE = RECORD[l1,l2: LocSchLay]; IF lst.first.sch <= lst.rest.first.sch THEN {IF lst.first.sch = lst.rest.first.sch OR lst.first.lay >= lst.rest.first.lay THEN ERROR; EXIT}; [lst.first, lst.rest.first] _ TwoLocSchLays[lst.rest.first, lst.first] ENDLOOP; FOR links: LIST OF Link _ node.links, links.rest WHILE links#NIL DO SetLayLoc[links.first.schLoc, layLoc + links.first.layDist] ENDLOOP}; Node: TYPE = RECORD[layLoc: INT _ -1, links: LIST OF Link _ NIL]; Link: TYPE = RECORD[schLoc, layDist: INT _ -1]; nodeTab: IntHashTable.Table _ IntHashTable.Create[]; min: INT _ LAST[INT]; FOR list _ list, list.rest WHILE list#NIL DO nodeUp: REF Node _ GetNode[list.first.schP1]; nodeDn: REF Node _ GetNode[list.first.schP2]; nodeUp.links _ CONS[[schLoc: list.first.schP2, layDist: +list.first.layDist], nodeUp.links]; nodeDn.links _ CONS[[schLoc: list.first.schP1, layDist: -list.first.layDist], nodeDn.links]; min _ MIN[min, list.first.schP1] ENDLOOP; SetLayLoc[min, 0]}; CheckInterfaces: PROC[frm: MosaicForm] = { IF CoreProperties.GetCellTypeProp[frm.cellType, $TrustMe]#NIL THEN RETURN; FOR row: INT IN [0..frm.size-2) DO FOR col: INT IN [0..frm[row].size-2) DO IF frm[row][col].ctInst # frm[row][col+1].ctInst AND frm[row][col].ctInst # -1 AND frm[row][col+1].ctInst # -1 THEN { l1: WirePins _ GetLayoutPins[frm, row, col+1, left]; l2: WirePins _ GetLayoutPins[frm, row, col, right]; IF NOT EqualWirePins[l1, l2] THEN ERROR}; IF frm[row][col].ctInst # frm[row+1][col].ctInst AND frm[row][col].ctInst # -1 AND frm[row+1][col].ctInst # -1 THEN { l1: WirePins _ GetLayoutPins[frm, row+1, col, bottom]; l2: WirePins _ GetLayoutPins[frm, row, col, top]; IF NOT EqualWirePins[l1, l2] THEN ERROR}; ENDLOOP ENDLOOP}; BuildSBoxs: PROC[frm: MosaicForm] = { name: IO.ROPE _ CoreOps.GetCellTypeName[frm.cellType]; globals: Core.Wires _ CoreRoute.GlobalWires[frm.cellType]; FOR row: INT IN [0..frm.size-1) DO FOR col: INT IN [0..frm[row].size-1) DO IF OriginRowColOf[frm, row, col] # [row, col] THEN LOOP; IF IsSBox[frm, row, col] THEN { lim: RowCol _ LimitRowColOf[frm, row, col]; laySize: CD.Position _ CDBasics.SubPoints[frm[lim.row][lim.col].layPos, frm[row][col].layPos]; pinAry: WirePinAry _ GetSBBrotherPins[frm, row, col, lim.row, lim.col]; wireAry: ARRAY Side OF Wires _ GetSBParentWires[frm, row, col, lim.row, lim.col]; TerminalIO.PutF["SBox at (%g, %g)\n", IO.int[col], IO.int[row]]; FOR side: Side IN Side DO IF pinAry[side] # NIL THEN LOOP; pinAry[side] _ CoreRoute.FilterPins[ pinAry[ DABasics.OtherSide[side]], wireAry[side], globals]; pinAry[side] _ AddMissingPins [frm, side, laySize, pinAry, wireAry[side] ] ENDLOOP; frm[row][col].sBox _ MakeSwitchBox[ name: IO.PutFR["%gSBox%gx%g", IO.rope[name],IO.int[col],IO.int[row]], routingRect: [0, 0, laySize.x, laySize.y], horizLayer: frm.horizLayer, vertLayer: frm.vertLayer, root: frm.data.internal, pinAry: pinAry, fastRoute: CoreProperties.GetCellTypeProp[frm.cellType, $FastRoute]#NIL ]}; ENDLOOP ENDLOOP; FOR i: NAT IN [0..frm.data.size) DO CoreRoute.FlushLayPinCache[frm.data[i].type]; CoreRoute.FlushSchPinCache[frm.data[i].type] ENDLOOP; CoreRoute.FlushSchPinCache[frm.cellType]}; AddMissingPins: PROC [frm: MosaicForm, side: Side, laySize: CD.Position, pinAry: WirePinAry, wires: Core.Wires] RETURNS[new: WirePins _ NIL] = { range: INT _ (IF side=left OR side=right THEN laySize.y ELSE laySize.x); layer: CD.Layer _ (IF side=left OR side=right THEN frm.horizLayer ELSE frm.vertLayer); pins: WirePins _ pinAry[side]; FOR wires _ wires, wires.rest WHILE wires#NIL DO size: INT _ 3*lambda; space: INT _ 4*lambda; spaceEnd: INT _ 8*lambda; done: BOOL _ FALSE; inMins, inMaxs: BOOL _ FALSE; FOR test: WirePins _ pins, test.rest WHILE test#NIL DO IF test.first.wire=wires.first THEN GOTO Loop REPEAT Loop => LOOP ENDLOOP; FOR test: WirePins _ pinAry[MinSide[side]], test.rest WHILE test#NIL DO IF test.first.wire=wires.first THEN {inMins _ TRUE; size _ MAX[size, test.first.max - test.first.min]} ENDLOOP; FOR test: WirePins _ pinAry[MaxSide[side]], test.rest WHILE test#NIL DO IF test.first.wire=wires.first THEN {inMaxs _ TRUE; size _ MAX[size, test.first.max - test.first.min]} ENDLOOP; IF NOT (inMins OR inMaxs) THEN ERROR; IF size=4*lambda AND layer=CMosB.met THEN size _ 3*lambda; IF size=3*lambda AND layer=CMosB.met2 THEN size _ 4*lambda; IF inMins THEN { IF (pins=NIL) AND (spaceEnd+size+spaceEnd <= range) OR (pins#NIL) AND (spaceEnd+size+space <= pins.first.min) THEN { pins _ CONS[[wires.first, spaceEnd, spaceEnd+size, layer], pins]; done _ TRUE}; IF NOT done THEN FOR test: WirePins _ pins, test.rest WHILE test#NIL DO IF (test.rest=NIL) AND (test.first.max + space+size+spaceEnd <= range) OR (test.rest#NIL) AND (test.first.max + space+size+space<=test.rest.first.min) THEN{ pos: INT _ test.first.max+space; test.rest _ CONS[[wires.first, pos, pos+size, layer], test.rest]; done _ TRUE; EXIT} ENDLOOP} ELSE { pins _ CoreRoute.ReverseWirePins[pins]; IF (pins=NIL) AND ( spaceEnd+size+spaceEnd <= range) OR (pins#NIL) AND (pins.first.max + space+size+spaceEnd <= range) THEN { pins _ CONS[[wires.first, range-size-spaceEnd, range-spaceEnd, layer], pins]; done _ TRUE}; IF NOT done THEN FOR test: WirePins _ pins, test.rest WHILE test#NIL DO IF (test.rest=NIL) AND ( space+size+spaceEnd <= test.first.min) OR (test.rest#NIL) AND (test.rest.first.max+space+size+space <= test.first.min) THEN { pos: INT _ test.first.min- space-size; test.rest _ CONS[[wires.first, pos, pos+size, layer], test.rest]; done _ TRUE; EXIT} ENDLOOP; pins _ CoreRoute.ReverseWirePins[pins]}; IF NOT done THEN { TerminalIO.PutF["\n*** A switchbox in the Mosaic layout: %g does not have enough space in which to put all of the %g side wires. Proceeding returns an incomplete route.\n", IO.rope[CoreOps.GetCellTypeName[frm.cellType]], IO.rope[SideNm[side]]]; Signal["Insufficient space on switchbox side. See Terminal Viewer."]; EXIT}; ENDLOOP; RETURN[pins]}; EqualWirePins: PROC[w1, w2: WirePins] RETURNS[equal: BOOL _ TRUE] = { DO IF w1=NIL OR w2=NIL THEN RETURN[w1=w2]; IF w1.first#w2.first THEN RETURN[FALSE]; w1_w1.rest; w2_w2.rest ENDLOOP}; GetLayoutPins: PROC[frm: MosaicForm, row, col: INT, side: Side, filtered: BOOL_FALSE] RETURNS[wirePins: WirePins _ NIL] = { layer: CD.Layer _ IF LeftRight[side] THEN frm.horizLayer ELSE frm.vertLayer; IF row IN [0..frm.size-1) AND col IN [0..frm[0].size-1) THEN { origin: RowCol _ OriginRowColOf[frm, row, col]; inst: CoreClasses.CellInstance _ frm.data[frm[row][col].ctInst]; temp: WirePins _ IF filtered THEN CoreRoute.FilteredInstanceLayoutPins[inst, side] ELSE CoreRoute.LayPins[inst.type, side]; bias: INT _ IF LeftRight[side] THEN frm[row][col].layPos.y - frm[origin.row][origin.col].layPos.y ELSE frm[row][col].layPos.x - frm[origin.row][origin.col].layPos.x; max: INT _ IF LeftRight[side] THEN frm[row+1][col].layPos.y - frm[row][col].layPos.y ELSE frm[row][col+1].layPos.x - frm[row][col].layPos.x; bindings: RefTab.Ref _ CoreOps.CreateBindingTable[inst.type.public, inst.actual]; FOR temp _ temp, temp.rest WHILE temp#NIL DO p: WirePin _ [temp.first.wire, temp.first.min-bias, temp.first.max-bias, temp.first.layer]; IF frm.ignoreNWell#NIL AND p.layer=CMosB.nwell THEN LOOP; IF filtered THEN { IF layer=CD.commentLayer THEN { IF p.layer#CMosB.met AND p.layer#CMosB.met2 THEN LOOP; IF LeftRight[side] = (p.layer = CMosB.met2) THEN {frm.horizLayer _ CMosB.met2; frm.vertLayer _ CMosB.met} ELSE {frm.horizLayer _ CMosB.met; frm.vertLayer _ CMosB.met2}; layer _ IF LeftRight[side] THEN frm.horizLayer ELSE frm.vertLayer}; IF p.layer#layer THEN LOOP} ELSE IF (p.wire _ NARROW[RefTab.Fetch[bindings, p.wire].val]) = NIL THEN ERROR; IF p.max <=0 THEN LOOP; IF p.min >=max THEN EXIT; wirePins _ CONS[p, wirePins] ENDLOOP; wirePins _ CoreRoute.ReverseWirePins[wirePins]}}; GetSBBrotherPins: PROC[frm: MosaicForm, row1, col1, row2, col2: INT] RETURNS[pinAry: WirePinAry _ ALL[NIL]] = { FOR row: INT IN [row1..row2) DO bias: INT _ frm[row][col1].layPos.y - frm[row1][col1].layPos.y; temp: WirePins _ GetLayoutPins[frm, row, col1-1, right, TRUE]; FOR temp _ temp, temp.rest WHILE temp#NIL DO p: WirePin _ temp.first; pinAry[left] _ CONS[[p.wire,p.min+bias,p.max+bias,p.layer],pinAry[left]] ENDLOOP; temp _ GetLayoutPins[frm, row, col2, left, TRUE]; FOR temp _ temp, temp.rest WHILE temp#NIL DO p: WirePin _ temp.first; pinAry[right] _ CONS[[p.wire,p.min+bias,p.max+bias,p.layer],pinAry[right]] ENDLOOP; ENDLOOP; FOR col: INT IN [col1..col2) DO bias: INT _ frm[row1][col].layPos.x - frm[row1][col1].layPos.x; temp: WirePins _ GetLayoutPins[frm, row1-1, col, top, TRUE]; FOR temp _ temp, temp.rest WHILE temp#NIL DO p: WirePin _ temp.first; pinAry[bottom]_CONS[[p.wire,p.min+bias,p.max+bias,p.layer],pinAry[bottom]] ENDLOOP; temp _ GetLayoutPins[frm, row2, col, bottom, TRUE]; FOR temp _ temp, temp.rest WHILE temp#NIL DO p: WirePin _ temp.first; pinAry[top] _ CONS[[p.wire,p.min+bias,p.max+bias,p.layer],pinAry[top]] ENDLOOP; ENDLOOP; FOR side: Side IN Side DO pinAry[side] _ CoreRoute.ReverseWirePins[pinAry[side]] ENDLOOP}; GetSBParentWires: PROC[frm: MosaicForm, row1, col1, row2, col2: INT] RETURNS[wireAry: ARRAY Side OF Wires _ ALL[NIL]] = { ir: CD.Rect _ CDBasics.ToRect[frm[row1][col1].schPos, frm[row2][col2].schPos]; pir: CD.Rect _ CD.InterestRect[CoreGeometry.GetObject[Sisyph.mode.decoration, frm.cellType]]; ir _ CDBasics.MoveRect[ir, CDBasics.NegOffset[CDBasics.BaseOfRect[pir]]]; IF row1=0 THEN wireAry[bottom] _ CoreRoute.OrderedAtomicSchWires[frm.cellType, bottom, ir.x1, ir.x2]; IF col1=0 THEN wireAry[left] _ CoreRoute.OrderedAtomicSchWires[frm.cellType, left, ir.y1, ir.y2]; IF row2=frm.size-1 THEN wireAry[top] _ CoreRoute.OrderedAtomicSchWires[frm.cellType, top, ir.x1, ir.x2]; IF col2=frm[0].size-1 THEN wireAry[right] _ CoreRoute.OrderedAtomicSchWires[frm.cellType, right, ir.y1, ir.y2]}; IsSBox: PROC[frm: MosaicForm, row, col: INT] RETURNS[BOOL] = {RETURN[ (row < (frm.size-1)) AND (col < (frm[row].size-1)) AND (frm[row][col].ctInst = -1)]}; LeftRight: PROC[side: Side] RETURNS[BOOL] = {RETURN[side=left OR side=right]}; LimitRowColOf: PROC[frm: MosaicForm, row, col: INT] RETURNS[rowCol: RowCol] = { rowI: INT _ row; colI: INT _ col; FOR row _ row+1, row+1 WHILE row {done_FALSE; list.rest _ list.rest.rest}; greater => {done_FALSE; [list.first, list.rest.first] _ TwoInts[list.rest.first, list.first]}; ENDCASE ENDLOOP; IF done THEN EXIT ENDLOOP}; WireName: PROC[wire, root: Wire _ NIL] RETURNS[rope: IO.ROPE] = { RETURN[(IF root#NIL THEN CoreRoute.LabelInternal[root, wire] ELSE CoreOps.GetShortWireName[wire])]}; MakeSwitchBox: PROC[ name: IO.ROPE, routingRect: CD.Rect, horizLayer: CD.Layer, vertLayer: CD.Layer, root: Wire,-- for consistant labels pinAry: WirePinAry, fastRoute: BOOL _ FALSE] RETURNS[switchBox: CD.Object] = { priority: CedarProcess.Priority _ CedarProcess.GetPriority[]; rulesParameters: Route.DesignRulesParameters = Route.DefaultDesignRulesParameters[ technologyHint: technologyKey, horizLayer: horizLayer, vertLayer: vertLayer, trunkDirection: horizontal]; intermediateResult: Route.IntermediateResult; nets: SymTab.Ref _ SymTab.Create[]; -- Label -> NetInfo FOR side: Side IN Side DO FOR pins: WirePins _ pinAry[side], pins.rest WHILE pins#NIL DO netInfo: NetInfo _ FetchNetInfo[nets, root, pins.first.wire]; netInfo.pins _ CONS [[side, pins.first.min, pins.first.max, pins.first.layer], netInfo.pins]; IF pins.first.wire.size#0 THEN ERROR ENDLOOP ENDLOOP; CedarProcess.CheckAbort[]; CedarProcess.SetPriority[background]; DO ENABLE Route.Signal => { TerminalIO.PutF["*** Route switchBox %g preliminary warning:\n %g\n", IO.rope[name], IO.rope[explanation]]; IF rulesParameters.trunkDirection=horizontal AND ( explanation.Find["Multiple channel exits"]#-1 OR explanation.Find["unable to find a place to dogleg"]#-1) THEN { TerminalIO.PutRope[" Will try again using vertical trunk.\n"]; rulesParameters.trunkDirection _ vertical; LOOP} ELSE RESUME}; intermediateResult _ Route.SwitchBoxRoute[ name: name, enumerateNets: EnumerateSwitchBoxNets, routingRect: routingRect, rulesParameters: rulesParameters, rules: Route.DefaultDesignRules[rulesParameters], enumerateObstructions: NIL, signalSinglePinNets: FALSE, signalCoincidentPins: FALSE, okToDiddleLLPins: FALSE, okToDiddleURPins: FALSE, optimization: IF fastRoute THEN noIncompletes ELSE full, switchBoxData: nets ]; EXIT ENDLOOP; CedarProcess.CheckAbort[]; IF intermediateResult=NIL THEN ERROR; switchBox _ Route.SwitchBoxRetrieve[intermediateResult ! Route.Signal => { TerminalIO.PutF["*** Route switchBox %g final warning:\n %g\n", IO.rope[name], IO.rope[explanation]]; RESUME} ].object; IF switchBox=NIL THEN ERROR; CedarProcess.SetPriority[priority]}; FetchNetInfo: PROC[nets: SymTab.Ref, root, wire: Wire] RETURNS[netInfo: NetInfo] = { label: Route.Label = CoreRoute.LabelInternal[root, wire]; rw: REF INT = NARROW [CoreProperties.GetWireProp[wire, wireWidthProp]]; netInfo _ NARROW [SymTab.Fetch[nets, label].val]; IF netInfo#NIL THEN RETURN; netInfo _ NEW [NetInfoRec _ [trunkSize: IF rw=NIL THEN 0 ELSE rw^*lambda]]; [] _ SymTab.Store[nets, label, netInfo]}; EnumerateSwitchBoxNets: Route.EnumerateSwitchBoxNetsProc = { nets: SymTab.Ref = NARROW [switchBoxData]; EachNet: SymTab.EachPairAction = { label: Route.Label = key; netInfo: NetInfo = NARROW[val]; eachNet[ name: label, enumeratePins: EnumerateSwitchBoxPins, trunkSize: netInfo.trunkSize, switchBoxData: NIL, netData: netInfo]}; [] _ SymTab.Pairs[nets, EachNet]}; EnumerateSwitchBoxPins: Route.EnumerateSwitchBoxPinsProc = { netInfo: NetInfo = NARROW [netData]; FOR pins: LIST OF PinInfo _ netInfo.pins, pins.rest WHILE pins#NIL DO pin: PinInfo = pins.first; eachPin[ side: pin.side, min: pin.min, max: pin.max, layer: pin.layer] ENDLOOP }; [] _ PWCore.RegisterLayoutAtom [mosaicLayoutProp, MosaicLayout, MosaicDecorate, MosaicAttributes]; END. ~CoreRouteMosaic.mesa Copyright Σ 1988 by Xerox Corporation. All rights reserved. Created by Don Curry February 23, 1988 2:20:43 pm PST Don Curry August 25, 1988 7:19:32 pm PDT Types and constants Mosaic Attribute, Layout and Decorate Procs CD.Instance given where you want the corner of the interest rect. Primary Procs Secondary Procs SBox generator Register layout atoms Κi˜– "Cedar" stylešœ™Icode– "Cedar" style™Jšœœ,˜3Jšœ œœ˜0—J˜šŸœ˜)š Ÿ œœœ œœœ˜MJšœœœ6˜B—Jšœœ;˜Tšœ˜Jšœ˜Jšœ ˜ Jšœ˜—Jšœœ˜Jšœ œ˜Jšœ9œ˜?——šœ ™ šŸœœœ˜Gš Ÿ œœœœœ ˜4Jšœ)˜)Jšœ>˜>Jšœ>˜>—Jšœ$œ˜;Jšœœœ˜Jšœœœ˜Jšœœœ ˜Jšœœœ ˜šœœœ˜Jšœœ Ÿ œ˜Jšœ œ ˜Jšœ œ+˜7Jšœœ ˜)Jšœœ œ˜1—Jšœ˜Jšœ˜Jšœœ*˜3Jšœ>˜>Jšœ˜Jšœ˜Jšœ\˜\JšœJ˜Jšœœœ˜ Jšœœœ˜!Jšœ œ)˜7šœœœ˜%Jšœ:˜:Jšœ:˜:Jšœ˜Jšœœ˜—Jšœœ˜—šœœœ˜JšœœŸ œ˜JšœΟc˜'Jšœ ˜'šœœœ˜"šœœœ˜'šœ/œœ˜;Jšœœœ˜&Jšœœœœ˜2————J˜—šŸœœœœ œœœ˜Qš Ÿœœ œœœ ˜6Jšœœ,˜9šœ˜ Jšœ œ:˜J——šŸ œœœ˜(Jšœœ˜!Jšœœœœœœœ˜FJšœ˜Jšœœ˜$šœœœœœœ œ˜MJšœœœ˜/šœ%˜+Jš œœ$œ%œœœ˜`—JšœGœ˜O—š œœœœœ˜CJšœ<œ˜E——Jš œœœ œœœœ˜BJšœœœœ˜0Jšœ4˜4Jšœœœœ˜šœœœ˜,Jšœœ"˜-Jšœœ"˜-JšœœI˜\JšœœI˜\Jšœœœ˜+—Jšœ˜J˜—šŸœœ˜+Jšœ8œœœ˜Jšœœœ˜"šœœœ˜'šœ0˜5Jšœ˜šœœ˜#JšœŸ œ˜4JšœŸ œ˜3Jšœœœœ˜)——šœ0˜5Jšœ˜šœœ˜#JšœŸ œ˜6JšœŸ œ˜1Jšœœœœ˜)——Jšœœ˜——J˜—šŸ œœ˜(Jšœœœ*˜8Jšœ:˜:šœœœ˜"šœœœ˜'Jšœ,œœ˜8šœœ˜ Jšœ,˜,šœ œ ˜JšœG˜G—Jšœ œ5˜GJšœ œœ;˜QJšœ&œ œ ˜@šœ œ˜Jšœœœœ˜ šœ$˜$JšœŸ œ!˜;—JšœJ˜JJšœ˜—šœ#˜#Jš œ œœ œ œ ˜HJšœ+˜+Jšœ˜Jšœ˜Jšœ˜Jšœ˜JšœFœ˜M——Jšœœ˜——šœœœ˜#Jšœ-˜-Jšœ,œ˜5—Jšœ*˜*J˜—šŸœ˜šœ'œ1˜ZJšœœ˜ —Jš œœœ œ œ œ ˜HJš œœ œ œ œœ˜VJšœœ ˜šœœœ˜0Jšœœ ˜Jšœ œ ˜Jšœ œ ˜Jšœœœ˜Jšœœœ˜šœ"œœ˜6Jš œœœœ œœ˜J—šœ3œœ˜Gšœ˜#Jšœ œ œ)œ˜K——šœ3œœ˜Gšœ˜#Jšœ œ œ)œ˜K——Jš œœ œ œœ˜%Jšœœœ˜:Jšœœœ˜;šœ˜ šœ˜šœœœ#˜6šœœœ)œ˜=Jšœœ6˜AJšœœ˜ ——š œœœœ"œœ˜Gšœ œœ1˜Išœ œœ:œ˜RJšœœ˜ Jšœ œ1˜AJšœœœœ˜————šœ˜Jšœ'˜'šœœœ(˜;šœœœ1œ˜EJšœœB˜MJšœœ˜ ——š œœœœ"œœ˜Gšœ œœ/˜GJšœ œœ:œ˜SJšœœ˜&Jšœ œ1˜AJšœœœœ˜——Jšœ(˜(——šœœœ˜šœ­˜­Jšœ.œŸœ ˜G—JšœGœ˜M—Jšœ˜—Jšœ˜——šœ™š Ÿ œœœœœ˜Fš˜Jš œœœœœœ˜'Jšœœœœ˜(Jšœ ˜ Jšœ œ˜—J˜—š Ÿ œœœœœ˜UJšœœ˜%Jš œœ œœœ˜Lš œœœœœ˜>Jšœ/˜/Jšœ@˜@šœœ ˜Jšœ1˜5Jšœ$˜(—šœœœ˜Jšœ>˜BJšœ?˜C—šœœœ˜Jšœ2˜6Jšœ3˜7—JšœR˜Ršœœœ˜,Jšœ[˜[Jš œœœœœ˜9šœ ˜ šœ˜šœœœ˜Jšœœœœ˜6šœ)˜+Jšœ9˜=Jšœ:˜>—Jšœœœœ˜C—Jšœœœ˜—Jš œœ œ'œœœ˜O—Jšœ œœ˜Jšœ œœ˜Jšœ œœ˜%—Jšœ1˜1—J˜—šŸœœ*œ˜DJšœ  œœœ˜*šœœœ˜Jšœœ6˜?Jšœ8œ˜>šœœœ˜,Jšœ˜Jšœœ6œ˜Q—Jšœ+œ˜1šœœœ˜,Jšœ˜Jšœœ7œ˜S—Jšœ˜—šœœœ˜Jšœœ6˜?Jšœ6œ˜<šœœœ˜,Jšœ˜Jšœœ8œ˜S—Jšœ-œ˜3šœœœ˜,Jšœ˜Jšœœ5œ˜O—Jšœ˜—šœ œ˜Jšœ7œ˜@—J˜—šŸœœ*œ˜DJš œ œœ œœ˜4JšœœH˜NJšœœœL˜]JšœI˜Išœ˜JšœV˜V—šœ˜JšœR˜R—šœ˜JšœQ˜Q—šœ˜JšœU˜U—J˜—š Ÿœœœœœ˜@Jšœœ˜Jšœœœ˜UJ˜—šŸ œœ œœ˜.Jšœœ œ˜"J˜—šŸ œœœœ˜PJšœœ˜Jšœœ˜šœ˜Jšœœ0œœ˜T—šœ˜Jšœœ.œœ˜W—Jšœ˜J˜—šŸœœ œ˜,Jšœœ%˜,J˜—šŸœœ œ˜,Jš œœœœœ˜3J˜—šŸœœœœ˜Qšœœœ.˜RJšœœ˜ —šœœœ.˜RJšœœ˜ —Jšœ˜J˜—šŸœœ˜*Jšœž œœ.˜UJšœ˜šœœœ˜%Jšœœœ˜=—Jšœ˜šœœœ˜%Jšœœœ˜=—š œœ œœ˜-šœ˜Jšœœ˜<—šœœœ˜'šœ˜Jšœœ˜9Jšœ œœ˜4———Jšœ˜J˜—šŸœœœ˜5Jšœœ˜šœœœ˜,šœ2˜2Jšœ ˜Jšœ'˜)Jšœ˜Jšœ˜Jšœœ˜(Jšœ˜Jšœ˜ ——J˜—šŸ œœœ˜4Jšœœ˜šœœœ˜0Jšœ œ œ$˜UJšœ˜ —J˜—š Ÿœœœœœ˜Jšœ@˜@J˜—šŸ œœœœœœœ˜@Jš œœœœœœ˜EJ˜—š Ÿœœœœ œœ˜IJš œœœœœœ˜EJ˜—š Ÿ œœ œœœ˜.Jšœ œœ œ˜$š˜Jšœœœ˜Jšœœœœ ˜š œœœœ œ˜>šœ0˜:Jšœœ˜3JšœœH˜^Jšœœ˜——Jšœœœœ˜—J˜—š Ÿœœœœœœ˜Bšœœ˜Jšœ$˜(Jšœ#˜'———šœ™šŸ œœ˜Jšœ œœ˜Jšœ˜Jšœ œ˜Jšœ œ˜Jšœ ˜&Jšœ˜šœ œœ˜Jšœ œ ˜!—Jšœ?˜?šœR˜RJšœ˜Jšœ˜Jšœ˜Jšœ˜—Jšœ-˜-Jšœ( ˜;šœ œ˜šœ*œœ˜>Jšœ=˜=JšœœJ˜]Jšœœœœ˜5——Jšœ˜Jšœ%˜%š˜šœ˜šœF˜FJšœ œ˜%—šœ+˜2Jšœ.˜0šœ8˜8šœ˜JšœA˜AJšœ+œ˜0—Jšœœ˜ ———šœ*˜*Jšœ˜Jšœ'˜'Jšœ˜Jšœ!˜!Jšœ4˜4Jšœœ˜Jšœœ˜Jšœœ˜Jšœœ˜Jšœœ˜Jšœœ œœ˜;Jšœ˜Jšœœ˜ ——Jšœ˜Jšœœœœ˜%šœJ˜Jšœ@˜@Jšœ œ˜%Jšœ ˜——Jšœ œœœ˜Jšœ$˜$J˜—šŸ œœ$˜:Jšœ˜Jšœ9˜9Jšœœœœ3˜GJšœ œ!˜1Jšœ œœœ˜Jš œ œœœœœ˜KJšœ)˜)J˜—šŸœ&˜