DIRECTORY AlpsBool, AlpsHeur, AlpsTile, AlpsPWGen, CD, CDCells, CDDirectory, CDExtras, CDPinObjects, CDIO, CMos, Convert, MC, MCCtl, PW, PWCmos, PWPins, Rope; MCCtlImpl: CEDAR PROGRAM IMPORTS AlpsBool, AlpsHeur, AlpsPWGen, CD, CDCells, CDDirectory, CDExtras, CDPinObjects, CDIO, Convert, CMos, MC, PW, PWPins, Rope EXPORTS MCCtl = BEGIN OPEN AlpsBool, MCCtl; ctlOutNames: PUBLIC LIST OF Rope.ROPE; InitCtlOutNames: PUBLIC PROC [] = { ctlOutNames _ NIL; }; AddListToCtlOutNames: PUBLIC PROC[names: LIST OF Rope.ROPE] = { FOR l: LIST OF Rope.ROPE _ names, l.rest UNTIL l=NIL DO ctlOutNames _ CONS[l.first, ctlOutNames]; ENDLOOP; }; AddTableToCtlOutNames: PUBLIC PROC [table: TableOfVariables] = { FOR l: LIST OF OutputRef _ table.outputs, l.rest UNTIL l=NIL DO ctlOutNames _ CONS[l.first.name, ctlOutNames]; ENDLOOP; }; CreateTable: PUBLIC PROC [names: LIST OF ROPE] RETURNS [table: TableOfVariables] = { count: INT _ 1; FOR list: LIST OF ROPE _ names, list.rest WHILE list#NIL DO count _ count+1 ENDLOOP; table _ InitTableOfVariables[count]; count _ 1; FOR list: LIST OF ROPE _ names, list.rest WHILE list#NIL DO table[count].name _ list.first; count _ count + 1; ENDLOOP; }; EqualInt: PUBLIC PROC [table: TableOfVariables, rope: ROPE, start, end, value: INT] RETURNS [Expression] = { expr: Expression; IF start>end THEN RETURN[true]; expr _ Find[table, MC.IndexedName[rope, end]]; RETURN [And[table, IF (value MOD 2) = 1 THEN expr ELSE Not[expr], EqualInt[table, rope, start, end-1, value/2]]]; }; FindInternal: PUBLIC PROC [table: TableOfVariables, rope: ROPE] RETURNS [internalIndex: INT] = { FOR i: INT IN [1..table.size) DO IF Rope.Equal[rope, table[i].name] THEN RETURN [i]; ENDLOOP; ERROR; }; Find: PUBLIC PROC [table: TableOfVariables, rope: ROPE] RETURNS [Expression] = { RETURN [Var[FindInternal[table, rope]]]; }; DefaultDontCare: PUBLIC PROC [] RETURNS [Expression] = { RETURN[false]; }; GenerateLayout: PUBLIC PROC [design: CD.Design, table: TableOfVariables, distanceBetweenGlue: INT _ 5] RETURNS [obj: CD.ObPtr] = { BEGIN file: ROPE _ "AlpsCells"; IF CDDirectory.Fetch[design, file].found THEN Output["AlpsCells already present in design\n"] ELSE BEGIN to: CD.Design _ design; Check: PROC [design: CD.Design] RETURNS [ok: BOOL] = BEGIN ok _ design.technology=to.technology; IF ~ok THEN Output["Technology mismatch: includee is ", design.technology.name, "\n"]; END; from: CD.Design _ CDIO.ReadDesign[file, Check]; Output["Design AlpsCells read and included in the design"]; [] _ CDExtras.MergeIn[design: to, from: from, name: file]; END; END; BEGIN input, aux, output, latch: INT; [input, aux, output, latch] _ AlpsBool.NbOfVars[table]; Output[" Input: ", Convert.RopeFromInt[input], " Aux: ", Convert.RopeFromInt[aux], " Output: ", Rope.Cat[Convert.RopeFromInt[output], " Latch: ", Convert.RopeFromInt[latch], "\n"]]; END; BEGIN alpsTileContext: AlpsTile.Context _ NEW[AlpsTile.ContextRec _ [design: design, table: table, distanceBetweenGlue: distanceBetweenGlue, distanceBetweenContacts: 20, debug: FALSE]]; Output["\nLet's start Layout!"]; obj _ AlpsPWGen.TableToLayout[alpsTileContext]; Output["Done!"]; END; }; InputsFromTable: PUBLIC PROC [table: TableOfVariables] RETURNS [inputs: LIST OF ROPE _ NIL] = { FOR i: INT DECREASING IN [1..table.size) DO inputs _ CONS[table[i].name, inputs] ENDLOOP; }; Permute: PUBLIC PROC [table: TableOfVariables, permute: PermuteFlags _ permuteFast] RETURNS [newTable: TableOfVariables] = { SELECT permute FROM dontPermute => newTable _ table; permuteFast => newTable _ AlpsHeur.BestPermuteInfinitely[table, AlpsHeur.ImproveAreaAndDelay]; permuteAllCases => newTable _ AlpsHeur.AllPermute[table, AlpsHeur.ImproveAreaAndDelay, 200]; -- Increase if it writes "Aborted" on the terminal and you want to try more. ENDCASE => ERROR; }; ListSize: PUBLIC PROC [list: LIST OF ROPE] RETURNS [size: INT _ 0] = { FOR l: LIST OF ROPE _ list, l.rest UNTIL l=NIL DO size _ size+1 ENDLOOP; }; ListCat: PUBLIC PROC [l1, l2: LIST OF ROPE] RETURNS[l3: LIST OF ROPE] = { l3 _ l2; FOR l: LIST OF Rope.ROPE _ l1, l.rest UNTIL l=NIL DO l3 _ CONS[l.first, l3]; ENDLOOP; }; MakeAlpsLatchandDrive: PUBLIC PROC [design: CD.Design, target: PW.ObPtr] RETURNS [result: PW.ObPtr] = { phASlice: PW.ObPtr _ PW.Get[design, "phALatchandDriveSlice"]; phBSlice: PW.ObPtr _ PW.Get[design, "phBLatchandDriveSlice"]; unLatchedDriveSlice: PW.ObPtr _ PW.Get[design, "unLatchedDriveSlice"]; targetIR: CD.Rect _ CD.InterestRect[target]; sliceIR: CD.Rect _ CD.InterestRect[phASlice]; resultIR: CD.Rect _ [0, 0, targetIR.x2-targetIR.x1, sliceIR.y2-sliceIR.y1]; attatchment: PW.ObPtr; attatchmentIR: CD.Rect; targetPinPosInResult: CD.Position; attatchmentIRPosInResult: CD.Position _ [0, 0]; ProcessTargetPin: PWPins.AppEnumerator = { side: PWPins.Side _ PWPins.GetSide[target, app].side; name: ROPE _ CDPinObjects.GetName[app]; layer: CD.Layer _ CDPinObjects.GetLayer[app]; ProcessAttatchmentPin: PWPins.AppEnumerator = { side: PWPins.Side _ PWPins.GetSide[attatchment, app].side; IF side=PWPins.top THEN attatchmentIRPosInResult.x _ targetPinPosInResult.x-(app.location.x-attatchmentIR.x1); }; NewName: PWPins.RenameProc = {newRope _ name}; targetPinPosInResult _ [app.location.x-targetIR.x1, sliceIR.y2-sliceIR.y1]; IF side=PWPins.bottom AND (layer=CMos.met) AND (Rope.Index[name, 0, "Not"]#0) THEN { SELECT TRUE FROM Rope.Match["xAB", name] => attatchment _ PWPins.RenamePins[design, phASlice, NewName]; Rope.Match["xBA", name] => attatchment _ PWPins.RenamePins[design, phBSlice, NewName]; ENDCASE => attatchment _ PWPins.RenamePins[design, unLatchedDriveSlice, NewName]; attatchmentIR _ CD.InterestRect[attatchment]; [] _ PWPins.EnumerateEdgePins[phASlice, ProcessAttatchmentPin]; PW.IncludeInCell[design, result, attatchment, [attatchmentIRPosInResult.x, attatchmentIRPosInResult.y]] }; }; result _ PW.CreateEmptyCell[]; CDCells.SetInterestRect[result, resultIR]; [] _ PWPins.EnumerateEdgePins[target, ProcessTargetPin]; BEGIN leftFillDist: INT _ attatchmentIRPosInResult.x; rightFillDist: INT _ (resultIR.x2-resultIR.x1)- (attatchmentIRPosInResult.x+attatchmentIR.x2-attatchmentIR.x1); IF leftFillDist > 0 THEN PW.IncludeInCell[design, result, MC.LeftFillerCell[design, attatchment, leftFillDist], [0, 0]]; IF rightFillDist > 0 THEN PW.IncludeInCell[design, result, MC.RightFillerCell[design, attatchment, rightFillDist], [attatchmentIRPosInResult.x+attatchmentIR.x2-attatchmentIR.x1, 0]]; END; PW.IncludeInDirectory[design, result, "LatchResult"]; }; MakeFeedBackLatchandDrive: PUBLIC PROC[design: CD.Design, signals: LIST OF ROPE] RETURNS [result: PW.ObPtr] = { nbFedBackInputs: INT _ ListSize[signals]; phASlice: PW.ObPtr _ PW.Get[design, "FBphAlatchandDriveSlice"]; phBSlice: PW.ObPtr _ PW.Get[design, "FBphBLatchandDriveSlice"]; unLatchedDriveSlice: PW.ObPtr _ PW.Get[design, "FBunLatchedDriveSlice"]; glue: PW.ObPtr _ PW.Get[design, "FeedBackLatchToOutputLatchGlue"]; sliceIR: CD.Rect _ CD.InterestRect[phASlice]; -- all slices must have same IR glueIR: CD.Rect _ CD.InterestRect[glue]; resultIR: CD.Rect _ [0, 0, nbFedBackInputs*(sliceIR.x2-sliceIR.x1)+glueIR.x2-glueIR.x1, sliceIR.y2-sliceIR.y1]; sliceNum: INT _ 0; name: ROPE; NewName: PWPins.RenameProc = { index: INT; newRope _ oldRope; IF Rope.Equal[oldRope, "in"] OR Rope.Equal[oldRope, "out"] THEN newRope _ name; IF Rope.Equal[oldRope, "Notout"] THEN newRope _ Rope.Cat["Not", name]; IF Rope.Find[name, "CyclexAB"] # -1 THEN RETURN; IF Rope.Equal[oldRope, "out"] AND (index _ Rope.Find[name, "xAB"])#-1 THEN newRope _ Rope.Replace[name, index, 3, "xBA"]; IF Rope.Equal[oldRope, "Notout"] AND (index _ Rope.Find[name, "xAB"])#-1 THEN newRope _ Rope.Cat["Not", Rope.Replace[name, index, 3, "xBA"]]; IF Rope.Equal[oldRope, "out"] AND (index _ Rope.Find[name, "xBA"])#-1 THEN newRope _ Rope.Replace[name, index, 3, "xAB"]; IF Rope.Equal[oldRope, "Notout"] AND (index _ Rope.Find[name, "xBA"])#-1 THEN newRope _ Rope.Cat["Not", Rope.Replace[name, index, 3, "xAB"]]; }; SpecialNewName: PWPins.RenameProc = { index: INT; IF Rope.Equal[oldRope, "out"] THEN newRope _ name; IF Rope.Equal[oldRope, "Notout"] THEN newRope _ Rope.Cat["Not", name]; IF Rope.Equal[oldRope, "in"] AND (index _ Rope.Find[name, "xBA"])#-1 THEN newRope _ Rope.Replace[name, index, 3, "xAB"]; }; result _ PW.CreateEmptyCell[]; CDCells.SetInterestRect[result, resultIR]; FOR l: LIST OF ROPE _ signals, l.rest WHILE l#NIL DO slice: PW.ObPtr; name _ l.first; SELECT TRUE FROM Rope.Find[name, "CyclexAB"] # -1 => slice _ PWPins.RenamePins[design, unLatchedDriveSlice, NewName]; Rope.Find[name, "CyclexBA"] # -1 => slice _ PWPins.RenamePins[design, phBSlice, SpecialNewName]; Rope.Find[name, "xAB"] # -1 => slice _ PWPins.RenamePins[design, phBSlice, NewName]; Rope.Find[name, "xBA"] # -1 => slice _ PWPins.RenamePins[design, phASlice, NewName]; ENDCASE => slice _ PWPins.RenamePins[design, unLatchedDriveSlice, NewName]; PW.IncludeInCell[design, result, slice, [sliceNum*(sliceIR.x2-sliceIR.x1), 0]]; sliceNum _ sliceNum+1; ENDLOOP; PW.IncludeInCell[design, result, glue, [nbFedBackInputs*(sliceIR.x2-sliceIR.x1), 0]]; PW.IncludeInDirectory[design, result, "FeedBackLatchandDrive"]; }; MakeFeedBack: PUBLIC PROC [design: CD.Design, alpsTarget, latchTarget: PW.ObPtr] RETURNS [result: PW.ObPtr] = { alpsTargetIR: CD.Rect _ CD.InterestRect[alpsTarget]; latchTargetIR: CD.Rect _ CD.InterestRect[latchTarget]; resultIR: CD.Rect _ [0, 0, latchTargetIR.x2-latchTargetIR.x1, alpsTargetIR.y2-alpsTargetIR.y1]; bus: PW.ObPtr; SelectPin: MC.SelectPinProc -- [pin: CD.ApplicationPtr] RETURNS [sel: BOOL] -- = { sel _ (CDPinObjects.GetLayer[pin]=CMos.met2); }; result _ PW.CreateEmptyCell[]; CDCells.SetInterestRect[result, resultIR]; PW.IncludeInCell[design, result, bus _ MC.LeftFillerCell[design, alpsTarget, resultIR.x2-resultIR.x1, SelectPin], [0, 0]]; PW.IncludeInCell[design, result, MC.ConnectTopToBus[design, latchTarget, bus], [0, 0]]; PW.IncludeInDirectory[design, result, "FeedBack"]; }; END. ²MCCtlImpl.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Created by: Sindhu, June 20, 1985 7:03:43 pm PDT Last Edited by: Sindhu, July 14, 1985 10:46:31 pm PDT Last Edited by: Serlet, July 6, 1985 2:10:26 pm PDT Include tileset if necessary Print info Layout at last [app: CD.ApplicationPtr] RETURNS [quit: BOOL _ FALSE] [app: CD.ApplicationPtr] RETURNS [quit: BOOL _ FALSE] Now put down two filler cells, one on the left of the last attatchment and one on its right. These will connect all of the horizontal bussed signals. But, of course, check for null filler cells first! Put down the input bus to alps Put down the connections from the latch to the bus Κ ‹˜™Icodešœ Οmœ1™