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.