LichenDataImpl2A.Mesa
Last tweaked by Mike Spreitzer on August 26, 1988 3:16:35 pm PDT
DIRECTORY AbSets, AMBridge, AMTypes, BasicTime, BiRels, IntStuff, IO, LichenDataOps, LichenDataStructure, LichenIntBasics, PrintTV, Rope, SetBasics;
LichenDataImpl2A: CEDAR PROGRAM
IMPORTS AbSets, AMBridge, BiRels, IntStuff, IO, LichenDataOps, LichenDataStructure, LichenIntBasics, PrintTV, SetBasics
EXPORTS LichenDataOps, LichenDataStructure
=
BEGIN OPEN IS:IntStuff, LIB:LichenIntBasics, LIB, LichenDataStructure, LichenDataOps, Sets:AbSets;
CreateDesign: PUBLIC PROC [names: Set--of ROPE--] RETURNS [d: Design] ~ {
IF names.SpaceOf[] # SetBasics.ropes[TRUE] THEN ERROR;
IF names.Empty[] THEN ERROR;
d ← NEW [DesignPrivate];
d.names ← Sets.CreateHashCopy[names];
d.eSpace ← CreateEntitySpace[d];
d.eSetSpace ← Sets.CreateSetSpace[d.eSpace];
d.cellTypes ← Sets.CreateHashSet[d.eSpace];
d.labelCellTypes ← Sets.CreateHashSet[d.eSpace];
d.transistorCellTypes ← Sets.CreateFilter[[CTIsTransistor, d.eSpace, d]];
d.sub ← BiRels.CreateHashFn[spaces: [d.eSpace, SetBasics.refs], invable: FALSE];
d.parent ← BiRels.CreateHashFn[spaces: ALL[d.eSpace], invable: TRUE];
d.ancest ← d.parent.TransitiveFnClosure[TRUE];
d.toRoot ← d.parent.ExtremeFnClosure[];
d.pwUpward ← d.parent.ClosureOrder[];
d.pwDownward ← d.pwUpward.ReversePO[];
d.nontriviallyConnectedWires ← Sets.CreateFilter[[WireNontriviallyConnected, d.eSpace, d]];
d.wiresConnectedAtSomeInstance ← Sets.CreateFilter[[WireConnectedAtSomeInstance, d.eSpace, d]];
d.cct ← [
p: BiRels.CreateHashFn[spaces: [d.eSpace, d.eSpace], invable: TRUE],
w: BiRels.CreateHashFn[spaces: [d.eSpace, d.eSpace], invable: TRUE],
i: BiRels.CreateHashFn[spaces: [d.eSpace, d.eSpace], invable: TRUE]];
d.partses ← [d.cct[p].SetOn[left], d.cct[w].SetOn[left], d.cct[i].SetOn[left]];
d.pws ← d.partses[p].Union[d.partses[w], TRUE];
d.parts ← d.pws.Union[d.partses[i], TRUE];
d.isntTop ← d.parent.SetOn[left];
d.isComposite ← d.sub.SetOn[left];
d.isTop ← d.pws.Difference[d.isntTop];
d.isAtomic ← d.pws.Difference[d.isComposite];
d.ciType ← BiRels.CreateHashFn[spaces: [d.eSpace, d.eSpace], invable: TRUE];
d.ctName ← BiRels.CreateHashReln[spaces: [d.eSpace, SetBasics.ropes[TRUE]]];
d.arrayElt ← BiRels.CreateHashFn[spaces: ALL[d.eSpace], invable: TRUE];
d.ciXfm ← BiRels.CreateHashTable[[d.eSpace, xfmSpace]];
{w2i: Fn ~ BiRels.FnFromProc[WireToInstances, [d.eSpace, d.eSetSpace], d];
i2w: Fn ~ BiRels.FnFromProc[InstanceToWires, [d.eSpace, d.eSetSpace], d];
d.iwConns ← BiRels.CreateFromHalves[
spaces: ALL[d.eSpace],
halves: [[dullHalfClass, i2w], [dullHalfClass, w2i]]]};
d.scale ← 0.0;
d.inheritNames ← FALSE;
d.other ← BiRels.CreateHashTable[];
RETURN};
CTIsTransistor: PROC [val: Sets.Value, data: REF ANYNIL] RETURNS [BOOL] ~ {
ct: CellType ~ NARROW[val.VA];
RETURN [ct.asTrans # NIL]};
WireNontriviallyConnected: PROC [val: Sets.Value, data: REF ANYNIL] RETURNS [BOOL] ~ {
w: Wire ~ NARROW[val.VA];
RETURN [w.conns.Size[IS.two].Compare[IS.two] >= equal]};
WireConnectedAtSomeInstance: PROC [val: Sets.Value, data: REF ANYNIL] RETURNS [BOOL] ~ {
w: Wire ~ NARROW[val.VA];
d: Design ~ NARROW[data];
RETURN [w.conns.ScanHalfRestriction[d.partses[i], BiRels.AcceptAny, right].found]};
WireToInstances: PROC [data: REF ANY, v: Sets.Value] RETURNS [mv: Sets.MaybeValue] ~ {
w: Wire ~ NARROW[v.VA];
d: Design ~ NARROW[data];
RETURN [[TRUE, w.conns.SetOn[right].SV[]]]};
InstanceToWires: PROC [data: REF ANY, v: Sets.Value] RETURNS [mv: Sets.MaybeValue] ~ {
ci: CellInstance ~ NARROW[v.VA];
d: Design ~ NARROW[data];
RETURN [[TRUE, ci.conns.SetOn[right].SV[]]]};
CreateEntitySpace: PROC [d: Design] RETURNS [Sets.Space] ~ {
RETURN [NEW [SetBasics.SpacePrivate ← [
Contains: EntityContains,
Equal: SetBasics.refs.Equal,
AHash: SetBasics.refs.AHash,
ACompare: SetBasics.refs.ACompare,
Print: EntityPrint,
name: IO.PutFR["entities of %g", [rope[NARROW[d.names.AnElt[].MA] ]] ],
data: d
]]]};
EntityContains: PROC [data: REF ANY, v: Sets.Value] RETURNS [BOOL] ~ {
d: Design ~ NARROW[data];
IF v.i#0 THEN RETURN [FALSE];
WITH v.ra SELECT FROM
ct: CellType => RETURN [TRUE];
v: Vertex => RETURN [TRUE];
p: Port => RETURN [TRUE];
ENDCASE => RETURN [FALSE]};
EntityPrint: PROC [data: REF ANY, v: Sets.Value, to: IO.STREAM, depth, length: INT, verbose: BOOL] ~ {
d: Design ~ NARROW[data];
ra: REF ANY ~ v.VA;
WITH ra SELECT FROM
ct: CellType => {
name: ROPE ~ ct.ACtName[];
to.PutRope[name];
};
ENDCASE => {
class: PartClass ~ WITH ra SELECT FROM
p: Port => p,
w: Wire => w,
ci: CellInstance => i,
ENDCASE => ERROR;
cct: CellType ~ NARROW[d.cct[class].Apply[v].MA];
mv: Sets.MaybeValue ~ cct.fullName[class].Lookup[goal: v, side: left];
IF mv.found
THEN to.PutRope[UnparseSteppyName[VSn[mv.it]]]
ELSE PrintTV.Print[RaTv[ra], to, depth, length, verbose];
RETURN};
};
fullNameHints: PUBLIC BiRels.HintPair ~ [
leftToRight: [
fn: [$Hash],
set: [$List, LIST[[$RelOrder, $fwd]]]
],
rightToLeft: [
fn: [$Hash],
set: [$Hash]
]];
CreateCellType: PUBLIC PROC [d: Design, flavor: CellFlavor, bbox: Range2, names: Set--of ROPE--] RETURNS [ct: CellType] ~ {
ct ← NEW [CellTypePrivate ← [
d: d,
fullName: [
p: BiRels.GenCreate[spaces: [d.eSpace, steppyNameSpace], hints: fullNameHints],
w: nilBiRel,
i: nilBiRel],
isDeduced: [
p: [
FALSE: Sets.CreateHashSet[d.eSpace],
TRUE: Sets.CreateHashSet[d.eSpace]],
w: [
FALSE: Sets.CreateHashSet[d.eSpace],
TRUE: Sets.CreateHashSet[d.eSpace]]],
bbox: bbox,
other: BiRels.CreateHashTable[]
]];
ct.nameOrder[p] ← BiRels.MapOrder[ct.fullName[p], leftToRight, Sets.fwd];
IF NOT d.cellTypes.AddA[ct] THEN ERROR;
[] ← d.ctName.AddSet[BiRels.CreateProduct[[Sets.CreateSingleA[ct, d.eSpace], names]]];
IF flavor=unorganized THEN FinishCreatingUnorganized[ct];
RETURN};
dullHalfClass: BiRels.HalfClass ~ NEW [BiRels.HalfClassPrivate ← [NIL]];
FinishCreatingUnorganized: PUBLIC PROC [ct: CellType] ~ {
d: Design ~ ct.d;
exports: BiRel ~ BiRels.CreateHashFn[[d.eSpace, d.eSpace]];
wires: Set ~ ct.CTParts[w];
ct.fullName[w] ← BiRels.GenCreate[spaces: [d.eSpace, steppyNameSpace], hints: fullNameHints];
ct.fullName[i] ← BiRels.GenCreate[spaces: [d.eSpace, steppyNameSpace], hints: fullNameHints];
ct.nameOrder[w] ← BiRels.MapOrder[ct.fullName[w], leftToRight, Sets.fwd];
ct.nameOrder[i] ← BiRels.MapOrder[ct.fullName[i], leftToRight, Sets.fwd, Sets.alleq];
ct.asu ← NEW [UnorganizedPrivate ← [
exports: exports,
publics: exports.SetOn[right]
]];
ct.asu.exportable ← wires.Intersection[Sets.CreateFilter[[TestExportable, d.eSpace, ct]]];
ct.asu.publicOrExportable ← ct.asu.publics.Union[ct.asu.exportable];
ct.asu.stuck ← wires.Difference[ct.asu.publicOrExportable];
};
TestExportable: PROC [val: Sets.Value, data: REF ANYNIL] RETURNS [BOOL] ~ {
ct: CellType ~ NARROW[data];
w: Wire ~ NARROW[val.VA];
IF ct.asu.publics.HasMember[val] THEN RETURN [FALSE];
{kids: Seq ~ BiRels.DeRef[ct.d.sub.ApplyA[w].MDA];
IF kids=nilBiRel THEN RETURN [TRUE];
RETURN ct.ExportableKids[kids]}};
CreatePort: PUBLIC PROC [ct: CellType, fullNames: Set--of SteppyName--, deduced, addum, nameDum, fixExpConns, fixInstConns, fixWExpConns, fixWInstConns: BOOL, children: Seq--of Port-- ← nilBiRel] RETURNS [p: Port] ~ {
d: Design ~ ct.d;
atomic: BOOL ~ children = nilBiRel;
FixUse: PROC [use: CellUse] ~ {WITH use SELECT FROM
ci: CellInstance => {
cct: CellType ~ d.CiCct[ci];
kidWires: Seq ← nilBiRel;
w: Wire ← NIL;
{IF NOT atomic THEN {
kidWires ← children.Compose[ci.conns];
IF kidWires.Size#children.Size THEN GOTO DontConnect;
{ssi: SubsIndex ~ d.SubseqIndex[kidWires];
IF ssi.multiparents THEN GOTO DontConnect;
IF ssi.full THEN {w ← NARROW[ssi.parent]; GOTO Connect};
IF NOT addum THEN GOTO DontConnect;
IF ssi.parent#NIL THEN GOTO DontConnect;
kidWires ← kidWires.CreateVectorCopy}}
ELSE IF NOT addum THEN GOTO DontConnect;
w ← CreateWire[cct, IF d.inheritNames AND nameDum THEN ActualNames[d.labelCellTypes.HasMemA[ct], cct.INames[ci], fullNames] ELSE emptySteppySet, FALSE, fixWExpConns, fixWInstConns, kidWires];
EXITS Connect => use ← use};
Connect[d, w, p, ci];
RETURN
EXITS DontConnect => ct ← ct};
act: CellType => NoteNewEltPort[act, p];
ENDCASE => ERROR};
p ← NEW [PortPrivate ← []];
d.cct[p].AddNewAA[p, ct];
IF NOT ct.isDeduced[p][deduced].AddA[p] THEN ERROR;
KnowPortNames[ct, p, fullNames, FALSE];
IF children # nilBiRel THEN {
nKids: NAT ~ children.Size.EN;
IF children.GetIntDom # [0, nKids-1] THEN ERROR;
d.sub.AddNewAA[p, children.Refify];
[] ← d.parent.AddSet[BiRels.CreateProduct[[children.SetOn[right], Sets.CreateSingleA[p, d.eSpace]]]];
IF fixExpConns THEN {
IF ct.asu#NIL THEN ClosePortConnectivity[d, p, children, ct.asu.exports, ct];
IF ct.asArray#NIL THEN NoteNewArrayPort[ct, p]};
};
IF addum OR (fixInstConns AND NOT atomic) THEN ct.EnumerateUses[FixUse];
RETURN};
ClosePortsConnectivity: PUBLIC PROC [d: Design, parents: Set--of Port--, conns: Fn--Port b Wire--, site: Cell] ~ {
CloseParent: PROC [pv: Sets.Value] RETURNS [BOOL] ~ {
parent: Port ~ NARROW[pv.VA];
kidPorts: Seq ~ d.SubSeq[parent];
ClosePortConnectivity[d, parent, kidPorts, conns, site];
RETURN [FALSE]};
IF parents.Scan[CloseParent].found THEN ERROR;
RETURN};
ClosePortConnectivity: PUBLIC PROC [d: Design, parent: Port, kidPorts: Seq--of Port--, conns: Fn--Port b Wire--, site: Cell] ~ {
DO
kidWires: Seq--of Wire-- ~ kidPorts.Compose[conns];
IF kidWires.Size#kidPorts.Size THEN RETURN;
{si: SubsIndex ~ d.SubseqIndex[kidWires];
IF NOT si.full THEN RETURN;
IF si.parent=NIL THEN ERROR;
Connect[d, NARROW[si.parent], parent, site];
parent ← d.PParent[parent];
IF parent=NIL THEN RETURN;
kidPorts ← d.SubSeq[parent];
}ENDLOOP;
};
CreateWire: PUBLIC PROC [ct: CellType, fullNames: Set--of SteppyName--, deduced, fixExpConns, fixInstConns: BOOL, children: Seq--of Wire-- ← nilBiRel] RETURNS [w: Wire] ~ {
d: Design ~ ct.d;
FixConn: PROC [porta: REF ANY, site: Cell] ~ {
p0: Port ~ NARROW[porta];
pp: Port ~ d.PParent[p0];
IF pp=NIL THEN RETURN;
IF NOT ((fixExpConns AND fixInstConns) OR (WITH site SELECT FROM ci: CellInstance => fixInstConns, ct: CellType => fixExpConns, ENDCASE => ERROR)) THEN RETURN;
{kidPorts: Seq ~ BiRels.DeRef[d.sub.ApplyA[pp].MA];
kidWires: Seq ~ kidPorts.Compose[SiteConns[site]];
IF kidWires.Equal[children] THEN Connect[d, w, pp, site];
RETURN}};
w ← CreateBareWire[d];
d.cct[w].AddNewAA[w, ct];
IF NOT ct.isDeduced[w][deduced].AddA[w] THEN ERROR;
KnowVertexNames[ct, w, fullNames, FALSE];
IF children # nilBiRel THEN {
nKids: NAT ~ children.Size.EN;
IF children.GetIntDom # [0, nKids-1] THEN ERROR;
d.sub.AddNewAA[w, children.Refify];
[]← d.parent.AddSet[BiRels.CreateProduct[[children.SetOn[right], Sets.CreateSingleA[w, d.eSpace]]]];
IF fixExpConns OR fixInstConns THEN {
c0: Wire ~ NARROW[children.ApplyI[0].MA];
c0.conns.EnumAA[FixConn];
w ← w};
w ← w};
RETURN};
CreateBareWire: PUBLIC PROC [d: Design] RETURNS [Wire] ~ {
RETURN [NEW [VertexPrivate[w] ← [variant: w[conns: BiRels.CreateHashReln[spaces: ALL[d.eSpace]]] ]]]};
CreateBareInstance: PUBLIC PROC [d: Design, offset: Int2] RETURNS [CellInstance] ~ {
RETURN [NEW [VertexPrivate.i ← [variant: i[BiRels.CreateHashFn[ALL[d.eSpace]], offset]]]]};
Instantiate: PUBLIC PROC [ict, cct: CellType, addum: BOOL, xfm: Transform, offset: Int2, names: Set--of SteppyName--] RETURNS [ci: CellInstance] ~ {
d: Design ~ ict.d;
ci ← CreateBareInstance[d, offset];
d.cct[i].AddNewAA[ci, cct];
d.ciType.AddNewAA[ci, ict];
IF d.ciXfm#nilBiRel THEN d.ciXfm.AddNewPair[[AV[ci], XfmV[xfm]]];
IF cct.bbox#fullRange2 AND NOT Range2Empty[ict.bbox] THEN cct.bbox ← IF ict.bbox=fullRange2 THEN fullRange2 ELSE Range2Mbb[cct.bbox, TransOffRange2[xfm, offset, ict.bbox]];
KnowVertexNames[cct, ci, names, FALSE];
IF addum THEN {
DumPort: PROC [pval: Sets.Value] RETURNS [BOOL] ~ {
p: Port ~ NARROW[pval.VA];
kidPorts: Seq ~ d.SubSeq[p];
kidWires: Seq ~ IF kidPorts#nilBiRel THEN kidPorts.Compose[ci.conns] ELSE nilBiRel;
IF kidPorts#nilBiRel AND kidPorts.Size # kidWires.Size THEN ERROR;
{w: Wire ~ CreateWire[cct, IF d.inheritNames THEN ActualNames[d.labelCellTypes.HasMemA[ict], names, ict.PNames[p]] ELSE emptySteppySet, FALSE, FALSE--don't bother, we know it's private--, FALSE--don't bother, it's taken care of by me--, kidWires];
Connect[d, w, p, ci];
RETURN [FALSE]}};
IF ict.CTParts[p].Scan[DumPort, d.pwUpward].found THEN ERROR;
ci ← ci};
RETURN};
RaTv: PROC [ra: REF ANY] RETURNS [AMTypes.TV] ~ TRUSTED {
RETURN AMBridge.TVForReferent[NEW [REF ANY ← ra], const]};
END.