<> <> <> <<>> DIRECTORY CD, Core, CoreBlock, CoreCreate, CoreFrame, CoreGlue, CoreLibrary, CoreName, CoreOps, CoreWire, CoreXform, HashTable, IFUCoreCells, IFUCoreData, IO, PWC, Rope; 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[ "GND", "pwr", 0]; Store[ "VDD", "pwr", 1] }; <<>> InitXlateTable[]; IFUCoreData.RegisterSubClassExpand [soft, "Match", ExpandDataMatchFrame]; IFUCoreData.RegisterSubClassExpand [hard, "Match", ExpandDataMatchFrame]; END.