IFUCoreDataMatchImpl.mesa,
Copyright c 1986 by Xerox Corporation. All rights reserved.
Last Edited by Curry, April 10, 1986 11:38:15 am PST
DIRECTORY CD, Core, CoreBlock, CoreCreate, CoreFrame, CoreGlue, CoreLibrary, CoreName, CoreOps, CoreWire, CoreXform, HashTable, IFUCoreCells, IFUCoreData, IO, PWCore, Rope;
IFUCoreDataMatchImpl: CEDAR PROGRAM
IMPORTS CoreBlock, CoreCreate, CoreFrame, CoreGlue, CoreLibrary, CoreName, CoreOps, CoreWire, CoreXform, HashTable, IFUCoreCells, IFUCoreData, IO, PWCore, Rope =
BEGIN
ROPE:  TYPE = Core.ROPE;
CWire:  TYPE = CoreWire.CWire;
Signal: SIGNAL = CODE;
ExpandDataMatchFrame: CoreFrame.ExpandProc = { -- frameCT
name: ROPE ← CoreName.CellNm[frameCT].n;
frame: CoreFrame.Frame ← NEW[CoreFrame.FrameRec ← [first: top] ];
data: IFUCoreData.DpCellData ← NARROW[frameCT.data];
xform: CoreXform.Xform ← CoreXform.GetXform[data.type];
out0:    CWire ← CWire[frameCT.public].f["out"].i[0];
library:   CoreLibrary.Library   ← IFUCoreCells.library;
domain:   NAT ← CoreXform.XformSize[xform];
topDegree:  NAT ← 0;
sums:    INT ← IF data.data=NIL THEN 1 ELSE NARROW[data.data, REF INT]^;
frame.seq  ← NEW[CoreFrame.FrameSeq[3]];
frame.seq[0] ← CoreFrame.NewFrameCell[domain, "Xor", [first: left]];
frame.seq[1] ← CoreGlue.CellProc[t:conn, b:conn]; -- carry in/out
frame.seq[2] ← CoreFrame.NewFrameCell[domain, "Gate", [first: left]];
frameCT.class ← CoreFrame.frameCellClass;
frameCT.data  ← frame;
CoreFrame.SetFrameExpandProc[soft, frameCT, NIL];
CoreFrame.SetFrameExpandProc[hard, frameCT, NIL];
FOR val: NAT ← sums/2, val/2 WHILE val#0
DO topDegree ← topDegree + 1 ENDLOOP;
FOR phyIndex: INT DECREASING IN [0..domain) DO
blank:  BOOL ← out0.x[phyIndex].n[]=CoreName.RopeNm["nil"];
xorCtx: CoreName.Context ← CoreName.NewContext[];
gateCtx: CoreName.Context ← CoreName.NewContext[];
specificXor, specificGate: Core.CellType;
logicalIndex: INT ← CoreXform.XformIndex[xform, rl, phyIndex].i;
tc: CoreXform.Coord ← CoreXform.FlatTreeIndex[domain, logicalIndex];
genXorCell: Core.CellType ← CoreLibrary.Get[library,
( IF blank
THEN "DpXorBlank"
ELSE "DpXor") ];
genGateCell: Core.CellType ← CoreLibrary.Get[library,
( IF blank OR topDegree >= tc.degree
THEN "DpGateBlank"
ELSE IF (tc.degree MOD 2)#(tc.degrees MOD 2)
THEN "DpNand"
ELSE "DpNor") ];
xorPublic: Core.Wire ← CoreOps.CreateWires[genXorCell.public.size];
gatePublic: Core.Wire ← CoreOps.CreateWires[genGateCell.public.size];
FOR index: INT IN [0..genXorCell.public.size) DO
aName: ROPE ← CoreName.WireNm[genXorCell.public[index]].n;
aName  ← TranslateGenericName[TRUE, aName, [frameCT.public], phyIndex];
xorPublic[index] ← CoreName.CtxWire[xorCtx, aName];
ENDLOOP;
FOR index: INT IN [0..genGateCell.public.size) DO
aName: ROPE ← CoreName.WireNm[genGateCell.public[index]].n;
aName  ← TranslateGenericName[FALSE, aName, [frameCT.public], phyIndex];
gatePublic[index] ← CoreName.CtxWire[gateCtx, aName];
ENDLOOP;
specificXor ← CoreCreate.Cell[xorPublic, NIL, NIL, LIST[
CoreCreate.Instance[genXorCell, [genXorCell.public, xorPublic]]]];
specificGate ← CoreCreate.Cell[gatePublic, NIL, NIL, LIST[
CoreCreate.Instance[genGateCell, [genGateCell.public, gatePublic]]]];
CoreFrame.FCT[frame.seq[1]].seq[phyIndex] ← CoreFrame.NewFrameCells[LIST[
CoreGlue.CellProc[],
CoreFrame.NewFrameCell[0, NIL, [first: left, cell: specificXor]] ], NIL, [first: left]];
CoreFrame.FCT[frame.seq[3]].seq[phyIndex] ← CoreFrame.NewFrameCells[LIST[
CoreGlue.CellProc[],
CoreFrame.NewFrameCell[0, NIL, [first: left, cell: specificGate]] ], NIL, [first: left]];
CoreBlock.PutCellSide [specificXor, left];
CoreBlock.PutCellSide [specificGate, left];
CoreBlock.MergeSides [specificXor];
CoreBlock.MergeSides [specificGate];
PWCore.SetAbutX  [specificXor];
PWCore.SetAbutX  [specificGate];
xorCtx  ← CoreName.KillContext[xorCtx];
gateCtx ← CoreName.KillContext[gateCtx];
ENDLOOP;
MatchID ← MatchID + 1;
frameCT.class ← CoreFrame.frameCellClass;
frameCT.data  ← frame;
CoreFrame.SetFrameExpandProc[soft, frameCT, NIL];
CoreFrame.SetFrameExpandProc[hard, frameCT, NIL] };
TranslateGenericName: PROC[gate: BOOL, name: ROPE, public: CWire, pIndex: INT]
RETURNS[new: ROPE] = {
keyIndex: KeyIndex ← NARROW[HashTable.Fetch[xlateTable, name].value];
xform:  CoreXform.Xform ← CoreXform.GetXform[public.f["out"].i[0]];
domain:  NAT   ← CoreXform.XformSize[xform];
logicalIndex: NAT   ← CoreXform.XformIndex[xform, rl, pIndex].i;
tc:   CoreXform.Coord ← CoreXform.FlatTreeIndex[domain, logicalIndex];
pos:  {left, right, middle};
IF NOT gate AND keyIndex#NIL THEN
RETURN[public.f[keyIndex.key].i[keyIndex.index].x[pIndex].n[]];
pos ←
IF name.Find["out0"]#-1 THEN middle ELSE
IF name.Find["in0"]#-1 THEN left ELSE
IF name.Find["in1"]#-1 THEN right ELSE ERROR;
IF ~gate THEN {tc.degree ← tc.degrees; tc.index ← pIndex; IF pos#middle THEN Signal[]};
new ← IO.PutFR[ "%g%gd%gi%02g",
IO.rope[IF (tc.degree MOD 2)#(tc.degrees MOD 2) THEN "nM" ELSE "M"],
IO.int[MatchID],
IO.int[IF pos=middle THEN tc.degree ELSE tc.degree+1 ],
IO.int[SELECT pos FROM
middle => tc.index,
left  => (tc.index)*2,
right  => (tc.index)*2 + 1, ENDCASE => ERROR ] ] };
MatchID:   INT ← 0;
KeyIndex:  TYPE = REF KeyIndexRec;
KeyIndexRec: TYPE = RECORD[key: ROPE, index: INT];
xlateTable:  HashTable.Table;
InitXlateTable: PROC = {
Store: PROC[refName, key: ROPE, index: INT] = {
refName ← CoreName.RopeNm[refName];
key  ← CoreName.RopeNm[key];
[] ← HashTable.Store[xlateTable, refName, NEW[KeyIndexRec ← [key, index]]]};
xlateTable ← HashTable.Create[equal: HashTable.RopeEqual, hash: HashTable.HashRope];
Store[ "in0",  "in",  0];
Store[ "in1",  "in",  1];
Store[ "out0",  "out",  0];
Store[ "out1",  "out",  1];
Store[ "0",  "left",  0];
Store[ "1",  "left",  1];
Store[ "rt0",  "right", 0];
Store[ "rt1",  "right", 1];
Store[ "GND", "pwr", 0];
Store[ "VDD", "pwr", 1] };
InitXlateTable[];
IFUCoreData.RegisterSubClassExpand [soft, "Match", ExpandDataMatchFrame];
IFUCoreData.RegisterSubClassExpand [hard, "Match", ExpandDataMatchFrame];
END.