Layout property
layoutProp: PUBLIC ATOM ← CoreProperties.RegisterProperty[$PWCoreLayout, CoreProperties.Props[[CoreProperties.propCopy, CoreProperties.PropDoCopy]]];
SetLayout:
PUBLIC
PROC [cellType: CellType, cdObject: Object] = {
cdNets: RefTab.Ref ← FindNets[cdObject];
nbAtomicWires: INT ← 0;
EachWire: CoreOps.EachWireProc = {
[wire: Wire] RETURNS [notSubWires: BOOL ← FALSE, quit: BOOL ← FALSE]
IF wire.elements#NIL THEN RETURN;
IF RefTab.Fetch[cdNets, wire].val=NIL THEN ERROR; -- wire has no pins
nbAtomicWires ← nbAtomicWires + 1;
};
CoreOps.VisitWire[cellType.publicWire, EachWire];
IF RefTab.GetSize[cdNets]#nbAtomicWires THEN ERROR; -- Some pins are associated with a non valid wire
CoreProperties.PutCellTypeProp[cellType, layoutProp, cdObject];
};
GetLayout:
PUBLIC
PROC [cellType: CellType]
RETURNS [cdObject: Object] = {
cdObject ← NARROW [CoreProperties.GetCellTypeProp[cellType, layoutProp]];
};
GateWay
-- A Gateway is a CD.Object whose specificRef points to a CellType
gateWayClass: PUBLIC REF CD.ObjectClass ← CD.RegisterObjectClass[$GateWayClass];
dpGateWayClass: REF CDDirectory.DirectoryProcs = CDDirectory.InstallDirectoryProcs[gateWayClass];
CreateGateWay:
PUBLIC
PROC [coreInstance: CellInstance]
RETURNS [cdObject: Object] = {
cdObject ← NEW [CD.ObjectRep ← [class: gateWayClass, specificRef: coreInstance]];
};
ExpandGateWay: CDDirectory.AnotherProc
-- [me: CD.Object, from: CD.Design, to: CD.Design] RETURNS [CD.Object] -- = {
RETURN [GetLayout[NARROW [me.specificRef, CellInstance].type]];
};
CreateGateWays:
PUBLIC
PROC [coreInstances:
LIST
OF CellInstance]
RETURNS [cdObjects:
LIST
OF Object] = {
WHILE coreInstances#
NIL
DO
cdObjects ← CONS [CreateGateWay[coreInstances.first], cdObjects];
coreInstances ← coreInstances.rest;
ENDLOOP;
cdObjects ← PW.Reverse[cdObjects];
};
Dealing with wires hanging on pins
wireOfPin: PUBLIC ATOM ← $PWCoreWireOfPin; -- The property on which the Wire of a pin hangs.
SetWire:
PUBLIC
PROC [pinInstance:
CD.Instance, wire: Wire] = {
CDProperties.PutPropOnInstance[pinInstance, wireOfPin, wire];
};
GetWire:
PUBLIC
PROC [pinInstance:
CD.Instance]
RETURNS [wire: Wire] = {
wire ← NARROW [CDProperties.GetPropFromInstance[pinInstance, wireOfPin]];
};
BindPins:
PUBLIC
PROC [cellType: CellType, cdObject: Object] = {
publicNames: SymTab.Ref ← SymTab.Create[];
EachWire: CoreOps.EachWireProc = {
[wire: Wire] RETURNS [notSubWires: BOOL ← FALSE, quit: BOOL ← FALSE]
IF wire.elements#NIL THEN RETURN;
IF wire.name=NIL THEN ERROR; -- all wires should be named at this point
IF ~SymTab.Store[publicNames, wire.name, wire] THEN ERROR; -- Two wires have the same name
};
EachPin: PWPins.InstanceEnumerator = {
[inst: CD.Instance] RETURNS [quit: BOOL ← FALSE]
name: ROPE ← CDPinObjects.GetName[inst];
wire: Wire ← NARROW [SymTab.Fetch[publicNames, name].val];
IF wire=NIL THEN ERROR;
SetWire[inst, wire];
};
CoreOps.VisitWire[cellType.publicWire, EachWire];
[] ← PWPins.EnumerateEdgePins[cdObject, EachPin];
};
Finding the nets
Each2WireProc: TYPE = PROC [wire1, wire2: Wire] RETURNS [notSubWires: BOOL ← FALSE, quit: BOOL ← FALSE];
Visit2Wire:
PUBLIC
PROC [wire1, wire2: Wire, eachWire: Each2WireProc]= {
RecurseOn2Wire:
PROC [wire1, wire2: Wire]
RETURNS [quit:
BOOL ←
FALSE] = {
notSubWires: BOOL;
[notSubWires, quit] ← eachWire[wire1, wire2];
IF
NOT quit
AND
NOT notSubWires
AND wire1.elements#
NIL
AND wire2.elements#
NIL
AND wire1.elements.size=wire2.elements.size
THEN
FOR i:
NAT
IN [0..wire1.elements.size)
DO
quit ← RecurseOn2Wire[wire1.elements[i], wire2.elements[i]];
IF quit THEN EXIT;
ENDLOOP;
};
IF wire1#NIL AND wire2#NIL THEN [] ← RecurseOn2Wire[wire1, wire2];
};
GateWayEnumerateDeepPinsInContext: PWPins.EnumerationProc = {
cellInstance: CellInstance ← NARROW [ob.specificRef];
translationTable: RefTab.Ref ← RefTab.Create[]; -- from the public Wire to the actual
Each2Wire: Each2WireProc = {
IF wire1.elements#NIL OR wire2.elements#NIL THEN RETURN;
[] ← RefTab.Store[translationTable, wire1, wire2];
};
TranslateEachPin: PWPins.InstanceEnumerator = {
[inst: CD.Instance] RETURNS [quit: BOOL ← FALSE]
wire: Wire ← GetWire[inst];
pin: CD.Instance ← NEW [CD.InstanceRep ← [ob: inst.ob, location: inst.location, orientation: inst.orientation, properties: CDProperties.DangerousCopyProps[inst.properties]]];
IF wire=NIL THEN ERROR; -- pin has no wire attribute
SetWire[pin, NARROW [RefTab.Fetch[translationTable, wire].val]];
quit ← eachPin[pin];
};
Visit2Wire[cellInstance.type.publicWire, cellInstance.actualWire, Each2Wire];
quit ← PWPins.EnumerateDeepPinsInContext[GetLayout[cellInstance.type], location, orientation, CDProperties.DangerousCopyProps[ob.properties], TranslateEachPin, stopEnumerateDeepPins, filter];
};
FindNets:
PUBLIC
PROC [obj:
CD.Object]
RETURNS [nets: RefTab.Ref] = {
EachPin: CDPinObjects.InstanceEnumerator = {
[inst: CD.Instance] RETURNS [quit: BOOL ← FALSE]
wire: Wire ← GetWire[inst];
pins: LIST OF CD.Instance;
IF wire=NIL THEN ERROR; -- pin has no wire property
pins ← CONS [inst, NARROW [RefTab.Fetch[nets, wire].val]];
[] ← RefTab.Store[nets, wire, pins];
};
nets ← RefTab.Create[];
[] ← PWPins.EnumerateEdgePins[obj, EachPin];
};
Short cuts
SetGet:
PUBLIC
PROC [cellType: CellType, source:
CD.Design] = {
cdObject: Object ← PW.Get[source, cellType.name];
BindPins[cellType, cdObject];
SetLayout[cellType, cdObject];
};
SetAbutX:
PUBLIC
PROC [cellType: CellType, instances:
LIST
OF CellInstance] = {
SetLayout[cellType, PW.AbutListX[NIL, CreateGateWays[instances]]];
};
SetAbutY:
PUBLIC
PROC [cellType: CellType, instances:
LIST
OF CellInstance] = {
SetLayout[cellType, PW.AbutListY[NIL, CreateGateWays[instances]]];
};
SetArrayX:
PUBLIC
PROC [cellType: CellType] = {
recasted: CellType ← CoreOps.Recast[cellType];
SetLayout[cellType, PW.AbutListX[NIL, CreateGateWays[NARROW [recasted.data, CoreClasses.RecordCellType].instances]]];
};
SetArrayY:
PUBLIC
PROC [cellType: CellType] = {
recasted: CellType ← CoreOps.Recast[cellType];
SetLayout[cellType, PW.AbutListY[NIL, CreateGateWays[NARROW [recasted.data, CoreClasses.RecordCellType].instances]]];
};
SetMapFunction: PUBLIC PROC [cellType: CellType] = {
Function: PW.XYFunction = {
cell: CellType ← mapFnCell.cells[mapFnCell.xyFn[x, y, NARROW [mapFnCell]]];
RETURN[CreateGateWay[cell]];
};
mapFnCell: CoreMapFunction.MapFnCellType ← NARROW [cellType.data];
SetLayout[cellType,
PW.MapFunction[NIL, Function, mapFnCell.lx, mapFnCell.ux, mapFnCell.ly, mapFnCell.uy]];
};
SetFlipX:
PUBLIC
PROC [cellType: CellType] = {
SetLayout[cellType, PW.FlipX[NIL, CreateGateWay[NARROW [cellType.data, CoreClasses.RecordCellType].instances.first]]];
};
SetFlipY:
PUBLIC
PROC [cellType: CellType] = {
SetLayout[cellType, PW.FlipY[NIL, CreateGateWay[NARROW [cellType.data, CoreClasses.RecordCellType].instances.first]]];
};
SetRot90:
PUBLIC
PROC [cellType: CellType] = {
SetLayout[cellType, PW.Rot90[NIL, CreateGateWay[NARROW [cellType.data, CoreClasses.RecordCellType].instances.first]]];
};
SetRot180:
PUBLIC
PROC [cellType: CellType] = {
SetLayout[cellType, PW.Rot180[NIL, CreateGateWay[NARROW [cellType.data, CoreClasses.RecordCellType].instances.first]]];
};
SetRot270:
PUBLIC
PROC [cellType: CellType] = {
SetLayout[cellType, PW.Rot270[NIL, CreateGateWay[NARROW [cellType.data, CoreClasses.RecordCellType].instances.first]]];
};
SetLazy:
PUBLIC
PROC [cellType: CellType, info:
REF, createProc: PWObjects.CreateProc] = {
SetLayout[cellType, PWObjects.CreateLazy[info: info, createProc: createProc]];
};
Initialization
gateWayClass.showMeSelected ← CDDefaultProcs.ShowMeSelectedWithExpand;
dpGateWayClass.expand ← ExpandGateWay;
gateWayClass.showMeSelected ← CDDefaultProcs.ShowMeSelectedWithExpand;
gateWayClass.interestRect ← CDDefaultProcs.InterestRectWithExpand;
[] ← CDProperties.RegisterAndInstall[wireOfPin, [makeCopy: CDProperties.CopyVal], $PWCore];
CDProperties.PutProp[gateWayClass, PWPins.enumerationProcProp, NEW [PWPins.EnumerationProc ← GateWayEnumerateDeepPinsInContext]];