SinixRose.mesa
Copyright © 1985 by Xerox Corporation. All rights reversed.
Created by Bertrand Serlet August 15, 1985 2:09:54 pm PDT
Bertrand Serlet October 21, 1985 10:52:31 am PDT
DIRECTORY
BasicTime,
CD, CDBasics, CDCells, CDDirectory, CDMenus, CDOps, CDOrient, CDProperties, CDRects, CDSequencer, CDViewHighlight, CDViewer,
Core, CoreClasses, CoreProperties,
IO,
Rope,
RoseControl,
Sinix, SinixFlatten,
TerminalIO,
ViewerClasses;
SinixRose: CEDAR PROGRAM
IMPORTS BasicTime, CDBasics, CDCells, CDDirectory, CDMenus, CDOps, CDOrient, CDProperties, CDRects, CDSequencer, CDViewHighlight, CDViewer, CoreClasses, CoreProperties, IO, RoseControl, Rope, Sinix, SinixFlatten, TerminalIO =
BEGIN
Utilities
ROPE: TYPE = Rope.ROPE;
debug: BOOLTRUE;
SimulationHandle Property
Only 1 simulation per design, because the simulation handle is stored on a property on the cd design.
simulationHandleProp: ATOM ← $SinixSimulationHandle;
SimulationHandle: TYPE = REF SimulationHandleRec;
SimulationHandleRec: TYPE = RECORD [
simulation: RoseControl.Simulation,
instance: CD.Instance, -- instance being simulated
flatten: Core.CellType -- flattened instance
];
Commands from the menu
Extract: PROC [command: CDSequencer.Command] = {
Extracts all selected instances
time: BasicTime.GMT ← BasicTime.Now[]; -- Start the stop watch
count: INT ← 0;
TerminalIO.WriteRope["Extraction started ...\n"];
FOR list: CD.InstanceList ← CDOps.InstList[command.design], list.rest WHILE list#NIL DO
obj: CD.Object ← list.first.ob;
IF list.first.selected THEN {
count ← count+1;
[] ← ExtractObj[obj];
};
ENDLOOP;
TerminalIO.WriteF[NIL, IO.int[count], IO.rope[" objects extracted in "], IO.int[BasicTime.Period[time, BasicTime.Now[]]], IO.rope[" seconds\n"]];
};
DescribeWire: PROC [command: CDSequencer.Command] = {
Finds a (the first one) wire belonging to the set of extracted cells at the click position, highlights it, and prints all the known information about it (properties).
wire: Core.Wire ← NIL; position: CD.Position; orientation: CD.Orientation;
[wire, position, orientation] ← FindWireAtPos[command.design, command.pos];
IF wire=NIL THEN {TerminalIO.WriteRope[Rope.Cat["No Core.Wire in the extracted cells at this location\n"]]; RETURN};
TerminalIO.WriteRope[Rope.Cat["At this location, Core.Wire name: ", wire.name, "\n"]];
FOR viewers: LIST OF ViewerClasses.Viewer ← CDViewer.ViewersOf[command.design], viewers.rest WHILE viewers#NIL DO
HighLightWire[viewers.first, wire, position, orientation];
ENDLOOP;
};
InitializeSimulation: PROC [command: CDSequencer.Command] = {
multiple: BOOL;
rootCellType: Core.CellType ← NIL;
handle: SimulationHandle ← NEW [SimulationHandleRec];
[handle.instance, multiple] ← CDOps.SelectedInstance[command.design];
IF multiple THEN {TerminalIO.WriteRope["Only 1 selection\n"]; RETURN};
rootCellType ← ExtractObj[handle.instance.ob];
CDProperties.PutPropOnDesign[command.design, simulationHandleProp, handle];
TerminalIO.WriteRope["Flattening ...\n"];
handle.flatten ← SinixFlatten.Flatten[rootCellType, SinixFlatten.NonTransistorsExpand].flat;
TerminalIO.WriteRope["Flattening completed\n"];
TerminalIO.WriteRope["Initializing simulation ...\n"];
handle.simulation ← RoseControl.Instantiate[rootCellType];
RoseControl.Initialize[handle.simulation];
TerminalIO.WriteRope["Initialization of simulation completed\n"];
};
Settle: PROC [command: CDSequencer.Command] = {
handle: SimulationHandle ← NARROW [CDProperties.GetPropFromDesign[command.design, simulationHandleProp]];
TerminalIO.WriteRope["Stepping simulation ...\n"];
RoseControl.Settle[handle.simulation];
TerminalIO.WriteRope["Stepping simulation done!\n"];
};
FetchValue: PROC [command: CDSequencer.Command] = {
handle: SimulationHandle ← NARROW [CDProperties.GetPropFromDesign[command.design, simulationHandleProp]];
wire: Core.Wire ← NIL; position: CD.Position; orientation: CD.Orientation;
[wire, position, orientation] ← FindWireAtPos[command.design, command.pos];
IF wire=NIL THEN {TerminalIO.WriteRope["No Core.Wire in the extracted cells at this location\n"]; RETURN};
TerminalIO.WriteRope[Rope.Cat["At this location, Core.Wire name: ", wire.name, "\n"]];
TerminalIO.WriteRope[Rope.Cat["Value of wire ", wire.name, " is: ", RoseControl.FetchValue[handle.simulation, wire]]];
};
ForceValue: PROC [command: CDSequencer.Command] = {
handle: SimulationHandle ← NARROW [CDProperties.GetPropFromDesign[command.design, simulationHandleProp]];
wire: Core.Wire ← NIL; position: CD.Position; orientation: CD.Orientation;
[wire, position, orientation] ← FindWireAtPos[command.design, command.pos];
IF wire=NIL THEN {TerminalIO.WriteRope[Rope.Cat["No Core.Wire in the extracted cells at this location\n"]]; RETURN};
TerminalIO.WriteRope[Rope.Cat["At this location, Core.Wire name: ", wire.name, "\n"]];
RoseControl.ForceValue[handle.simulation, wire, TerminalIO.RequestRope[Rope.Cat["New Value of wire ", wire.name, " : "]]];
};
Auxiliary functions for the commands
ExtractObj: PROC [obj: CD.Object] RETURNS [extractedCellType: Core.CellType] = {
ok: BOOL;
[extractedCellType, ok] ← Sinix.ExtractObj[obj];
TerminalIO.WriteF[NIL, IO.rope["Extraction of "], IO.rope[CDDirectory.Name[obj]], IO.rope[IF ok THEN " **** errors\n" ELSE " ok\n"]];
};
FindWireAtPos: PROC [cdDesign: CD.Design, pos: CD.Position] RETURNS [wire: Core.Wire ← NIL, position: CD.Position, orientation: CD.Orientation] = {
wire=NIL means wire not found. position and orientation are relative to the design.
FOR list: CD.InstanceList ← CDOps.InstList[cdDesign], list.rest WHILE list#NIL DO
cdInstance: CD.Instance ← list.first;
obj: CD.Object ← cdInstance.ob;
cellType: Core.CellType ← NARROW [CDProperties.GetPropFromObject[obj, Sinix.extractedCoreProp]];
IF cellType=NIL THEN LOOP;
[wire, position, orientation] ← FindWireAtPosInCellType[cellType, CDOrient.DeMapPoint[pos, obj.size, cdInstance.orientation, cdInstance.location]];
IF wire#NIL THEN RETURN [
wire,
CDOrient.MapPoint[position, cdInstance.ob.size, cdInstance.orientation, cdInstance.location],
CDOrient.ComposeOrient[orientation, cdInstance.orientation]
];
ENDLOOP;
};
FindWireAtPosInCellType: PROC [cellType: Core.CellType, pos: CD.Position] RETURNS [wire: Core.Wire ← NIL, position: CD.Position ← [0, 0], orientation: CD.Orientation ← 0] = {
wire=NIL means wire not found. position and orientation are for the [0, 0] of the cellType containing wire
elements: Core.WireSequence ← cellType.public.elements;
FOR i: NAT IN [0 .. elements.size) DO
wire ← elements[i];
IF PosInInstanceList[pos, Sinix.GetWireGeometryPropFromWire[wire]] THEN RETURN;
ENDLOOP;
SELECT cellType.class FROM
CoreClasses.recordCellClass   => {
data: CoreClasses.RecordCellType ← NARROW [cellType.data];
internalElements: Core.WireSequence ← data.internal.elements;
FOR i: NAT IN [0 .. internalElements.size) DO
wire ← internalElements[i];
IF PosInInstanceList[pos, Sinix.GetWireGeometryPropFromWire[wire]] THEN RETURN;
ENDLOOP;
FOR instances: CoreClasses.CellInstanceList ← data.instances, instances.rest WHILE instances#NIL DO
cdInstance: CD.Instance ← NARROW [CoreProperties.GetCellInstanceProp[instances.first, Sinix.instanceProp]];
[wire, position, orientation] ← FindWireAtPosInCellType[instances.first.type, CDOrient.DeMapPoint[pos, cdInstance.ob.size, cdInstance.orientation, cdInstance.location]];
IF wire#NIL THEN RETURN [
wire,
CDOrient.MapPoint[position, cdInstance.ob.size, cdInstance.orientation, cdInstance.location],
CDOrient.ComposeOrient[orientation, cdInstance.orientation]
];
ENDLOOP;
};
CoreClasses.transistorCellClass => {};
ENDCASE        => ERROR;
wire ← NIL;
};
HighLightWire: PROC [viewer: ViewerClasses.Viewer, wire: Core.Wire, position: CD.Position, orientation: CD.Orientation, removeOthers: BOOLTRUE] = {
instances: LIST OF CD.Instance ← HighLightListInst[NARROW[CoreProperties.GetProp[wire.properties, Sinix.wireGeometryProp]]];
cell: CD.Object ← CDCells.CreateEmptyCell[];
cellPtr: CD.CellPtr ← NARROW [cell.specificRef];
instance: CD.Instance ← NEW [CD.InstanceRep ← [ob: cell, location: position, orientation: orientation]];
cellPtr.contents ← instances;
CDViewHighlight.ShowInstance[viewer, instance, removeOthers];
};
HighLightListInst: PROC [instances: LIST OF CD.Instance] RETURNS [hlist: LIST OF CD.Instance ← NIL] = {
WHILE instances#NIL DO
hlist ← CONS[HighLightInst[instances.first], hlist]; instances ← instances.rest;
ENDLOOP;
};
HighLightInst: PROC [inst: CD.Instance] RETURNS [hinst: CD.Instance] = {
hinst ← NEW [CD.InstanceRep ← [
ob: IF inst.ob.class.objectType=$PinOb0 THEN CDRects.CreateRect[inst.ob.size, CD.highLightShade] ELSE HighLightOb[inst.ob],
location: inst.location, orientation: inst.orientation]];
};
HighLightOb: PROC [ob: CD.Object] RETURNS [hob: CD.Object] = {
SELECT ob.class.objectType FROM
$Rect  => hob ← CDRects.CreateRect[ob.size, CD.highLightShade];
$Cell  => {
cellPtr, hcellPtr: CD.CellPtr;
hob ← CDCells.CreateEmptyCell[];
cellPtr ← NARROW [ob.specificRef];
hcellPtr ← NARROW [hob.specificRef];
hcellPtr.contents ← HighLightListInst[cellPtr.contents];
hob.size ← ob.size;
};
ENDCASE => {
hob ← CDDirectory.ExpandHard[ob, NIL, NIL];
IF hob=NIL THEN RETURN[CDRects.CreateRect[ob.size, CD.combined]];
hob ← HighLightOb[hob];
};
};
PosInInstanceList: PROC [pos: CD.Position, instances: LIST OF CD.Instance] RETURNS [yes: BOOLFALSE] = {
WHILE instances#NIL DO
IF PosInInstance[pos, instances.first] THEN RETURN [TRUE];
instances ← instances.rest;
ENDLOOP;
};
PosInInstance: PROC [pos: CD.Position, instance: CD.Instance] RETURNS [yes: BOOLFALSE] = {
yes ← PosInObject[CDOrient.DeMapPoint[pos, instance.ob.size, instance.orientation, instance.location], instance.ob];
};
PosInObject: PROC [pos: CD.Position, ob: CD.Object] RETURNS [yes: BOOLFALSE] = {
SELECT ob.class.objectType FROM
$Rect  => yes ← CDBasics.InsidePos[pos, CDBasics.RectAt[[0, 0], ob.size]];
$Cell  => yes ← PosInInstanceList[pos, NARROW [ob.specificRef, CD.CellPtr].contents];
ENDCASE => {
ob ← CDDirectory.ExpandHard[ob, NIL, NIL];
IF ob#NIL THEN yes ← PosInObject[pos, ob];
};
};
Initialization
BEGIN
[] ← CDProperties.RegisterProperty[simulationHandleProp, $Sinix];
CDSequencer.ImplementCommand[$Extract, Extract];
CDMenus.CreateEntry[$RectProgramMenu, "Extract selected", $Extract];
CDSequencer.ImplementCommand[$DescribeWire, DescribeWire];
CDMenus.CreateEntry[$RectProgramMenu, "DescribeWire at pos", $DescribeWire];
CDSequencer.ImplementCommand[$InitializeSimulation, InitializeSimulation];
CDMenus.CreateEntry[$RectProgramMenu, "Initializes simulation", $InitializeSimulation];
CDSequencer.ImplementCommand[$Settle, Settle];
CDMenus.CreateEntry[$RectProgramMenu, "Steps simulation", $Settle];
CDSequencer.ImplementCommand[$FetchValue, FetchValue];
CDMenus.CreateEntry[$RectProgramMenu, "Fetch the value of a wire", $FetchValue];
CDSequencer.ImplementCommand[$ForceValue, ForceValue];
CDMenus.CreateEntry[$RectProgramMenu, "Stores the value of a wire", $ForceValue];
END;
END.