<> <> <> <> DIRECTORY CD, CDBasics, CDCells, CDExtras, CDFrame, CDOps, CDPinObjects, CDViewer, IO, PW, PWRoute, IFUPW, IFUPWControl, REFBit, Rope, Route, ViewerClasses; IFUPWContSection: CEDAR PROGRAM IMPORTS CD, CDCells, CDExtras, CDFrame, CDOps, CDPinObjects, CDViewer, IFUPW, IFUPWControl, IO, PW, PWRoute, REFBit, Rope, Route -- , CD, CDBasics, CDExtras EXPORTS IFUPWControl = BEGIN OPEN IFUPWControl; ColumnFromPLAClusterDrives: PUBLIC PROC [drives: Frame, design: CD.Design] RETURNS[column: Frame] = { column _ drives; column _ MergeConnSections [column]; GenPlaSections [column, design]; GenConnSections [column, design]; }; MergeConnSections: PROC[drives: Frame] RETURNS[new: Frame] ~ { testProc: CDFrame.TestMergeProc = {RETURN[frame.data=NIL]}; -- data=NIL => connect new _ CDFrame.TestMergeNodes[drives, testProc]}; GenPlaSections: PROC[drives: Frame, design: CD.Design] ~ { outs: INT _ 0; FOR index: INT IN [0..drives.seqSize) DO desc: IFUPWControl.PLADescription; IF drives[index].data = NIL THEN LOOP; desc _ NARROW[drives[index].data]; outs _ MAX[outs, REFBit.Desc[desc.ttt.out].bitForm.size]; ENDLOOP; FOR index: INT IN [0..drives.seqSize) DO IF drives[index].data = NIL THEN LOOP; drives[index] _ CreateDrivenPLAFrame[ drFrame: drives[index], design: design, outWidth: outs]; ENDLOOP }; Trace: BOOL _ FALSE; GenConnSections: PROC[drives: Frame, design: CD.Design] ~ { params: PWRoute.RouterParams _ NEW[PWRoute.RouterParamsRec _ [trunkLayer: "metal2", branchLayer: "metal"]]; FOR index: INT IN [0..drives.seqSize) DO IF drives[index].data # NIL THEN LOOP ELSE { -- returns x sequence with drivers in 0 top, bottom, left, right, wire: CD.Object; drFrame: Frame _ drives[index]; wireFrame: Frame _ CDFrame.NewFrame[0,x,drives[index].shell.name.Cat["-Wire"]]; top _ IF (index+1)=drives.seqSize THEN NIL ELSE NARROW[drives[index+1][0].data]; bottom _ IF index=0 THEN NIL ELSE NARROW[drives[index-1][0].data]; left _ GenPassDummyFromDrives[drFrame, design]; BuildDrivers[drFrame, design]; right _ CDFrame.FrameToObject[drFrame, design]; wire _ PWRoute.AbutSbRoute [design, bottom, right, top, left, vertical, params ! Route.Signal => {log.PutF["\n Route Signal: %g", IO.rope[explanation]]; RESUME}]; IF Trace THEN ShowAllFive[design, wire, bottom, right, top, left]; PW.RenameObject[design, wire, wireFrame.shell.name]; wireFrame.data _ wire; drives[index] _ CDFrame.NewFrame[2, x, drFrame.shell.name.Cat["-DrWire"]]; drives[index][0] _ wireFrame; drives[index][1] _ drFrame }; ENDLOOP }; <<>> ShowAllFive: PUBLIC PROC [design: CD.Design, wire, bottom, right, top, left: CD.Object] = { viewer: ViewerClasses.Viewer _ CDViewer.CreateViewer[design]; maxX: INT _ MAX[ IF top=NIL THEN 0 ELSE CD.InterestSize[top].x, IF bottom=NIL THEN 0 ELSE CD.InterestSize[bottom].x]; maxY: INT _ MAX[ IF left=NIL THEN 0 ELSE CD.InterestSize[left].y, IF right=NIL THEN 0 ELSE CD.InterestSize[right].y]; CDOps.SetInstList[design, NIL]; CDOps.AddAnObject[design, left, [-CD.InterestSize[left].x, 0]]; CDOps.AddAnObject[design, bottom, [0, -CD.InterestSize[bottom].y]]; CDOps.AddAnObject[design, top, [0, maxY]]; CDOps.AddAnObject[design, right, [maxX, 0]]; CDOps.AddAnObject[design, wire, [0, 0]]; CDViewer.ShowAndScale[viewer, CDExtras.BoundingBox[design]]}; <<>> <> <> <> <> <> <> <> <> <> <> GenPassDummyFromDrives: PROC[drives: Frame, design: CD.Design] RETURNS[cell: CD.Object] ~ { pinSize: CD.Position _ [6,6]; driverHeight: INT _ 48; outputOffset: INT _ 16; minHeight: INT _ (drives.seqSize+1)*driverHeight; cellPtr: CD.CellPtr; FOR index: INT IN [0..drives.seqSize) DO rec: REF DriveRec _ NARROW[drives[index].data]; IF rec.pass THEN EXIT REPEAT FINISHED => RETURN[NIL] ENDLOOP; cell _ CDCells.CreateEmptyCell[]; cellPtr _ NARROW[cell.specificRef]; FOR index: INT IN [0..drives.seqSize) DO rec: REF DriveRec _ NARROW[drives[index].data]; IF rec.pass THEN { height: INT _ index*driverHeight+driverHeight/2 -pinSize.y/2+outputOffset; newInst: CD.Instance _ NEW[CD.InstanceRep _ [ ob: CDPinObjects.CreatePinOb[pinSize], location: [6, height] ] ]; minHeight _ MIN[minHeight, height]; CDPinObjects.SetLayer[newInst, IFUPW.cmosMet]; CDPinObjects.SetName[newInst, DriverPinName[(IF rec.drDir=in THEN out0 ELSE in), rec]]; cellPtr.contents _ CONS[newInst, cellPtr.contents]}; ENDLOOP; CDCells.SetInterestRect[cell, [0, 0, 12, drives.seqSize*driverHeight]]; PW.IncludeInDirectory[design, cell, "Dummy"]; <> RETURN[cell] }; log: IO.STREAM _ CDFrame.GetLog[]; END.