<> <> <> <<>> DIRECTORY CD, CCDUtils, Core, CoreBlock, CoreClasses, CoreCreate, CoreFrame, CoreGlue, CoreName, CoreOps, CoreWire, CoreXform, HashTable, IFUCoreData, IO, Rope; IFUCoreDataSBImpl: CEDAR PROGRAM IMPORTS CCDUtils, CoreBlock, CoreCreate, CoreFrame, CoreGlue, CoreName, CoreOps, CoreWire, CoreXform, HashTable, IFUCoreData, Rope = BEGIN OPEN CM: CCDUtils; ROPE: TYPE = Core.ROPE; <<>> Signal: SIGNAL = CODE; ExpandDataSBFrameSoft: CoreFrame.ExpandProc = { -- frameCT eachWire: CoreOps.EachWireProc = { IF wire.size#0 THEN RETURN; wire _ CoreName.CtxWire[ctx, CoreName.WireNm[wire].n ]; [ ] _ CoreBlock.AddWireSide[wire, current]}; ctx: CoreName.Context _ CoreName.NewContext[]; rowPub: CoreWire.CWire _ [frameCT.public]; frame: REF CoreFrame.FrameRec _ NEW[CoreFrame.FrameRec _ [first: left]]; current: CoreBlock.Sides; current _ left; [ ] _ CoreOps.VisitWire[rowPub.f["left"].w, eachWire]; current _ right; [ ] _ CoreOps.VisitWire[rowPub.f["right"].w, eachWire]; frame.seq _ NEW[CoreFrame.FrameSeq[0]]; frame.cell _ CoreCreate.Cell[ public: CoreOps.CreateWire[CoreName.WiresFromCtx[ctx]], instances: NIL]; ctx _ CoreName.KillContext[ctx]; frameCT.class _ CoreFrame.frameCellClass; frameCT.data _ frame; CoreFrame.SetFrameExpandProc[soft, frameCT, NIL]}; <<>> CWire: TYPE = CoreWire.CWire; Node: TYPE = CoreGlue.Node; NodeRec: TYPE = CoreGlue.NodeRec; ExpandDataSBFrameHard: CoreFrame.ExpandProc = { rowPub: CoreWire.CWire _ [frameCT.public]; data: IFUCoreData.DpCellData _ NARROW[frameCT.data]; name: ROPE _ CoreName.CellNm[frameCT].n; frame: REF CoreFrame.FrameRec _ NEW[CoreFrame.FrameRec _ [first: left, seq: NEW[CoreFrame.FrameSeq[0]]]]; frame.cell _ ThreeLevelSB[ cwire: rowPub, channels: data.channels, polyMaxRef: data.data ]; frameCT.data _ frame; frameCT.class _ CoreFrame.frameCellClass; CoreFrame.SetFrameExpandProc[hard, frameCT, NIL];}; ThreeLevelSB: PROC[ cwire: CWire, channels: INT, polyMaxRef: REF _ NIL ] -- REF INT, lengths less than or equal to this are poly RETURNS[cellType: Core.CellType] = { range: INT _ CoreXform.XformSize[cwire.f["top"].i[0]]; cellWidth: INT _ IFUCoreData.CellWidth[channels]; left: INT _ CM.metW/2-CM.leftTail; right: INT _ CM.metW/2-CM.leftTail+range*cellWidth; polyMax: INT _ IF polyMaxRef#NIL THEN NARROW[polyMaxRef, REF INT]^ ELSE -1; symTab: HashTable.Table _ BuildSymbolTable[cwire, CM.metPitch, polyMax, left, right, channels]; cellType _ CoreGlue.ThreeLevelRoute[symTab, range, left, right, cellWidth, channels]; RETURN[cellType]}; BuildSymbolTable: PROC[cwire: CWire, pitchX, polyMax, left, right, channels: INT] RETURNS[symTab: HashTable.Table] = { cellWidth: INT _ IFUCoreData.CellWidth[channels]; GetNode: PROC[name: ROPE] RETURNS[node: Node] = { IF IsPwr[name] THEN RETURN[NIL]; IF name=NIL THEN RETURN[NIL]; node _ NARROW[HashTable.Fetch[symTab, name].value]; IF node=NIL THEN { node _ NEW[NodeRec _ [name: name, minX: right, maxX: 0, type: CM.cmosMet2]]; [ ] _ HashTable.Store[symTab, name, node] } }; MarkPolys: HashTable.EachPairAction = { node: Node _ NARROW[value]; node.type _ IF node.maxX-node.minX <= polyMax THEN CM.cmosPoly ELSE CM.cmosMet2; RETURN[FALSE] }; symTab _ HashTable.Create[equal: HashTable.RopeEqual, hash: HashTable.HashRope]; FOR row: INT IN [0..cwire.f["left"].w.size) DO node: Node _ GetNode[cwire.f["left"].i[row].n]; IF node=NIL THEN LOOP; node.minX _ left ENDLOOP; FOR row: INT IN [0..cwire.f["right"].w.size) DO node: Node _ GetNode[cwire.f["right"].i[row].n]; IF node=NIL THEN LOOP; node.maxX _ right ENDLOOP; FOR wd: INT IN [0..cwire.f["top"].w.size) DO FOR bit: INT IN [0..CoreXform.XformSize[cwire.f["top"][0]]) DO coord: INT _ bit*cellWidth + wd*pitchX; node: Node _ GetNode[cwire.f["top"].i[wd].x[bit].n]; IF node=NIL THEN LOOP; node.top _ CONS [coord, node.top]; node.minX _ MIN [coord, node.minX]; node.maxX _ MAX [coord, node.maxX] ENDLOOP ENDLOOP; FOR wd: INT IN [0..cwire.f["bot"].w.size) DO FOR bit: INT IN [0..CoreXform.XformSize[cwire.f["bot"][0]]) DO coord: INT _ bit*cellWidth + wd*pitchX; node: Node _ GetNode[cwire.f["bot"].i[wd].x[bit].n]; IF node=NIL THEN LOOP; node.bot _ CONS [coord, node.bot]; node.minX _ MIN [coord, node.minX]; node.maxX _ MAX [coord, node.maxX] ENDLOOP ENDLOOP; [ ] _ HashTable.Pairs[symTab, MarkPolys]}; IsPwr: PROC[name: ROPE] RETURNS[BOOL] = {RETURN[Rope.Find[name,"GND"]#-1 OR Rope.Find[name,"VDD"]#-1]}; log: IO.STREAM _ CoreFrame.GetLog[]; IFUCoreData.RegisterSubClassExpand[soft, "SwitchBox", ExpandDataSBFrameSoft]; IFUCoreData.RegisterSubClassExpand[hard, "SwitchBox", ExpandDataSBFrameHard]; END.