<> <> <> <> <<>> DIRECTORY CD, CDCells, CDDirectory, CDEvents, CDInstances, CDLayers, CDProperties, CDRects, CDTexts, CDViewer, Core, CoreOps, CoreProperties, IO, PipalCore, PipalSinix, PipalSisyph, PipalWireIcons, PW, TerminalIO, ViewerOps; PipalWireIconsImpl: CEDAR PROGRAM IMPORTS CD, CDCells, CDDirectory, CDEvents, CDInstances, CDLayers, CDProperties, CDRects, CDTexts, CDViewer, CoreOps, CoreProperties, IO, PipalCore, PipalSinix, PipalSisyph, PW, TerminalIO, ViewerOps EXPORTS PipalWireIcons SHARES PipalSisyph = BEGIN OPEN PipalWireIcons; <> font: CDTexts.CDFont _ CDTexts.MakeFont["Xerox/TiogaFonts/Helvetica8", 4]; AddRect: PROC [size, pos: CD.Position, il: CD.InstanceList] RETURNS [newIl: CD.InstanceList] = { newIl _ CONS [CDInstances.NewInst[CDRects.CreateRect[size, CD.commentLayer], [pos]], il]; }; AddText: PROC [rope: ROPE, pos: CD.Position, il: CD.InstanceList] RETURNS [newIl: CD.InstanceList] = { newIl _ CONS [CDInstances.NewInst[CDTexts.Create[rope, font], [pos]], il]; }; PutPin: PROC [wire: Wire, size, pos: CD.Position, il: CD.InstanceList] RETURNS [newIl: CD.InstanceList] = { newIl _ AddRect[size, pos, il]; PipalCore.PutPins[PipalSisyph.mode.decoration, wire, LIST [[newIl.first.ob, newIl.first.trans]]]; }; EvalNat: PROC [cx: PipalSisyph.Context, expr: ROPE] RETURNS [nat: NAT] = { WITH PipalSisyph.EvalToRef[cx, expr] SELECT FROM refInt: REF INT => RETURN [NAT[refInt^]]; refNat: REF NAT => RETURN [refNat^]; ENDCASE => ERROR; -- Wrong type }; <> MakeComposer: PUBLIC PROC [design: CD.Design, size: NAT] RETURNS [wire: Wire, obj: CD.Object] = { il: CD.InstanceList _ NIL; increment: INT _ SELECT TRUE FROM size<4 => 8, size<6 => 6, size<8 => 4, size<16 => 2, size<32 => 2, ENDCASE => 1; wire _ CoreOps.CreateWires[size: size]; <> il _ AddRect[[increment*(size-1)* <> il _ PutPin[wire, [ <> FOR i: NAT IN [0 .. size) DO wire[i] _ CoreOps.CreateWire[]; il _ PutPin[wire[i], [ ENDLOOP; <> il _ AddRect[[ obj _ PW.CreateCell[instances: il, props: LIST [[$ComposerSize, NEW [INT _ size]], [PipalSisyph.mode.extractProcProp, $WireIconsExtractComposer]]]; CDCells.SetSimplificationTreshhold[obj, 10.0]; }; Composer: PW.GeneratorProc = { name: ROPE; int: INT _ TerminalIO.RequestInt["Size of the composer? "]; IF int<1 THEN {TerminalIO.PutF["*** Incorrect parameter.\n"]; RETURN}; name _ IO.PutFR["::Composer[%g].icon", IO.int[int]]; ob _ CDDirectory.Fetch[design, name].object; IF ob=NIL THEN { ob _ MakeComposer[design, NAT [int]].obj; [] _ CDDirectory.Include[design, ob, name]; }; }; ExtractComposer: PipalSinix.ExtractProc = { cx: PipalSisyph.Context = NARROW [userData]; refNat: REF INT _ NARROW [CDProperties.GetObjectProp[obj, $ComposerSize]]; size: NAT _ NAT [refNat^]; result _ MakeComposer[PipalSisyph.GetDesign[cx], size].wire; }; <> AdjGridWidthComposer: PW.GeneratorProc = { name: ROPE; grid: INT _ Grid[design]; n: INT _ TerminalIO.RequestInt["Size of the composer? "]; w: INT _ CDLayers.LayerWidth[design, CD.commentLayer]; IF n<1 THEN {TerminalIO.PutF["*** Invalid parameter.\n"]; RETURN}; name _ IO.PutFR["ComposerP%gW%g[%g].icon", IO.int[grid], IO.int[w], IO.int[n]]; ob _ CDDirectory.Fetch[design, name].object; IF ob=NIL THEN { ob _ AdjGridWidthComposerObj[design, grid, n].obj; [] _ CDDirectory.Include[design, ob, name]}}; AdjGridWidthComposerObj: PROC [design: CD.Design, grid, n: INT] RETURNS [obj: CD.Object] = { Add: PROC[name: ROPE _ NIL, size, pos: CD.Position] = { list _ CONS[CDInstances.NewInst[CDRects.CreateRect[size, CD.commentLayer], [pos]], list]; IF name#NIL THEN { names: LIST OF ROPE _ LIST[name]; CDProperties.PutInstanceProp[list.first, PipalSisyph.expressionsProp, names]}}; list: CD.InstanceList _ NIL; w: INT _ CDLayers.LayerWidth[design, CD.commentLayer]; l: INT _ MAX[w, grid/4]; wireNm: IO.ROPE _ "w"; wire: Core.Wire _ IndexedWire[wireNm, n]; Add[size:[2*l, grid*2*n+w], pos:[l, 0]]; CDProperties.PutInstanceProp[list.first, PipalSisyph.mode.extractProcProp, $ExtractNull]; Add[name: wireNm, size:[l, w], pos:[0, grid]]; FOR ii: INT IN [0..n) DO name: IO.ROPE _ CoreOps.GetShortWireName[wire[ii]]; Add[name: name, size:[l, w], pos:[3*l, (2*ii+1)*grid]] ENDLOOP; obj _ PW.CreateCell[instances: list]; CDProperties.PutObjectProp [obj, $CodeFor, IO.PutFR["PipalWireIcons.IndexedWire[\"%g\",%g]", IO.rope[wireNm], IO.int[n]]]; CDProperties.PutObjectProp[obj, PipalSisyph.mode.extractProcProp, $SisyphExtractUnNamedWireIcon]; CDCells.SetSimplificationTreshhold[obj, 20]}; IndexedWire: PUBLIC PROC[name: ROPE, n: NAT] RETURNS [wire: Wire] ~ { wire _ CoreOps.CreateWires[n, name]; FOR ii: INT IN [0..n) DO wire[ii] _ CoreOps.CreateWires[0, IO.PutFR["%g%g", IO.rope[name], IO.int[ii]]] ENDLOOP}; <> Grid: PROC[design: CD.Design] RETURNS[grid: NAT _ 0] = { viewers: CDViewer.ViewerList _ CDViewer.ViewersOf[design]; IF viewers#NIL THEN WITH ViewerOps.GetViewer[viewers.first, $Grid] SELECT FROM rgrid: REF CD.Number => grid _ rgrid^; ENDCASE; IF grid=0 THEN grid _ design.technology.lambda*2}; <> MakeSlash: PROC [design: CD.Design] RETURNS [obj: CD.Object] = { il: CD.InstanceList _ NIL; FOR i: INT IN [0 .. 2* obj _ PW.CreateCell[il]; CDCells.SetSimplificationTreshhold[obj, 10.0]; }; MakeBus: PUBLIC PROC [design: CD.Design, size: NAT, slash: CD.Object _ NIL] RETURNS [wire: Wire, obj: CD.Object] = { il: CD.InstanceList _ NIL; wire _ CoreOps.CreateWires[size: size]; <> IF slash#NIL THEN il _ CONS [CDInstances.NewInst[slash, [[ <> il _ PutPin[wire, [9* <> FOR i: NAT IN [0 .. size) DO wire[i] _ CoreOps.CreateWire[] ENDLOOP; <> il _ AddText[IO.PutR1[IO.int[size]], [6* obj _ PW.CreateCell[instances: il, ir: [0, 0, 9*[PipalSisyph.mode.extractProcProp, $WireIconsExtractBus]]]; CDCells.SetSimplificationTreshhold[obj, 10.0]; }; Bus: PW.GeneratorProc = { slash: CD.Object; int: INT _ TerminalIO.RequestInt["Size of the bus? "]; IF int<1 THEN {TerminalIO.PutF["*** Incorrect parameter.\n"]; RETURN}; slash _ CDDirectory.Fetch[design, "::SlashForBusIcon"].object; IF slash=NIL THEN { slash _ MakeSlash[design]; [] _ CDDirectory.Include[design, slash, "::SlashForBusIcon"]; }; ob _ MakeBus[design, NAT [int], slash].obj; }; ExtractBus: PipalSinix.ExtractProc = { cx: PipalSisyph.Context = NARROW [userData]; refNat: REF INT _ NARROW [CDProperties.GetObjectProp[obj, $BusSize]]; size: NAT _ NAT [refNat^]; result _ MakeBus[PipalSisyph.GetDesign[cx], size].wire; }; <> MakeExtractor: PUBLIC PROC [design: CD.Design, index, size: NAT] RETURNS [wire: Wire, obj: CD.Object] = { il: CD.InstanceList _ NIL; wire _ CoreOps.CreateWires[size: size]; <> FOR i: NAT IN [0 .. size) DO wire[i] _ CoreOps.CreateWire[] ENDLOOP; <> il _ PutPin[wire, [9* <> il _ PutPin[wire[index], [ <> il _ AddRect[[3* il _ AddRect[[3* il _ AddRect[[ il _ AddRect[[ <> il _ AddText[IO.PutR1[IO.int[index]], [9* il _ AddText[IO.PutR1[IO.int[size]], [9* obj _ PW.CreateCell[instances: il, ir: [0, 0, 9*NEW [INT _ size]], [ PipalSisyph.mode.extractProcProp, $WireIconsExtractExtractor]]]; CDCells.SetSimplificationTreshhold[obj, 10.0]; }; Extractor: PW.GeneratorProc = { int: INT _ TerminalIO.RequestInt["Index of the extracted wire? "]; int2: INT _ TerminalIO.RequestInt["Size of the structured wire? "]; IF int<0 OR int2<1 OR int>=int2 THEN {TerminalIO.PutF["*** Incorrect parameters.\n"]; RETURN}; ob _ MakeExtractor[design, NAT [int], NAT [int2]].obj; }; ExtractExtractor: PipalSinix.ExtractProc = { cx: PipalSisyph.Context = NARROW [userData]; refNat: REF INT _ NARROW [CDProperties.GetObjectProp[obj, $ExtractorIndex]]; refNat2: REF INT _ NARROW [CDProperties.GetObjectProp[obj, $ExtractorSize]]; index: NAT _ NAT [refNat^]; size: NAT _ NAT [refNat2^]; result _ MakeExtractor[PipalSisyph.GetDesign[cx], index, size].wire; }; <> MakeRangeExtractor: PUBLIC PROC [design: CD.Design, index, subSize, size: NAT] RETURNS [wires: Wires, obj: CD.Object] = { il: CD.InstanceList _ NIL; <> structWire: Wire _ CoreOps.CreateWires[size: size]; subWire: Wire _ CoreOps.CreateWires[size: subSize]; wires _ LIST [subWire, structWire]; <> 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; <> il _ PutPin[structWire, [19* <> il _ AddRect[[ il _ PutPin[subWire, [ <> il _ AddRect[[5* il _ AddRect[[5* il _ AddRect[[ il _ AddRect[[ <> il _ AddText[IO.PutFR["%g/%g", IO.int[index], IO.int[subSize]], [13* il _ AddText[IO.PutR1[IO.int[size]], [13* obj _ PW.CreateCell[instances: il, ir: [0, 0, 19*[$ExtractorSubSize, NEW [INT _ subSize]], [$ExtractorSize, NEW [INT _ size]], [PipalSisyph.mode.extractProcProp, $WireIconsExtractRangeExtractor]]]; CDCells.SetSimplificationTreshhold[obj, 10.0]; }; RangeExtractor: PW.GeneratorProc = { int: INT _ TerminalIO.RequestInt["Index of the extracted wire? "]; int2: INT _ TerminalIO.RequestInt["Size of the extracted wire? "]; int3: INT _ TerminalIO.RequestInt["Size of the structured wire? "]; IF int<0 OR int2<1 OR int3<1 OR int>=int3 OR int+int2>int3 THEN {TerminalIO.PutF["*** Incorrect parameters.\n"]; RETURN}; ob _ MakeRangeExtractor[design, NAT [int], NAT [int2], NAT [int3]].obj; }; ExtractRangeExtractor: PipalSinix.ExtractProc = { cx: PipalSisyph.Context = NARROW [userData]; 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[PipalSisyph.GetDesign[cx], index, subSize, size].wires; }; <> ParametrizedBus: PW.GeneratorProc = { il: CD.InstanceList _ NIL; slash: CD.Object _ CDDirectory.Fetch[design, "::SlashForBusIcon"].object; sizeRope: ROPE _ TerminalIO.RequestRope["Size of the parametrized bus? "]; IF slash=NIL THEN { slash _ MakeSlash[design]; [] _ CDDirectory.Include[design, slash, "::SlashForBusIcon"]; }; il _ CONS [CDInstances.NewInst[slash, [[ il _ AddRect[[9* <> il _ AddText[sizeRope, [6* ob _ PW.CreateCell[instances: il, ir: [0, 0, 9*$WireIconsExtractParametrizedBus]]]; CDCells.SetSimplificationTreshhold[ob, 10.0]; }; ExtractParametrizedBus: PipalSinix.ExtractProc = { cx: PipalSisyph.Context _ PipalSisyph.EvaluateParameters[userData, obj, properties]; design: CD.Design _ PipalSisyph.GetDesign[cx]; sizeRope: ROPE _ NARROW [CDProperties.GetObjectProp[obj, $BusSize]]; size: NAT _ EvalNat[cx, sizeRope]; wire: Wire; IF size<1 THEN ERROR; wire _ CoreOps.CreateWires[size: size]; <> [] _ PutPin[wire, [9* <> FOR i: NAT IN [0 .. size) DO wire[i] _ CoreOps.CreateWire[] ENDLOOP; result _ wire; }; <> ParametrizedExtractor: PW.GeneratorProc = { il: CD.InstanceList _ NIL; indexRope: ROPE _ TerminalIO.RequestRope["Parametrized index of the extracted wire? "]; sizeRope: ROPE _ TerminalIO.RequestRope["Size of the parametrized bus? "]; <> il _ AddRect[[9* <> il _ AddRect[[ <> il _ AddRect[[3* il _ AddRect[[3* il _ AddRect[[ il _ AddRect[[ <> il _ AddText[indexRope, [9* il _ AddText[sizeRope, [9* ob _ PW.CreateCell[instances: il, ir: [0, 0, 9*[PipalSisyph.mode.extractProcProp, $WireIconsExtractParametrizedExtractor]]]; CDCells.SetSimplificationTreshhold[ob, 10.0]; }; ExtractParametrizedExtractor: PipalSinix.ExtractProc = { cx: PipalSisyph.Context _ PipalSisyph.EvaluateParameters[userData, obj, properties]; design: CD.Design _ PipalSisyph.GetDesign[cx]; indexRope: ROPE _ NARROW [CDProperties.GetObjectProp[obj, $ExtractorIndex]]; sizeRope: ROPE _ NARROW [CDProperties.GetObjectProp[obj, $ExtractorSize]]; index: NAT _ EvalNat[cx, indexRope]; size: NAT _ EvalNat[cx, sizeRope]; wire: Wire; IF index<0 OR size<1 OR index>=size THEN ERROR; wire _ CoreOps.CreateWires[size: size]; FOR i: NAT IN [0 .. size) DO wire[i] _ CoreOps.CreateWire[] ENDLOOP; <> [] _ PutPin[wire, [9* <> [] _ PutPin[wire[index], [ result _ wire; }; <> ParametrizedRangeExtractor: PW.GeneratorProc = { il: CD.InstanceList _ NIL; indexRope: ROPE _ TerminalIO.RequestRope["Parametrized index of the extracted wire? "]; subSizeRope: ROPE _ TerminalIO.RequestRope["Size of the parametrized sub wire? "]; sizeRope: ROPE _ TerminalIO.RequestRope["Size of the parametrized bus? "]; <> il _ AddRect[[19* <> il _ AddRect[[ il _ AddRect[[ <> il _ AddRect[[5* il _ AddRect[[5* il _ AddRect[[ il _ AddRect[[ <> il _ AddText[IO.PutFR["%g/%g", IO.rope[indexRope], IO.rope[subSizeRope]], [13* il _ AddText[sizeRope, [13* ob _ PW.CreateCell[instances: il, ir: [0, 0, 19*subSizeRope], [$ExtractorSize, sizeRope], [PipalSisyph.mode.extractProcProp, $WireIconsExtractParametrizedRangeExtractor]]]; CDCells.SetSimplificationTreshhold[ob, 10.0]; }; ExtractParametrizedRangeExtractor: PipalSinix.ExtractProc = { cx: PipalSisyph.Context _ PipalSisyph.EvaluateParameters[userData, obj, properties]; design: CD.Design _ PipalSisyph.GetDesign[cx]; indexRope: ROPE _ NARROW [CDProperties.GetObjectProp[obj, $ExtractorIndex]]; subSizeRope: ROPE _ NARROW [CDProperties.GetObjectProp[obj, $ExtractorSubSize]]; sizeRope: ROPE _ NARROW [CDProperties.GetObjectProp[obj, $ExtractorSize]]; index: NAT _ EvalNat[cx, indexRope]; subSize: NAT _ EvalNat[cx, subSizeRope]; size: NAT _ EvalNat[cx, sizeRope]; wire, subWire: Wire; wires: Wires; IF index<0 OR subSize<1 OR size<1 OR index>=size OR index+subSize>size THEN RETURN; wire _ CoreOps.CreateWires[size: size]; subWire _ CoreOps.CreateWires[size: subSize]; FOR i: NAT IN [0 .. size) DO wire[i] _ CoreOps.CreateWire[] ENDLOOP; FOR i: NAT IN [0 .. subSize) DO subWire[i] _ wire[i+index] ENDLOOP; <> [] _ PutPin[wire, [19* <> [] _ PutPin[subWire, [ wires _ LIST [subWire, wire]; result _ wires; }; <> SequencingSlash: PW.GeneratorProc = { il: CD.InstanceList _ NIL; il _ AddRect[[5* FOR i: INT IN [0 .. 2* ob _ PW.CreateCell[instances: il, name: "/", props: LIST [[PipalSisyph.mode.extractProcProp, $WireIconsExtractSequencingSlash]]]; CDCells.SetSimplificationTreshhold[ob, 10.0]; }; ExtractSequencingSlash: PipalSinix.ExtractProc = { cx: PipalSisyph.Context _ PipalSisyph.EvaluateParameters[userData, obj, properties]; design: CD.Design _ PipalSisyph.GetDesign[cx]; wire: Wire _ CoreOps.CreateWire[props: CoreProperties.Props[[$Sequence, $Sequence]]]; <> [] _ PutPin[wire, [5* result _ wire; }; <> <> <> <