-- File: IPTopImpl.mesa
-- Last Edited by: CSChow, February 1, 1985 8:47:46 am PST
Preas, August 2, 1986 6:27:25 pm PDT
--Documentation will come later after consolidating the design --
DIRECTORY
Rope USING [ROPE, Equal, Substr],
IO,
Convert USING [IntFromRope],
FS USING [StreamOpen],
Imager USING [Context],
SymTab,
ExprRead USING[ReadFile, FetchRope, FetchBool],
Misc USING [Rect],
IP,
IPCTG,
IPConstants,
IPParams,
IPCTGMaker,
IPCoVerifier,
IPCoTab,
RefStack USING [Ref, Create, Reset, Empty, Push, Pop1, Items, EachItemAction, Size],
IPChipRose,
IPNetTab,
IPTypeTab,
IPPortTab,
IPToolBox,
IPTop;
IPTopImpl: CEDAR PROGRAM
IMPORTS Rope, IO, Convert, FS, ExprRead, RefStack, IP, IPParams, IPCoTab, IPCTG, IPCTGMaker, IPCoVerifier, IPChipRose, IPPortTab, IPNetTab, IPTypeTab, IPToolBox
EXPORTS IPTop = BEGIN OPEN IPTop;
CyclicConstraint: PUBLIC ERROR[negCh, posCh: IPCTG.Channel] = CODE;
ComponentsOverlapped: PUBLIC ERROR[overlaps: LIST OF Misc.Rect] = CODE;
Create: PUBLIC PROC[chipRose: IPChipRose.Ref] RETURNS[Ref] = {
types: IPTypeTab.Ref ← IPTypeTab.Create[chipRose];
nets: IPNetTab.Ref ← IPNetTab.Create[chipRose];
ports: IPPortTab.Ref ← IPPortTab.Create[chipRose, nets];
coTab: IPCoTab.Ref ← IPCoTab.Create[chipRose, types, nets];
ctg: IPCTG.Ref ← IPCTG.Create[];
RETURN [NEW[Rep ← [coTab, ports, ctg, types, nets, RefStack.Create[], RefStack.Create[], RefStack.Create[], RefStack.Create[]]]]
}; --Create --
Create1: PUBLIC PROC[defaultDir, descFile: Rope.ROPE] RETURNS [Ref] ={
tab: SymTab.Ref ← ExprRead.ReadFile[IPToolBox.ConstructFileName[defaultDir, descFile, "desc"]];
systemName: Rope.ROPE ← ExprRead.FetchRope[tab, "ObjectName", TRUE].val;
roseFile: Rope.ROPE ← ExprRead.FetchRope[tab, "ConnectivityFile", TRUE].val;
chipFile: Rope.ROPE ← ExprRead.FetchRope[tab, "LibraryFile", TRUE].val;
typFile: Rope.ROPE ← ExprRead.FetchRope[tab, "IPTypeFile", TRUE].val;
initFile: Rope.ROPE ← ExprRead.FetchRope[tab, "IPInitFile", TRUE].val;
readCDFirst: BOOL ← ExprRead.FetchBool[tab, "ReadCDFirst", TRUE].val;
chipRose: IPChipRose.Ref ← IPChipRose.CreateFrom[
IPToolBox.ConstructFileName[defaultDir, roseFile, "sch"],
IPToolBox.ConstructFileName[defaultDir, chipFile, "dale"],
IPToolBox.ConstructFileName[defaultDir, typFile, "typ"],
IPToolBox.ConstructFileName[defaultDir, initFile, "init"],
readCDFirst];
RETURN[Create[chipRose]];
}; --Create1
DestroySelf: PUBLIC PROC [top: Ref] ={
IPCTG.DestroySelf[top.ctg];
IPCoTab.DestroySelf[top.coTab];
}; --DestroySelf
ReDefineChs: PUBLIC PROC[top: Ref, chWidth: NAT ← IPParams.ChDefaultWidth, yPrimary, maxChWidth: BOOLFALSE] RETURNS [Ref] ={
cI: IPCoVerifier.Ref ← IPCoVerifier.Create[yPrimary];
ctgMaker: IPCTGMaker.Ref ← IPCTGMaker.Create[];
ctg: IPCTG.Ref;
overlaps: LIST OF Misc.Rect;
p: IPCoTab.EachComponentAction ={cI.InsertComponent[co]}; --p --
IPCTG.DestroySelf[top.ctg]; -- Release top.ctg--
IPCoTab.Components[top.coTab, p];
IF (overlaps ← cI.Verify) = NIL
THEN ctg ← ctgMaker.ConstructCTG[cI, chWidth, yPrimary, maxChWidth].ctg
ELSE ERROR ComponentsOverlapped[overlaps];
cI.Destroy;
ctgMaker.Destroy;
top.ctg ← ctg;
top.undoStack.Reset; --undoStack is no longer valid--
top.redoStack.Reset; --redoStack is no longer valid--
top.horOldChs.Reset; --horOldChs is no longer valid--
top.verOldChs.Reset; --verOldChs is no longer valid--
IF top.initialized THEN InitTop[top];
RETURN [top];
}; --ReDefineChs--
ClearChannels: PUBLIC PROC[top: Ref] ={
IPCTG.DestroySelf[top.ctg];
top.ctg ← IPCTG.Create[];
top.undoStack.Reset; --undoStack is no longer valid--
top.redoStack.Reset; --redoStack is no longer valid--
top.horOldChs.Reset; --horOldChs is no longer valid--
top.verOldChs.Reset; --verOldChs is no longer valid--
}; --ClearChannels
DescribeSelf: PUBLIC PROC[top: Ref, file: Rope.ROPE] = {
stream: IO.STREAMFS.StreamOpen[file, $create];
stream.PutF["\nBeginTop"];
stream.PutF["\n%g\n", IO.bool[top.initialized]];
top.ctg.DescribeSelf[stream]; --(1) Print ctg
top.nets.DescribeSelf[stream]; --(2) Print nets
top.types.DescribeSelf[stream]; --(3) Print types
top.ports.DescribeSelf[stream]; --(4) Print ports
top.coTab.DescribeSelf[stream]; --(5) Print coTab
IF top.southMost = NIL THEN NULL ELSE
stream.PutF["\n%g %g %g %g\n --Bounding Channels--", IO.rope[IPCTG.GetName[top.southMost]], IO.rope[IPCTG.GetName[top.eastMost]], IO.rope[IPCTG.GetName[top.northMost]], IO.rope[IPCTG.GetName[top.westMost]]];
stream.PutF["\nEndTop\n"];
stream.Close[];
}; --DescribeSelf--
PaintSelf: PUBLIC PROC[top: Ref, context: Imager.Context, xOffset, yOffset: REAL ← 0.0, scaleFactor: REAL ← 1.0, compStipple: CARDINAL ← IPConstants.White, showChNames, showCompNames, showPinNames: BOOLTRUE] ={
top.coTab.PaintSelf[context, xOffset, yOffset, scaleFactor, compStipple, showCompNames, showPinNames];
top.ctg.PaintSelf[context, xOffset, yOffset, scaleFactor, showChNames];
}; --PaintSelf--
ReconstructSelf: PUBLIC PROC[file: Rope.ROPE] RETURNS [top: Ref] = {
stream: IO.STREAMFS.StreamOpen[file];
id: Rope.ROPE ← stream.GetID;
init: BOOL;
undoStack: RefStack.Ref ← RefStack.Create[];
redoStack: RefStack.Ref ← RefStack.Create[];
horOldChs: RefStack.Ref ← RefStack.Create[];
verOldChs: RefStack.Ref ← RefStack.Create[];
ctg: IPCTG.Ref;
nets: IPNetTab.Ref;
ports: IPPortTab.Ref;
types: IPTypeTab.Ref;
coTab: IPCoTab.Ref;
southMost, eastMost, northMost, westMost: IPCTG.Channel ← NIL;
IF NOT Rope.Equal[id, "BeginTop"] THEN ERROR IP.Error[callingError, "Bad Input"];
init ← stream.GetBool;
IF Rope.Equal[stream.GetID, "BeginCTG"]
THEN ctg ← IPCTG.ReconstructSelf[stream] --(1) Get ctg
ELSE ERROR IP.Error[callingError, "Bad Input"];
IF Rope.Equal[stream.GetID, "BeginNetTab"]
THEN nets ← IPNetTab.ReconstructSelf[stream] -- (2) Get nets
ELSE ERROR IP.Error[callingError, "Bad Input"];
IF Rope.Equal[stream.GetID, "BeginTypeTab"]
THEN types ← IPTypeTab.ReconstructSelf[stream] -- (3) Get types
ELSE ERROR IP.Error[callingError, "Bad Input"];
IF Rope.Equal[stream.GetID, "BeginPortTab"]
THEN ports ← IPPortTab.ReconstructSelf[stream, nets] -- (4) Get ports
ELSE ERROR IP.Error[callingError, "Bad Input"];
IF Rope.Equal[stream.GetID, "BeginCoTab"]
THEN coTab ← IPCoTab.ReconstructSelf[stream, types, nets, ctg] -- (5) Get coTab
ELSE ERROR IP.Error[callingError, "Bad Input"];
id ← stream.GetID;
IF Rope.Equal[id, "EndTop"] THEN NULL ELSE{
southMost ← IPCTG.GetChannel[ctg, id];
eastMost ← IPCTG.GetChannel[ctg, stream.GetID];
northMost ← IPCTG.GetChannel[ctg, stream.GetID];
westMost ← IPCTG.GetChannel[ctg, stream.GetID];
IF ~ Rope.Equal[stream.GetID, "EndTop"] THEN ERROR IP.Error[callingError, "Bad Input"];
};
top ← NEW[Rep ← [coTab, ports, ctg, types, nets, undoStack, redoStack, horOldChs, verOldChs, init, southMost, eastMost, northMost, westMost]];
IF init THEN InitTop[top];
}; -- ReconstructSelf--
CheckSelf: PUBLIC PROC[top: Ref] ={
oldChsType: IPCTG.ChType ← hor; --First Check horizontal channel--
prevChCount: NAT ← 2; --All old hor/ver channels must have count greater than this--
eachOldCh: RefStack.EachItemAction = {
ch: IPCTG.Channel ← NARROW[item];
currentChCount: NAT;
IF ch.type # oldChsType THEN ERROR;
IF top.ctg.GetChannel[ch.name, FALSE] # NIL THEN ERROR;
currentChCount ← Convert.IntFromRope[Rope.Substr[IPCTG.GetName[ch], 1]];
IF prevChCount < currentChCount THEN NULL ELSE ERROR;
prevChCount ← currentChCount;
}; --eachOldCh--
top.horOldChs.Items[eachOldCh];
oldChsType ← ver; prevChCount ← 2;
top.verOldChs.Items[eachOldCh];
IF top.undoStack.Size[] # top.redoStack.Size[] THEN ERROR; --They should match--
BEGIN
IF top.ctg.Size[hor] = 0 OR top.ctg.Size[ver] = 0 THEN {
IF top.ctg.Size[hor] # top.ctg.Size[ver] THEN ERROR ELSE RETURN};
top.ctg.CheckSelf;
top.coTab.CheckSelf;
END;
BEGIN
IF top.southMost = NIL OR top.eastMost = NIL OR top.northMost = NIL OR top.westMost = NIL THEN {
IF top.southMost # NIL OR top.eastMost # NIL OR top.northMost # NIL OR top.westMost # NIL THEN ERROR;}; --IF one of them is NIL THEN all must be NIL--
END;
};--CheckSelf--
ConstraintChannels: PUBLIC PROC[top: Ref, negCh, posCh: IPCTG.Channel, wt: INT] = {
IF ~ top.initialized THEN InitTop[top];
top.ctg.SetExternalConstraint[negCh, posCh, wt ! IPCTG.CyclicConstraints => GOTO reSignal];
top.ctg.ConstrainChannels0[negCh, posCh, wt];
EXITS
reSignal => {ERROR CyclicConstraint[negCh, posCh]}}; --ConstraintChannels--
ClearConstraints: PUBLIC PROC[top: Ref, negCh: IPCTG.Channel, posCh: IPCTG.Channel ← NIL] ={
top.ctg.ClearExternalConstraints[negCh, posCh];
top.initialized ← FALSE;
}; --ClearConstraints--
ClearAllConstraints: PUBLIC PROC[top: Ref] ={
top.ctg.ClearAllExternalConstraints;
top.initialized ← FALSE;
}; --ClearAllConstraints--
NoTopology: PUBLIC PROC[top: Ref] RETURNS [BOOL] ={
RETURN [top.ctg.Size[hor] = 0 OR top.ctg.Size[ver] = 0]
};--NoTopology
Geometrize: PUBLIC PROC [top: Ref, xPosition: INT ← IPParams.ChDefaultPositionX, yPosition: INT ← IPParams.ChDefaultPositionY, horPosSense, verPosSense: BOOLTRUE] = {
chs: IPCTG.Ref ← top.ctg;
p: IPCoTab.EachComponentAction ={ quit ← FALSE; IPCoTab.PositionComponent[co]};
IF top.ctg.Size[hor] = 0 OR top.ctg.Size[ver] = 0 THEN RETURN;
IF ~ top.initialized THEN InitTop[top];
chs.ComputeGeometry[xPosition, yPosition, horPosSense, verPosSense]; --Compute the geometrical information of the channels --
top.coTab.Components[p]; --compute the position of the boxes wrt. the channels --
InitTop[top]
}; -- Geometrize--
XDim: PUBLIC PROC[top: Ref] RETURNS [INT] ={
IF ~ top.initialized THEN InitTop[top];
IF top.eastMost = NIL OR top.westMost = NIL THEN
[top.southMost, top.eastMost, top.northMost, top.westMost] ← top.ctg.GetBoundingChannels;
RETURN [IPCTG.GetCoord[top.eastMost] - IPCTG.GetCoord[top.westMost]]
};--XDim--
YDim: PUBLIC PROC[top: Ref] RETURNS [INT] ={
IF ~ top.initialized THEN InitTop[top];
IF top.southMost = NIL OR top.northMost = NIL THEN
[top.southMost, top.eastMost, top.northMost, top.westMost] ← top.ctg.GetBoundingChannels;
RETURN [IPCTG.GetCoord[top.northMost] - IPCTG.GetCoord[top.southMost]]};--YDim--
Area: PUBLIC PROC[top: Ref] RETURNS [INT] ={RETURN [XDim[top] * YDim[top]]};--Area--
InitTop: PROC[top: Ref] ={
chs: IPCTG.Ref ← top.ctg;
p: IPCoTab.EachComponentAction = {IPCoTab.ConstrainChannels[co, chs]};
top.ctg.RefreshAllConstraints[]; -- Clears all previous constraints
top.coTab.Components[p]; --Add the constraints between channels resulting from the components --
chs.AddTopologicalConstraints; -- Add the constraints resulting from the topology of the channel intersection --
chs.AddExternalConstraints; -- Add any user specified constriants --
top.initialized ← TRUE;
}; --InitTop--
CreateChannel: PUBLIC PROC[top: Ref, type: IPCTG.ChType, width: NAT ← IPParams.ChDefaultWidth, coord: INT ← 0] RETURNS[ch: IPCTG.Channel] ={
top.initialized ← FALSE;
SELECT type FROM
hor => IF ~ top.horOldChs.Empty THEN {
ch ← NARROW[top.horOldChs.Pop1]; IPCTG.SetWidth[ch, width];
IPCTG.SetCoord[ch, coord]; top.ctg.ReActivateChannel[ch];
RETURN [ch]};
ver => IF ~ top.verOldChs.Empty THEN {
ch ← NARROW[top.verOldChs.Pop1]; IPCTG.SetWidth[ch, width];
IPCTG.SetCoord[ch, coord]; top.ctg.ReActivateChannel[ch];
RETURN [ch]};
ENDCASE => ERROR;
RETURN [top.ctg.CreateChannel[type, width, coord]]
};--CreateChannel--
DestroyChannel: PUBLIC PROC[top: Ref, ch: IPCTG.Channel] ={
DeActivateChannel[top, ch];
SELECT IPCTG.GetType[ch] FROM
hor => top.horOldChs.Push[ch];
ver => top.verOldChs.Push[ch];
ENDCASE => ERROR;
}; --DestroyChannel--
DeActivateChannel: PUBLIC PROC[top: Ref, ch: IPCTG.Channel] = {
top.initialized ← FALSE;
top.ctg.DeActivateChannel[ch]}; --DeActivateChannel--
ReActivateChannel: PUBLIC PROC[top: Ref, ch: IPCTG.Channel] ={
top.initialized ← FALSE;
top.ctg.ReActivateChannel[ch]
}; --ReActivateChannel--
END.