DIRECTORY Core, CoreClasses, CoreOps, CoreProperties, GList, HashTable, IO, Rope; CoreClassesImpl: CEDAR PROGRAM IMPORTS CoreOps, CoreProperties, GList, HashTable, IO, Rope EXPORTS CoreClasses = BEGIN OPEN Core, CoreClasses; recordCellClass: PUBLIC CellClass _ CoreOps.SetClassPrintProc[NEW [CellClassRec _ [name: "Record", layersProps: FALSE]], PropRecordPrint]; PropRecordPrint: CoreOps.PrintClassProc = { recordCellType: RecordCellType _ NARROW [data]; CoreOps.PrintIndent[indent, out]; IO.PutRope[out, "Internal wire:"]; CoreOps.PrintWire[recordCellType.internal, out, indent, level]; CoreOps.PrintIndent[indent, out]; IO.PutF[out, "%g instances", IO.int[recordCellType.size]]; FOR i: NAT IN [0 .. recordCellType.size) DO instance: CellInstance = recordCellType.instances[i]; EachWirePair: CoreOps.EachWirePairProc = { publicName: ROPE = CoreOps.GetFullWireName[instance.type.public, publicWire]; actualName: ROPE = CoreOps.GetFullWireName[recordCellType.internal, actualWire]; subWires _ CoreOps.GetShortWireName[publicWire]=NIL AND publicWire.size>0; IF NOT subWires THEN IF Rope.Match["[*]", actualName] THEN out.PutF[" %g: %g(%g^);", IO.rope[publicName], IO.rope[actualName], IO.int[LOOPHOLE[actualWire]]] ELSE out.PutF[" %g: %g;", IO.rope[publicName], IO.rope[actualName]]; }; CoreOps.PrintIndent[indent, out]; IO.PutF[out, "CellInstance %g: %g", [rope[GetCellInstanceName[instance]]], [rope[CoreOps.GetCellTypeName[instance.type]]]]; CoreOps.PrintIndent[indent, out]; IO.PutRope[out, " Actual wire: "]; IF NOT CoreOps.Conform[instance.actual, instance.type.public] THEN out.PutF["\n*** Actual and Public do not conform\n"]; FOR j: NAT IN [0 .. instance.type.public.size) DO [] _ CoreOps.VisitBinding[instance.actual[j], instance.type.public[j], EachWirePair]; ENDLOOP; CoreProperties.PrintProperties[props: instance.properties, out: out, indent: 1, level: level]; ENDLOOP; }; givenNameProp: ATOM _ CoreProperties.RegisterProperty[$GivenName, CoreProperties.Props[[CoreProperties.propPrint, CoreProperties.PropDontPrint]]]; CreateRecordCell: PUBLIC PROC [public: WireSeq, internal: WireSeq, instances: LIST OF CellInstance, name: ROPE _ NIL, props: Properties _ NIL, giveNames: BOOL _ FALSE] RETURNS [recordCell: CellType] = { internals: HashTable.Table _ HashTable.Create[internal.size]; AddInInternals: CoreOps.EachWireProc = {[] _ HashTable.Store[internals, wire, wire]}; data: RecordCellType; size: NAT _ GList.Length[instances]; data _ NEW [RecordCellTypeRec[size]]; size _ 0; FOR i: NAT IN [0 .. internal.size) DO [] _ CoreOps.VisitWire[internal[i], AddInInternals]; ENDLOOP; FOR i: NAT IN [0 .. public.size) DO IF ~HashTable.Fetch[internals, public[i]].found THEN ERROR; -- public public[i] is not part of internal ENDLOOP; FOR list: LIST OF CellInstance _ instances, list.rest WHILE list#NIL DO data[size] _ list.first; size _ size+1; IF NOT CoreOps.Conform[list.first.actual, list.first.type.public] THEN ERROR; FOR i: NAT IN [0 .. list.first.actual.size) DO IF ~HashTable.Fetch[internals, list.first.actual[i]].found THEN ERROR; -- actual list.first.actual[i] is not part of internal ENDLOOP; ENDLOOP; data.internal _ internal; IF giveNames THEN { Fetch: PROC [table: HashTable.Table, key: REF] RETURNS [value: REF] = { value _ HashTable.Fetch[table, key].value; IF value=$None THEN value _ NIL; }; Store: PROC [table: HashTable.Table, key: REF, value: REF] = { [] _ HashTable.Store[table, key, IF HashTable.Fetch[table, key].value=NIL THEN value ELSE $None]; }; FindPossibleName: CoreOps.EachWirePairProc = { value: REF; name: ROPE _ CoreOps.GetShortWireName[publicWire]; IF CoreOps.GetShortWireName[actualWire]#NIL THEN RETURN; IF name=NIL THEN RETURN; value _ HashTable.Fetch[actualPossibleNames, actualWire].value; IF value=$None THEN RETURN; IF Rope.Equal[NARROW [value], name] THEN RETURN; Store[actualPossibleNames, actualWire, name]; }; AddInExistingNames: CoreOps.EachWireProc = { name: ROPE _ CoreOps.GetShortWireName[wire]; IF name=NIL THEN { value: REF _ Fetch[actualPossibleNames, wire]; IF value=NIL THEN RETURN; Store[existingNames, value, wire]; } ELSE Store[existingNames, name, wire]; }; AddName: CoreOps.EachWireProc = { name: ROPE _ CoreOps.GetShortWireName[wire]; value: REF; IF name#NIL THEN RETURN [subWires: FALSE]; value _ Fetch[actualPossibleNames, wire]; IF value=NIL OR Fetch[existingNames, value]#wire THEN RETURN; CoreProperties.PutWireProp[wire, $GivenName, $GivenName]; [] _ CoreOps.SetShortWireName[wire, NARROW [value]]; }; actualPossibleNames: HashTable.Table _ HashTable.Create[]; -- association actual -> possible name for the actual. $None indicates at least two different names. existingNames: HashTable.Table _ HashTable.Create[equal: HashTable.RopeEqual, hash: HashTable.HashRope]; -- association name -> wire that will get that name. $None indicates a conflict FOR i: NAT IN [0 .. data.size) DO [] _ CoreOps.VisitBinding[data[i].actual, data[i].type.public, FindPossibleName]; ENDLOOP; [] _ CoreOps.VisitWire[internal, AddInExistingNames]; [] _ CoreOps.VisitWire[internal, AddName]; }; CoreOps.FlushNameCaches[internal]; recordCell _ CoreOps.CreateCellType[recordCellClass, public, data, name, props]; }; CreateInstance: PUBLIC PROC [actual: WireSeq, type: CellType, name: ROPE _ NIL, props: Properties _ NIL] RETURNS [instance: CellInstance] = { instance _ NEW [CellInstanceRec _ [actual: actual, type: type, properties: props]]; IF name#NIL THEN instance _ SetCellInstanceName[instance, name]; }; GetCellInstanceName: PUBLIC PROC [instance: CellInstance] RETURNS [name: ROPE] = { name _ NARROW [CoreProperties.GetCellInstanceProp[instance, CoreOps.nameProp]]; }; SetCellInstanceName: PUBLIC PROC [instance: CellInstance, name: ROPE] RETURNS [sameInstance: CellInstance] = { CoreProperties.PutCellInstanceProp[on: instance, prop: CoreOps.nameProp, value: name]; sameInstance _ instance; }; CorrespondingActual: PUBLIC PROC [instance: CellInstance, public: Wire] RETURNS [actual: Wire _ NIL] = { EachWirePair: CoreOps.EachWirePairProc = { IF publicWire=public THEN {actual _ actualWire; quit _ TRUE}; }; [] _ CoreOps.VisitBinding[instance.actual, instance.type.public, EachWirePair]; }; Compose: PROC [xToY, yToZ, xToZ: HashTable.Table] RETURNS [ok: BOOL _ TRUE, overWritten: BOOL _ FALSE] = { EachX: HashTable.EachPairAction = { found: BOOL; z: HashTable.Value; [found, z] _ HashTable.Fetch[yToZ, value]; IF NOT found THEN {ok _ FALSE; quit _ TRUE; RETURN}; overWritten _ overWritten OR NOT HashTable.Store[xToZ, key, z]; }; ok _ NOT HashTable.Pairs[xToY, EachX]; }; CreatePermutedRecordCell: PUBLIC PROC [iconPublic: WireSeq, schCell: CellType, table: HashTable.Table, name: ROPE _ NIL, props: Properties _ NIL] RETURNS [recordCell: CellType] = { AddInternal: PROC [wire: Wire] = { IF NOT CoreOps.Member[internals, wire] THEN internals _ CONS [wire, internals]; }; internals: LIST OF Wire _ NIL; public: Wire _ CoreOps.CopyWire[iconPublic]; actual: Wire; schPublicsToRecordPublics: HashTable.Table _ HashTable.Create[]; BEGIN -- fill public and initialize schPublicsToRecordPublics RegisterPublicMapping: CoreOps.EachWirePairProc = { [] _ HashTable.Store[iconToRecord, actualWire, publicWire]; }; iconToRecord: HashTable.Table _ HashTable.Create[]; [] _ CoreOps.VisitBinding[iconPublic, public, RegisterPublicMapping]; FOR i: NAT IN [0 .. public.size) DO AddInternal[public[i]] ENDLOOP; IF NOT Compose[table, iconToRecord, schPublicsToRecordPublics].ok THEN ERROR; END; BEGIN -- fill actual while filling schPublicsToRecordPublics Map: PROC [schPublic: Wire] RETURNS [actual: Wire] = { actual _ NARROW [HashTable.Fetch[schPublicsToRecordPublics, schPublic].value]; IF actual#NIL THEN RETURN; actual _ CoreOps.CreateWires[size: schPublic.size]; [] _ HashTable.Store[schPublicsToRecordPublics, schPublic, actual]; FOR i: NAT IN [0 .. actual.size) DO actual[i] _ Map[schPublic[i]] ENDLOOP; }; actual _ Map[schCell.public]; FOR i: NAT IN [0 .. actual.size) DO AddInternal[actual[i]] ENDLOOP; END; recordCell _ CreateRecordCell [public: public, internal: CoreOps.CreateWire[internals], instances: LIST [CreateInstance[actual, schCell]], name: name, props: props]; }; ReverseCellInstances: PUBLIC PROC [instances: CellInstances] RETURNS [rev: CellInstances _ NIL] = { rev _ NARROW [GList.Reverse[instances]]; }; InstanceIndex: PUBLIC PROC [recordCell: CellType, instance: CellInstance] RETURNS [index: INT _ -1] = { rct: RecordCellType _ NARROW [recordCell.data]; FOR i: NAT IN [0 .. rct.size) DO IF rct[i]=instance THEN RETURN [i]; ENDLOOP; }; transistorCellClass: PUBLIC CellClass _ CoreOps.SetClassPrintProc[NEW [CellClassRec _ [name: "Transistor", layersProps: FALSE]], PrintTransistor]; transistorTypeNames: PUBLIC ARRAY TransistorType OF ROPE _ ["nE", "pE", "nD"]; transistorPortNames: PUBLIC ARRAY TransistorPort OF ROPE _ ["gate", "ch1", "ch2"]; PrintTransistor: CoreOps.PrintClassProc = { tran: Transistor _ NARROW [data]; IO.PutF[out, "\n\ntype: %g, length: %g, width: %g", IO.rope[transistorTypeNames[tran.type]], IO.int[tran.length], IO.int[tran.width]]; }; CreateTransistor: PUBLIC PROC [args: TransistorRec, name: ROPE _ NIL, props: Properties _ NIL] RETURNS [cellType: CellType] = { tranNames: ARRAY TransistorType OF ROPE _ ["nE", "pE", "nD"]; tranPublic: Wire _ CoreOps.CreateWire[LIST[ CoreOps.CreateWire[name: "gate"], CoreOps.CreateWire[name: "ch1"], CoreOps.CreateWire[name: "ch2"] ]]; cellType _ CoreOps.CreateCellType[ class: transistorCellClass, public: tranPublic, data: NEW [TransistorRec _ args], name: name, props: props]; }; unspecifiedCellClass: PUBLIC CellClass _ NEW [CellClassRec _ [name: "Unspecified", layersProps: FALSE]]; CreateUnspecified: PUBLIC PROC [public: WireSeq, name: ROPE _ NIL, props: Properties _ NIL] RETURNS [cellType: CellType] = { cellType _ CoreOps.CreateCellType[ class: unspecifiedCellClass, public: public, data: NIL, name: name, props: props]; }; sequenceCellClass: PUBLIC CellClass _ CoreOps.SetClassPrintProc[NEW [CellClassRec _ [name: "Sequence", recast: RecastSequence, layersProps: FALSE]], PrintSequence]; PrintSequence: CoreOps.PrintClassProc = { cell: SequenceCellType _ NARROW [data]; IO.PutF[out, "\n\nBase cell type: %g", IO.rope[CoreOps.GetCellTypeName[cell.base]]]; IO.PutF[out, ", count: %g", IO.int[cell.count]]; IO.PutRope[out, "\nsequence wires:"]; IF cell.sequence#NIL THEN FOR seq: NAT IN [0 .. cell.sequence.length) DO IO.PutF[out, " %g", IO.rope[CoreOps.GetShortWireName[ cell.base.public[cell.sequence[seq]]]]]; ENDLOOP; IO.PutRope[out, "\nflat sequence wires:"]; IF cell.flatSequence#NIL THEN FOR seq: NAT IN [0 .. cell.flatSequence.length) DO IO.PutF[out, " %g", IO.rope[CoreOps.GetShortWireName[ cell.base.public[cell.flatSequence[seq]]]]]; ENDLOOP; IO.PutRope[out, "\nstitch wires:"]; IF cell.stitch#NIL THEN FOR seq: NAT IN [0 .. cell.stitch.length) DO IO.PutF[out, " [%g, &g]", IO.rope[CoreOps.GetShortWireName[ cell.base.public[cell.stitch[seq].this]]], IO.rope[CoreOps.GetShortWireName[ cell.base.public[cell.stitch[seq].that]]]]; ENDLOOP; }; RecastSequence: RecastProc = { seqCell: SequenceCellType _ NARROW[me.data]; public: Wire _ CoreOps.CopyWire[me.public]; newInternal: Wire _ NEW [WireRec[public.size+seqCell.count]]; instances: LIST OF CoreClasses.CellInstance _ NIL; FOR w: NAT IN [0..public.size) DO newInternal[w] _ public[w]; ENDLOOP; FOR cell: NAT DECREASING IN [0..seqCell.count) DO newWire: Wire _ NEW[WireRec[public.size] _ public^]; cellTypeName: ROPE _ CoreOps.GetCellTypeName[seqCell.base]; IF seqCell.sequence#NIL THEN FOR seqWire: NAT IN [0..seqCell.sequence.length) DO seqElement: NAT _ seqCell.sequence[seqWire]; newWire[seqElement] _ newWire[seqElement][cell]; ENDLOOP; IF seqCell.flatSequence#NIL THEN FOR seqWire: NAT IN [0..seqCell.flatSequence.length) DO seqElement: NAT _ seqCell.flatSequence[seqWire]; size: NAT _ seqCell.base.public[seqElement].size; actWire: Wire _ NEW[WireRec[size]]; FOR i: NAT IN [0..size) DO actWire[i] _ newWire[seqElement][(size*cell)+i]; ENDLOOP; newWire[seqElement] _ actWire; ENDLOOP; IF seqCell.stitch#NIL AND seqCell.count>1 AND cellKš œ!žœ#žœžœžœ˜aKšœ˜—šŸœ˜.Jšœžœ˜ Jšœžœ(˜2Jšžœ&žœžœžœ˜8Jšžœžœžœžœ˜Jšœ?˜?Jšžœ žœžœ˜Jšžœ žœžœžœ˜0Jšœ-˜-Jšœ˜—šŸœ˜,Kšœžœ"˜,šžœžœžœ˜Kšœ™Jšœžœ$˜.Jšžœžœžœžœ˜Jšœ"˜"Jšœžœ"˜(—K˜—šŸœ˜!Kšœžœ"˜,Kšœžœ˜ Kš žœžœžœžœ žœ˜*Kšœ)˜)Kš žœžœžœ"žœžœ˜=Kšœ9˜9Kšœ$žœ ˜5K˜—Kšœ;‘e˜ Kšœi‘P˜ΉKšœ ™ šžœžœžœž˜!J˜QJšžœ˜—Kšœ5™5Kšœ5˜5Kšœ/™/Kšœ*˜*K˜—Kšœ"˜"KšœP˜PK˜—J˜šŸœžœžœ)žœžœžœžœ˜Kšœ žœE˜SKšžœžœžœ0˜@K˜J˜—š Ÿœžœžœžœžœ˜RKšœžœB˜OK˜J˜—š Ÿœžœžœ žœžœ!˜nKšœV˜VKšœ˜K˜K˜—š Ÿœžœžœ(žœžœ˜hš  œ˜*Kšžœžœžœ˜=K˜—KšœO˜OK˜J˜—Kšœ…™…šŸœžœ%žœžœžœžœžœ˜jšŸœ˜#Kšœžœ˜ Kšœ>˜>Kš žœžœžœžœ žœžœ˜4Kšœžœžœ˜?K˜—Kšœžœ˜&K˜K˜—šŸœžœžœHžœžœžœžœ˜΄šŸ œžœ˜"Kšžœžœ!žœ žœ˜OK˜—Kšœ žœžœžœ˜Kšœ,˜,Kšœ ˜ Kšœ@˜@šžœ‘7˜=šŸœ˜3Kšœ;˜;K˜—Kšœ3˜3KšœE˜EKš žœžœžœžœžœ˜CKšžœžœ<žœžœ˜MKšžœ˜—šžœ‘6˜<šŸœžœžœ˜6Kšœ žœ?˜NKšžœžœžœžœ˜Kšœ3˜3KšœC˜CKš žœžœžœžœžœ˜JK˜—Kšœ˜Kš žœžœžœžœžœ˜CKšžœ˜—Kšœcžœ>˜₯Kšœ˜K˜—š Ÿœžœžœžœžœ˜cJšœžœ˜(J˜J˜—š Ÿ œžœžœ0žœ žœ ˜gKšœžœ˜/šžœžœžœž˜ Kšžœžœžœ˜#Kšžœ˜—Kšœ˜——šŸ ™ Kšœžœ'žœ3žœ˜’K˜š œžœžœžœžœ˜NK˜—š œžœžœžœžœ˜RK˜—šŸœ˜+Jšœžœ˜!Kšžœ2žœ'žœžœ˜†Kšœ˜K˜—šŸœžœžœžœžœžœžœ˜Kšœ žœžœžœ˜=šœ&žœ˜+Jšœ!˜!Jšœ ˜ Jšœ˜Jšœ˜—šœ"˜"Jšœ˜Jšœ˜Jšœžœ˜!Jšœ˜—Kšœ˜——šŸ ™ Kšœžœ žœ4žœ˜hK˜šŸœžœžœžœžœžœžœ˜|šœ"˜"Kšœ˜Kšœ˜Kšœžœ˜ Kšœ ˜ Kšœ˜—Kšœ˜——šŸ™Kšœžœ'žœIžœ˜₯K˜š  œ˜)Jšœžœ˜'Kšžœ%žœ+˜TKšžœžœ˜0Kšžœ#˜%š žœžœžœžœžœžœž˜HKšžœžœH˜^Kšžœ˜—Kšžœ(˜*š žœžœžœžœžœžœ!ž˜PKšžœžœL˜bKšžœ˜—Kšžœ!˜#š žœ žœžœžœžœžœž˜DKšžœžœKžœK˜΄Kšžœ˜—Kšœ˜K˜—šŸœ˜Kšœžœ ˜,Kšœ+˜+Kšœžœ&˜=Kšœ žœžœžœ˜2šžœžœžœž˜!Kšœ˜Kšžœ˜—š žœžœž œžœž˜1Jšœžœ!˜4Jšœžœ)˜;š žœžœžœžœ žœžœž˜PKšœ žœ˜,Jšœ0˜0Kšžœ˜—š žœžœžœžœ žœžœ"ž˜XKšœ žœ!˜0Jšœžœ(˜1Kšœžœ˜#šžœžœžœ ž˜Kšœ0˜0Kšžœ˜—Jšœ˜Kšžœ˜—šžœžœžœžœžœžœ žœžœž˜yKšœžœ ˜)Kšœžœ ˜)Kšœžœ˜„Kšžœ˜—šœ žœ˜!Kšœ˜Kšœ˜Kšœžœžœžœžœžœžœžœžœ ˜_Kšœ ˜ —Kšœ(˜(Kšžœ˜—šœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ"˜"Kšœžœ˜ —Kšœ˜K˜—šŸœžœžœ žœžœžœžœ˜€Kšœ2˜2š žœžœžœžœžœžœž˜FKšœ(˜(Kšœžœ˜)šžœžœžœž˜"Kšœ>žœ˜CKšžœ˜—Kšœ_˜_Kšžœ˜—š žœžœžœžœžœžœž˜NKšœ,˜,Kšœžœ˜+Kšœžœ˜*Kšžœ žœžœ˜šžœžœžœž˜"Kšœ@žœ˜EKšžœ˜—Kšœb˜bKšžœ˜—šœ"˜"Kšœ˜Kšœ˜Kšœ ˜ Kšœ ˜ Kšœ˜—Kšœ˜K˜K˜——Kšžœ˜K˜—…—68Gγ