IFUCorePadsImpl:
CEDAR
PROGRAM
IMPORTS IFUCoreCells, CoreFrame, CoreLibrary, CoreName, CoreOps, CoreInstCell, IO, 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, enWtC: %g",
IO.rope[padData.data1],
IO.rope[padData.data2],
IO.rope[padData.enWtA],
IO.rope[padData.enWtB],
IO.rope[padData.enWtC] ];
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[
SELECT
TRUE
FROM
pad.type=conn => pad.data1,
pad.data1#NIL => Rope.Cat["Pad-", pad.data1],
pad.data2#NIL => Rope.Cat["Pad-", pad.data2],
ENDCASE => CoreName.ID["Pad-"] ] ];
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 ]];
enWtC => RETURN[CoreName.RopeNm[ pad.enWtC ]];
phA => RETURN[PhA];
phB => RETURN[PhB];
ENDCASE => Signal[] };
name: ROPE;
pad: Pad ← NARROW[frameCT.data];
generic: CellType ← Pads [pad];
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[pad: Pad]
RETURNS[cell: Core.CellType] = {
name: ROPE ← PadsTypeRp[pad.type].Cat[".mask"];
conditions: LIST OF ROPE ← NIL;
AppendCondition:
PROC[sig, ref:
ROPE] = {
SELECT sig ← CoreName.RopeNm[sig]
FROM
NIL => { };
gnd, GND => conditions ← CONS[Rope.Cat[ref, "Gnd"], conditions];
vdd, VDD => conditions ← CONS[Rope.Cat[ref, "Vdd"], conditions];
ENDCASE => conditions ← CONS[ref, conditions]};
AppendCondition[pad.enWtA, enWtA];
AppendCondition[pad.enWtB, enWtB];
AppendCondition[pad.enRd, enRd];
AppendCondition[pad.disRd, disRd];
In order to get Vdd and Gnd to connect internally must flatten one level with some funny overlapping name object or else call something like CoreBlock.MergeSplitWires
cell ← CoreLibrary.Get[IFUCoreCells.libraryPads, name, FALSE, conditions, 0, TRUE];
cell ← CoreLibrary.Get[IFUCoreCells.libraryPads, name, FALSE, conditions, -1];
IF pad.side#top
THEN {
norm: Core.CellType ← cell;
name ← Rope.Cat[CoreFrame.SideRope[pad.side], "-", CoreName.CellNm[norm].n];
cell ← CoreLibrary.Get[IFUCoreCells.libraryPads, name];
IF cell=
NIL
THEN {
cell ←
SELECT pad.side
FROM
left => CoreFrame.RotateCellType[norm, rotate90],
bottom => CoreFrame.RotateCellType[norm, rotate180X],
right => CoreFrame.RotateCellType[norm, rotate90X],
ENDCASE => ERROR;
CoreLibrary.Set[IFUCoreCells.libraryPads, name, cell]} } };
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
gate2Out: CoreName.RopeNm["ExtGate2OutPad"], -- fromChip enWA
gate3Out: CoreName.RopeNm["ExtGate3OutPad"], -- fromChip enWA enWB
gate4Out: CoreName.RopeNm["ExtGate4OutPad"], -- fromChip enWA enWB enWC
triOut: CoreName.RopeNm["ExtIOTstPad"], --toChip fromChip enWA enWB phA phB
triIO: CoreName.RopeNm["ExtIOTstIOPad"], -- 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["ExtPadGndVddCornerHi"],
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"];
enWt: ROPE ← CoreName.RopeNm["enWt"];
enWtA: ROPE ← CoreName.RopeNm["enWA"];
enWtB: ROPE ← CoreName.RopeNm["enWB"];
enWtC: ROPE ← CoreName.RopeNm["enWC"];
phA: ROPE ← CoreName.RopeNm["phA"];
phB: ROPE ← CoreName.RopeNm["phB"];
PhA: ROPE ← CoreName.RopeNm["PhA"];
PhB: ROPE ← CoreName.RopeNm["PhB"];
END.