<> <> <> DIRECTORY CoreCreate, CD, CDOrient, Basics, Core, CoreBlock, CoreGeometry, CoreIOIFUProps, CoreOps, CoreClasses, CoreFrame, CoreInstCell, CoreName, CoreProperties, HashTable, IO, PWC, Rope; CoreBlockImpl: CEDAR PROGRAM IMPORTS CD, CDOrient, Basics, CoreBlock, CoreOps, CoreFrame, CoreGeometry, CoreInstCell, CoreIOIFUProps, CoreName, CoreProperties, HashTable, IO, PWC, Rope EXPORTS CoreBlock = BEGIN OPEN CoreBlock; Wire: TYPE = Core.Wire; CellType: TYPE = Core.CellType; ROPE: TYPE = Core.ROPE; SidesProp: PROC RETURNS[ATOM] = {RETURN[CoreIOIFUProps.sides]}; Signal: SIGNAL[] = CODE; AddSide: PUBLIC PROC[new, old: Sides] RETURNS[Sides] = {RETURN[SidesFmWord[Basics.BITOR[SidesToWord[new], SidesToWord[old]]]]}; DelSide: PUBLIC PROC[new, old: Sides] RETURNS[Sides] = {RETURN[SidesFmWord[Basics.BITAND[Basics.BITNOT[SidesToWord[new]], SidesToWord[old]]]]}; OnSide: PUBLIC PROC[new, old: Sides] RETURNS[BOOL] = {RETURN[(Basics.BITAND[SidesToWord[new], SidesToWord[old]])#0]}; OtherSide: PUBLIC PROC[side: Sides] RETURNS[Sides] = {RETURN[SELECT side FROM bottom=>top, top=>bottom, left=>right, right=>left,ENDCASE=>none]}; SidesToWord: PUBLIC PROC[side: Sides] RETURNS[word: WORD] = {RETURN[LOOPHOLE[side]]}; SidesFmWord: PUBLIC PROC[word: WORD] RETURNS[side: Sides] = {RETURN[LOOPHOLE[Basics.BITAND[word, SidesToWord[all] ] ] ] }; GetCellSide: PUBLIC PROC[cell: CellType] RETURNS[side: Sides] = { refSides: REF Sides; IF cell=NIL THEN RETURN[none]; refSides _ NARROW[CoreProperties.GetCellTypeProp[cell, SidesProp[]]]; RETURN[IF refSides=NIL THEN none ELSE refSides^] }; PutCellSide: PUBLIC PROC[cell: CellType, side: Sides] = {CoreProperties.PutCellTypeProp[cell, SidesProp[], NEW[CoreBlock.Sides _ side]]}; GetWireSide: PUBLIC PROC[wire: Wire] RETURNS[side: Sides] = { refSides: REF Sides; IF wire=NIL THEN RETURN[none]; refSides _ NARROW[CoreProperties.GetWireProp[wire, SidesProp[]]]; RETURN[IF refSides=NIL THEN none ELSE refSides^]}; PutWireSide: PUBLIC PROC[wire: Wire, side: Sides] = { refSides: REF Sides; IF wire=NIL THEN RETURN; refSides _ NARROW[CoreProperties.GetWireProp[wire, SidesProp[]]]; IF refSides=NIL THEN CoreProperties.PutWireProp[wire, SidesProp[], NEW[CoreBlock.Sides _ side]] ELSE refSides^ _ side; FOR i: NAT IN [0..wire.size) DO PutWireSide[wire[i], side] ENDLOOP}; AddWireSide: PUBLIC PROC[wire: Wire, side: Sides] RETURNS[sameWire: Wire] = { refSides: REF Sides; IF wire=NIL THEN RETURN[NIL]; refSides _ NARROW[CoreProperties.GetWireProp[wire, SidesProp[]]]; IF refSides=NIL THEN refSides _ NEW[Sides _ none]; refSides^ _ AddSide[side, refSides^]; CoreProperties.PutWireProp[wire, SidesProp[], refSides]; FOR i: NAT IN [0..wire.size) DO wire[i] _ AddWireSide[wire[i], side] ENDLOOP; RETURN[wire]}; DelWireSide: PUBLIC PROC[wire: Wire, side: Sides] RETURNS[sameWire: Wire] = { refSides: REF Sides; IF wire=NIL THEN RETURN[NIL]; refSides _ NARROW[CoreProperties.GetWireProp[wire, SidesProp[]]]; IF refSides=NIL THEN refSides _ NEW[Sides _ none]; refSides^ _ DelSide[side, refSides^]; CoreProperties.PutWireProp[wire, SidesProp[], refSides]; FOR i: NAT IN [0..wire.size) DO wire[i] _ DelWireSide[wire[i], side] ENDLOOP; RETURN[wire]}; MergeSides: PUBLIC PROC[cell: CellType] = { first: Sides _ GetCellSide[cell]; last: Sides _ OtherSide[first]; hidden: Sides; data: CoreClasses.RecordCellType _ NARROW[cell.data]; visit: CoreOps.EachWirePairProc ~ { side: Sides _ GetWireSide[publicWire]; side _ DelSide[hidden, side]; [ ] _ AddWireSide[actualWire, side]}; IF data.size>1 AND first=none THEN Signal[]; FOR i: NAT IN [0..data.size) DO hidden _ IF i # 0 THEN first ELSE none; hidden _ AddSide[ IF (i+1) < data.size THEN last ELSE none, hidden]; [ ] _ CoreOps.VisitBinding[data[i].actual, data[i].type.public, visit] ENDLOOP; DeletePseudoPublics[cell]}; DeletePseudoPublics: PUBLIC PROC [cell: Core.CellType] = { publics: Core.Wires _ NIL; FOR i: INT DECREASING IN [0..cell.public.size) DO IF GetWireSide[ cell.public[i] ]#none THEN publics _ CONS[ cell.public[i], publics] ELSE log.PutF["\nRemoving pseudo public: %g", IO.rope[ CoreName.WireNm[cell.public[i]].n] ]; ENDLOOP; cell.public _ CoreOps.CreateWire[publics]}; RevInstances: PROC[list: CoreClasses.CellInstances] RETURNS[rev: CoreClasses.CellInstances] = { FOR list _ list, list.rest WHILE list#NIL DO rev _ CONS[list.first, rev] ENDLOOP}; AbutCellList: PUBLIC PROC[ name: ROPE, first: Sides, cellTypes: LIST OF CellType] RETURNS[cellType: CellType] = { temp: LIST OF CellType _ NIL; cts: LIST OF CellType _ NIL; data: CoreClasses.RecordCellType; <> <> < { }; ENDCASE => {>> <> <> <> <> <> <> <> <> <> <> <> DelPAInternalOnlys: PROC[context: CoreName.Context, ais: LIST OF PWC.AbutInstance] = { IsPublic: PROC[wr: CoreCreate.WR] RETURNS[BOOL] = {name: ROPE _ NARROW[wr]; RETURN[CoreName.CtxNameToWire[context, name]#NIL]}; FOR ais _ ais, ais.rest WHILE ais#NIL DO -- two LOOPs to avoid CONSing pas: LIST OF CoreCreate.PA; DO -- remove internal onlys from first of list IF ais.first.pas=NIL THEN GOTO Exit; IF IsPublic[ais.first.pas.first.actual] THEN EXIT; ais.first.pas _ ais.first.pas.rest; REPEAT Exit => LOOP; ENDLOOP; pas _ ais.first.pas; WHILE pas.rest#NIL DO -- remove internal onlys from rest of list IF IsPublic[pas.rest.first.actual] THEN pas _ pas.rest ELSE pas.rest _ pas.rest.rest ENDLOOP; ENDLOOP}; checking: BOOL _ TRUE; OutSides: PROC[index, size: INT, first: Sides] RETURNS[ outSides: Sides _ all] = { nextInSide, lastInSide: Sides; SELECT first FROM left => {nextInSide _ right; lastInSide _ left}; bottom => {nextInSide _ top; lastInSide _ bottom}; right => {nextInSide _ left; lastInSide _ right}; top => {nextInSide _ bottom; lastInSide _ top}; ENDCASE => Signal[]; IF index#0 THEN outSides _ DelSide[lastInSide, outSides]; IF index+1#size THEN outSides _ DelSide[nextInSide, outSides]}; <<>> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> < RevInstances[instances], ENDCASE => instances;>> <> <> <> < PWC.SetAbutX[cellType];>> < PWC.SetAbutY[cellType];>> < Signal[] };>> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> < RevInstances[instances], ENDCASE => instances;>> <> <> <> < PWC.SetAbutX[cellType];>> < PWC.SetAbutY[cellType];>> < Signal[] };>> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <