IFUPWContSection.mesa
Copyright c 1985 by Xerox Corporation. All rights reserved.
Last Edited by Curry, December 26, 1985 1:55:11 pm PST
Preas, November 5, 1985 2:32:09 pm PST
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: BOOLFALSE;
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
THENNIL
ELSENARROW[drives[index+1][0].data];
bottom ← IF index=0
THENNIL
ELSENARROW[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: INTMAX[
IF top=NIL  THEN 0 ELSE CD.InterestSize[top].x,
IF bottom=NILTHEN 0 ELSE CD.InterestSize[bottom].x];
maxY: INTMAX[
IF left=NILTHEN 0 ELSE CD.InterestSize[left].y,
IF right=NILTHEN 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]]};
MakeDummySwitchbox: PROC RETURNS[cell: CD.Object] = {
shell: REF CDFrame.ShellRec ← NEW[CDFrame.ShellRec ← [name: "Routing"]];
shell.size.x ← IF top#NIL
THEN CDBasics.SizeOfRect[CD.InterestRect[top]].x
ELSE CDBasics.SizeOfRect[CD.InterestRect[bottom]].x;
shell.size.y ← IF left#NIL
THEN CDBasics.SizeOfRect[CD.InterestRect[left]].y
ELSE CDBasics.SizeOfRect[CD.InterestRect[right]].y;
RETURN[CDFrame.ShellToBlock[design, shell]]};
route.data ← MakeDummySwitchbox[];
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"];
CDCells.SetInterestRect[cell, [0, -minHeight, 12, drives.seqSize*driverHeight-minHeight]];
RETURN[cell] };
log: IO.STREAM ← CDFrame.GetLog[];
END.