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:
BOOL ←
FALSE]
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.STREAM ← FS.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:
BOOL ←
TRUE] ={
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.STREAM ← FS.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:
BOOL ←
TRUE] = {
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.