MakeRangeExtractor:
PUBLIC PROC [index, subSize, size:
NAT]
RETURNS [wire: Wire, obj:
CD.Object] = {
We create an extra level of hierarchy in the wires to extract things properly
structWire: Wire ← CoreOps.CreateWires[size: size];
subWire: Wire ← CoreOps.CreateWires[size: subSize];
wire ← CoreOps.CreateWire[LIST [subWire, structWire]];
The composed wires
FOR i: NAT IN [0 .. size) DO structWire[i] ← CoreOps.CreateWire[] ENDLOOP;
FOR i: NAT IN [0 .. subSize) DO subWire[i] ← structWire[i+index] ENDLOOP;
obj ← PW.CreateEmptyCell[];
The structured wire
Sinix.AddPinsProp[
Sisyph.sisyphMode, structWire,
PW.IncludeInCell[obj, CDRects.CreateRect[[19*l/2, l/2], CD.commentLayer], [0, 2*l]]
];
The extracted wire
Sinix.AddPinsProp[
Sisyph.sisyphMode, subWire,
PW.IncludeInCell[obj, CDRects.CreateRect[[l, 3*l/2], CD.commentLayer], [5*l/2, 0]]
];
The rectangle
[] ← PW.IncludeInCell[obj, CDRects.CreateRect[[5*l/2, l/8], CD.commentLayer], [l, 3*l/2]];
[] ← PW.IncludeInCell[obj, CDRects.CreateRect[[5*l/2, l/8], CD.commentLayer], [l, 3*l]];
[] ← PW.IncludeInCell[obj, CDRects.CreateRect[[l/8, 3*l/2], CD.commentLayer], [l, 3*l/2]];
[] ← PW.IncludeInCell[obj, CDRects.CreateRect[[l/8, 3*l/2], CD.commentLayer], [27*l/8, 13*l/8]];
The texts
[] ← PW.IncludeInCell[obj, CDTexts.CreateText[IO.PutFR["%g/%g", IO.int[index], IO.int[subSize]], font], [7*l/2, -3*l/4]];
[] ← PW.IncludeInCell[obj, CDTexts.CreateText[IO.PutR1[IO.int[size]], font], [7*l/2, 2*l]];
CDProperties.PutObjectProp[obj, $ExtractorIndex, NEW [INT ← index]];
CDProperties.PutObjectProp[obj, $ExtractorSubSize, NEW [INT ← subSize]];
CDProperties.PutObjectProp[obj, $ExtractorSize, NEW [INT ← size]];
CDProperties.PutObjectProp[obj, Sisyph.sisyphMode.extractProcProp, $WireIconsExtractRangeExtractor];
PW.SetInterestRect[obj, [19*l/2, 7*l/2]];
PW.RepositionCell[obj];
};
RangeExtractor:
PW.UserProc = {
name: ROPE;
int: INT ← PW.RequestInt["Index of the extracted wire? "];
int2: INT ← PW.RequestInt["Size of the extracted wire? "];
int3: INT ← PW.RequestInt["Size of the structured wire? "];
IF int<0 OR int2<1 OR int3<1 OR int>=int3 OR int+int2>int3 THEN RETURN;
name ← IO.PutFR[":RangeExtractor[%g/%g, %g].icon", IO.int[int], IO.int[int2], IO.int[int3]];
ob ← CDDirectory.Fetch[design, name].object;
IF ob=
NIL
THEN {
ob ← MakeRangeExtractor[NAT [int], NAT [int2], NAT [int3]].obj;
[] ← CDDirectory.Include[design, ob, name];
};
};
ExtractRangeExtractor: Sinix.ExtractProc = {
refNat: REF INT ← NARROW [CDProperties.GetObjectProp[obj, $ExtractorIndex]];
refNat2: REF INT ← NARROW [CDProperties.GetObjectProp[obj, $ExtractorSubSize]];
refNat3: REF INT ← NARROW [CDProperties.GetObjectProp[obj, $ExtractorSize]];
index: NAT ← NAT [refNat^];
subSize: NAT ← NAT [refNat2^];
size: NAT ← NAT [refNat3^];
result ← MakeRangeExtractor[index, subSize, size].wire;
};