IFUCoreDataMatchImpl:
CEDAR
PROGRAM
IMPORTS CoreBlock, CoreCreate, CoreFrame, CoreGlue, CoreLibrary, CoreName, CoreOps, CoreWire, CoreXform, HashTable, IFUCoreCells, IFUCoreData, IO, PWC, 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];
PWC.SetAbutX [specificXor];
PWC.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.