IFUCorePadsImpl.mesa
Copyright c 1985 by Xerox Corporation. All rights reserved.
Last Edited by Curry, June 7, 1986 10:22:45 am PDT
DIRECTORY CD, Core, CoreBlock, IFUCoreCells, CoreFrame, CoreLibrary, CoreName, CoreOps, CoreInstCell, IFUCorePads, IO, PW, PWCore, Rope;
IFUCorePadsImpl: CEDAR PROGRAM
IMPORTS CoreBlock, IFUCoreCells, CoreFrame, CoreLibrary, CoreName, CoreOps, CoreInstCell, IO, PW, PWCore, Rope
EXPORTS IFUCorePads =
BEGIN
ROPE:   TYPE = Core.ROPE;
CellType:  TYPE = Core.CellType;
Side:   TYPE = CoreFrame.Side;
PadsType: TYPE = IFUCorePads.PadsType;
Pad:   TYPE = IFUCorePads.Pad;
Signal: SIGNAL = CODE;
padCellClass: PUBLIC Core.CellClass ←
CoreOps.SetClassPrintProc[
NEW[Core.CellClassRec ← [name: "IFUCorePads", recast: NIL]],
ClassPrintProc];
ClassPrintProc: CoreOps.PrintClassProc ~ {
padData: Pad ← NARROW[data];
IO.PutF[out, "\nPad: side: %g, type: %g,",
IO.rope[CoreFrame.SideRope[padData.side]],
IO.rope[PadsTypeRp[padData.type]]];
IO.PutF[out, "data1: %g, data2: %g, enWtA: %g, enWtB: %g",
IO.rope[padData.data1],
IO.rope[padData.data2],
IO.rope[padData.enWtA],
IO.rope[padData.enWtB] ];
IO.PutF[out, "enRd: %g, disRd: %g",
IO.rope[padData.enRd],
IO.rope[padData.disRd] ] };
CellProc: PUBLIC PROC [
name: ROPE  ← NIL,
data: IFUCorePads.PadRec ]
RETURNS [cellType: CellType] = {
cellType ← CoreOps.SetCellTypeName[
NEW [ Core.CellTypeRec ← [
class:  padCellClass,
public: CoreOps.CreateWires[0],
data:  NEW[IFUCorePads.PadRec ← data] ] ],
name];
CoreFrame.SetFrameExpandProc [soft, cellType, NEW[CoreFrame.ExpandProc ← Expand] ];
CoreFrame.SetFrameExpandProc [hard, cellType, NEW[CoreFrame.ExpandProc ← Expand] ]};
Expand: CoreFrame.ExpandProc = {
renameProc: CoreInstCell.RenameProc ~ {
SELECT (new ← CoreName.RopeNm[old]) FROM
padvdd => RETURN[padVDD];
padgnd => RETURN[padGND];
vdd  => RETURN[VDD];
gnd  => RETURN[GND];
padSig => RETURN[CoreName.RopeNm[ pad.data1 ]];
toChip => RETURN[CoreName.RopeNm[ pad.data1 ]];
fromChip => RETURN[CoreName.RopeNm[ pad.data2 ]];
clock  => RETURN[CoreName.RopeNm[ pad.data1 ]];
nClock => RETURN[CoreName.RopeNm[ pad.data2 ]];
enRd  => RETURN[CoreName.RopeNm[ pad.enRd ]];
disRd  => RETURN[CoreName.RopeNm[ pad.disRd ]];
enWtA => RETURN[CoreName.RopeNm[ pad.enWtA ]];
enWtB => RETURN[CoreName.RopeNm[ pad.enWtB ]];
phA  => RETURN[PhA];
phB  => RETURN[PhB];
ENDCASE => Signal[] };
name:  ROPE;
pad:  Pad  ← NARROW[frameCT.data];
generic: CellType ← Pads [pad.side, pad.type];
specific: CellType ← CoreInstCell.SpecificGeneric[generic, renameProc];
name  ← CoreName.CellNm[frameCT, name].n;
name  ← IF name#NIL THEN name ELSE IF pad.data1#NIL THEN pad.data1 ELSE pad.data2;
[ ] ← CoreName.CellNm[specific, name];
[ ] ← CoreName.CellNm[frameCT, name];
frameCT.data ← NEW[CoreFrame.FrameRec ← [
first: left,
cell: specific,
seq: NEW[CoreFrame.FrameSeq[0]] ] ];
frameCT.class ← CoreFrame.frameCellClass;
CoreFrame.SetFrameExpandProc [soft, frameCT, NIL];
CoreFrame.SetFrameExpandProc [hard, frameCT, NIL]};
Pads: PROC[side: Side, type: PadsType] RETURNS[cell: Core.CellType] =
{CheckPads[]; RETURN[ pads[side][type] ]};
pads: REF ARRAY Side OF ARRAY PadsType OF Core.CellType ← NIL;
PadsTypeRp: ARRAY PadsType OF ROPE = [   -- all have PadVdd PadGnd Vdd Gnd
empty: CoreName.RopeNm["ExtBlankPad"],
conn:  CoreName.RopeNm["ExtConnectPad"],   -- Pad
in:   CoreName.RopeNm["ExtInputPad"],   -- toChip
out:  CoreName.RopeNm["ExtOutputPad"],  -- fromChip
triOut: CoreName.RopeNm["ExtIOTstPad"], -- toChip fromChip enWA enWB phA phB
triIO:  CoreName.RopeNm["ExtIOTstPad"], -- triOut + enRd disRd
clock:  CoreName.RopeNm["ExtClockPad"],   -- Clock nClock
ext:  CoreName.RopeNm["ExtPadExtention"], -- needs to be rotated 270
corLo:  CoreName.RopeNm["ExtPadGndVddCorner"],
corHi:  CoreName.RopeNm["ExtPadGndVddCorner"],
gnd:  CoreName.RopeNm["ExtGndPad"],
vdd:  CoreName.RopeNm["ExtVddPad"],
padgnd: CoreName.RopeNm["ExtPadGndPad"],
padvdd: CoreName.RopeNm["ExtPadVddPad"] ];
padvdd:  ROPE ← CoreName.RopeNm["PadVdd"];
padgnd:  ROPE ← CoreName.RopeNm["PadGnd"];
padVDD:  ROPE ← CoreName.RopeNm["PadVDD"];
padGND:  ROPE ← CoreName.RopeNm["PadGND"];
vdd:   ROPE ← CoreName.RopeNm["Vdd"];
gnd:   ROPE ← CoreName.RopeNm["Gnd"];
VDD:   ROPE ← CoreName.RopeNm["VDD"];
GND:   ROPE ← CoreName.RopeNm["GND"];
padSig:  ROPE ← CoreName.RopeNm["Pad"];
toChip:  ROPE ← CoreName.RopeNm["toChip"];
fromChip: ROPE ← CoreName.RopeNm["fromChip"];
clock:   ROPE ← CoreName.RopeNm["Clock"];
nClock:  ROPE ← CoreName.RopeNm["nClock"];
enRd:   ROPE ← CoreName.RopeNm["enRd"];
disRd:   ROPE ← CoreName.RopeNm["disRd"];
enWtA:  ROPE ← CoreName.RopeNm["enWA"];
enWtB:  ROPE ← CoreName.RopeNm["enWB"];
phA:   ROPE ← CoreName.RopeNm["phA"];
phB:   ROPE ← CoreName.RopeNm["phB"];
PhA:   ROPE ← CoreName.RopeNm["PhA"];
PhB:   ROPE ← CoreName.RopeNm["PhB"];
CheckPads: PROC = {
TwoCellTypes: TYPE = RECORD[c0, c1: Core.CellType];
IF pads#NIL THEN RETURN;
pads ← NEW[ARRAY Side OF ARRAY PadsType OF Core.CellType];
FOR type: PadsType IN PadsType DO
name: ROPE  ← PadsTypeRp[type];
obj: CD.Object ← PW.Get[IFUCoreCells.libraryPads.design, name.Cat[".mask"]];
obj    ← CoreLibrary.FlattenOneLevel[obj].new;
pads[top]  [type] ← PWCore.FromLayoutWithoutPublic[obj];
IF type=corHi THEN
pads[top][type]   ← PWCore.RotateCellType[pads[top][type], $Rot270];
pads[left]  [type] ← PWCore.RotateCellType[pads[top][type], $Rot90];
pads[bottom] [type] ← PWCore.RotateCellType[pads[top][type], $Rot180];
pads[right] [type] ← PWCore.RotateCellType[pads[top][type], $Rot270];
ENDLOOP;
[pads[bottom][corHi], pads[bottom][corLo]] ←
TwoCellTypes[pads[bottom][corLo], pads[bottom][corHi]];
[pads[right][corHi], pads[right][corLo]] ←
TwoCellTypes[pads[right][corLo], pads[right][corHi]];
FOR type: PadsType IN PadsType DO
FOR side: Side IN Side DO
sides: CoreBlock.Sides ← CoreFrame.SideSides[side];
cap: CoreBlock.Sides;
cap ← SELECT type FROM
corLo => CoreBlock.AddSide[sides, CoreFrame.SideSides[CoreFrame.NextSide[side]]],
corHi => CoreBlock.AddSide[sides, CoreFrame.SideSides[CoreFrame.PrevSide[side]]],
ENDCASE => sides;
CoreBlock.MarkSides[pads[side][type], cap];
ENDLOOP;
ENDLOOP};
END.