DecorateFlatten:
PUBLIC
PROC [cellType: CellType, obj: Object, sort:
PROC [
CD.Position,
CD.Position]
RETURNS [
BOOL]] = {
ir: CD.Rect ← CD.InterestRect[obj];
extractedCT: CellType ← NARROW [Sinix.Extract[obj, extractMode].result];
extractedToSource: HashTable.Table ← HashTable.Create[CoreOps.WireBits[extractedCT.public]]; -- table of publics of extracted to publics of source
extractedCTData: CoreClasses.RecordCellType ← NARROW [extractedCT.data];
cellTypeData: CoreClasses.RecordCellType ← NARROW [cellType.data];
positionnedInstances: LIST OF PositionnedInstance;
positionnedWires: LIST OF PositionnedWire;
DecorateActual:
PROC [bindings: HashTable.Table, sourceActual, deepPublic: Wire] = {
wireBind: CoreFlat.FlatWire ← NARROW [HashTable.Fetch[bindings, deepPublic].value]; -- bindings=NIL would mean that extractedCT is a leaf, which is impossible
extractedActual: Wire;
wire: Wire;
FOR i: NAT IN [0 .. sourceActual.size) DO DecorateActual[bindings, sourceActual[i], deepPublic[i]] ENDLOOP;
IF deepPublic.size#0 THEN RETURN;
IF wireBind=NIL THEN ERROR Error[$InternalBug, "Internal invariant failed", cellType]; -- something is really wrong!
IF wireBind.flatCell#[] THEN ERROR Error[$InternalBug, "Internal invariant failed", cellType]; -- a deep internal wire
extractedActual ← wireBind.wire;
IF sourceActual.size#extractedActual.size THEN ERROR Error[$InternalBug, "Internal invariant failed", cellType];
wire ← NARROW [HashTable.Fetch[extractedToSource, extractedActual].value];
IF wire=sourceActual THEN RETURN;
IF wire#NIL THEN SIGNAL PinsCorrespondingToSeveralPublics[cellType, obj, LIST [wire, sourceActual], CoreGeometry.GetPins[extractMode.decoration, extractedActual]];
CoreGeometry.AddIndirectLazyPins[extractMode.decoration, sourceActual, extractedActual];
[] ← HashTable.Insert[extractedToSource, extractedActual, sourceActual];
};
[positionnedInstances, positionnedWires] ← GetPositionnedInstances[extractedCT, sort];
CoreGeometry.PutIR[extractMode.decoration, cellType, CD.InterestRect[obj]];
IF cellTypeData.size#GList.Length[positionnedInstances] THEN ERROR Error[$CallerBug, IO.PutFR["Mismatch between extracted layout (%g instances) and source description (%g instances)", IO.int[GList.Length[positionnedInstances]], IO.int[cellTypeData.size]], cellType];
CoreOps.VisitRootAtomics[cellType.public, SmashPins];
FOR i:
NAT
IN [0 .. cellTypeData.size)
DO
positionnedInstance: PositionnedInstance = positionnedInstances.first;
cell: CellType = positionnedInstance.cell;
sourceCellType: CellType = NARROW [cell.data, LayoutData].cellType;
IF Layout[cellTypeData[i].type]#Layout[sourceCellType] THEN ERROR Error[$CallerBug, IO.PutFR["Mismatch between the %gth instance of the extracted layout and the %gth instance of the source description: cellTypes are different", IO.int[i], IO.int[i]], cellType];
CoreGeometry.PutTransf[extractMode.decoration, cellTypeData[i], positionnedInstance.transf];
IF ~ CoreOps.CorrectConform[cellTypeData[i].actual, cell.public] THEN ERROR Error[$InternalBug, "Call Implementor!", cellType];
FOR j:
NAT
IN [0 .. cell.public.size)
DO
DecorateActual[positionnedInstance.bindings, cellTypeData[i].actual[j], cell.public[j]];
ENDLOOP;
positionnedInstances ← positionnedInstances.rest;
ENDLOOP;
We copy the pins for all publics. For now, we only do it for wires which have the same name as some internal of cellType.
All this code stinks ....
WHILE positionnedWires#
NIL
DO
positionnedWire: PositionnedWire = positionnedWires.first;
wire: Wire = positionnedWire.wire;
flatWire: CoreFlat.FlatWireRec = positionnedWire.flatWire;
name: ROPE = CoreOps.GetShortWireName[wire];
source: Wire ← NARROW [HashTable.Fetch[extractedToSource, flatWire.wire].value];
IF flatWire.flatCell#[] THEN ERROR Error[$InternalBug, "Call implementor!", cellType]; -- not yet implemented if it is not part of the internal of extractedCT
The following line is to pass PWCoreRoute test
All this code stinks ....
IF source=NIL THEN source ← CoreOps.FindWire[cellTypeData.internal, name];
If source is NIL, crash!
IF source=NIL THEN SIGNAL Signal[cellType];
If it is an internal only, let's forget it!
IF source#
NIL
AND CoreOps.RecursiveMember[cellType.public, source]
THEN
FOR list:
LIST
OF
CD.Instance ← positionnedWire.geometry, list.rest
WHILE list#
NIL
DO
IF NOT CoreGeometry.AtEdge[ir, list.first] THEN LOOP;
CoreGeometry.PutPins[
extractMode.decoration, source,
CONS [list.first, CoreGeometry.GetPins[extractMode.decoration, source]]
];
ENDLOOP;
positionnedWires ← positionnedWires.rest;
ENDLOOP;
};
GetPositionnedInstances:
PROC [extractedCT: CellType, sort: SortProc]
RETURNS [positionnedInstances:
LIST
OF PositionnedInstance ←
NIL, positionnedWires:
LIST
OF PositionnedWire ←
NIL] = {
InsertInOrdered:
PROC [element: PositionnedInstance, sorted:
LIST
OF PositionnedInstance]
RETURNS [new:
LIST
OF PositionnedInstance] = {
IF sorted=NIL THEN RETURN [LIST [element]];
IF sort[CDBasics.BaseOfRect[CDInstances.InstRectO[element.transf]], CDBasics.BaseOfRect[CDInstances.InstRectO[sorted.first.transf]]] THEN RETURN [CONS [element, sorted]];
RETURN [CONS [sorted.first, InsertInOrdered[element, sorted.rest]]];
};
Leaf: CoreGeometry.LeafProc = {RETURN [cellType.class=layoutClass]};
EachFlatWire: CoreGeometry.EachFlatWireProc = {
positionnedWires ←
CONS [
NEW [PositionnedWireRec ← [wire: wire, flatWire: flatWire, geometry: geometry]],
positionnedWires];
};
EachFlatCell: CoreGeometry.EachFlatCellProc = {
positionnedInstances ←
CONS [
NEW [PositionnedInstanceRec ← [
cell: cell, flatCell: flatCell, bindings: bindings, transf: transf
]],
positionnedInstances];
};
Compare: GList.CompareProc = {
pi1: PositionnedInstance = NARROW [ref1];
pi2: PositionnedInstance = NARROW [ref2];
RETURN [IF sort[CDBasics.BaseOfRect[CDInstances.InstRectO[pi1.transf]], CDBasics.BaseOfRect[CDInstances.InstRectO[pi2.transf]]] THEN less ELSE greater];
};
CoreGeometry.EnumerateFlatGeometry[decoration: extractMode.decoration, root: extractedCT, leafProc: Leaf, eachFlatWire: EachFlatWire, eachFlatCell: EachFlatCell];
positionnedInstances ← NARROW [GList.Sort[positionnedInstances, Compare]];
};