<> <> <> <> <> <<>> DIRECTORY Core, CoreClasses, CoreCreate, CoreFlat, CoreOps, CoreProperties, GList, RefTab; TestCore: CEDAR PROGRAM IMPORTS CoreClasses, CoreCreate, CoreFlat, CoreOps, CoreProperties, GList, RefTab = BEGIN OPEN Core; CreateInverter: PROC [] RETURNS [cellType: CellType] = { In: Wire _ CoreOps.CreateWire[name: "In"]; Out: Wire _ CoreOps.CreateWire[name: "Out"]; Gnd: Wire _ CoreOps.CreateWire[name: "Gnd"]; Vdd: Wire _ CoreOps.CreateWire[name: "Vdd"]; ntrans: CoreClasses.CellInstance _ NEW [CoreClasses.CellInstanceRec _ [ actual: CoreOps.CreateWire[LIST [In, Out, Gnd]], type: CoreClasses.CreateTransistor[nE] ]]; ptrans: CoreClasses.CellInstance _ NEW [CoreClasses.CellInstanceRec _ [ actual: CoreOps.CreateWire[LIST [In, Out, Vdd, Vdd]], type: CoreClasses.CreateTransistor[pE] ]]; cellType _ CoreClasses.CreateRecordCell[ public: CoreOps.CreateWire[LIST [In, Out, Gnd, Vdd]], internal: CoreOps.CreateWire[LIST [In, Out, Gnd, Vdd]], instances: LIST [ntrans, ptrans], name: "Inverter" ]; }; Create2Inverter: PROC [] RETURNS [cellType: CellType] = { In: Wire _ CoreOps.CreateWire[name: "In"]; Out: Wire _ CoreOps.CreateWire[name: "Out"]; Gnd: Wire _ CoreCreate.Seq[size:2, name: "Gnd"]; Vdd: Wire _ CoreCreate.Seq[size:2, name: "Vdd"]; Intern: Wire _ CoreOps.CreateWire[name: "Intern"]; inverter: CellType _ CreateInverter[]; first: CoreClasses.CellInstance _ NEW [CoreClasses.CellInstanceRec _ [ actual: CoreOps.CreateWire[LIST [In, Intern, Gnd[0], Vdd[0]]], type: inverter ]]; second: CoreClasses.CellInstance _ NEW [CoreClasses.CellInstanceRec _ [ actual: CoreOps.CreateWire[LIST [Intern, Out, Gnd[1], Vdd[1]]], type: inverter ]]; cellType _ CoreClasses.CreateRecordCell[ public: CoreOps.CreateWire[LIST [In, Out, Gnd, Vdd]], internal: CoreOps.CreateWire[LIST [In, Out, Gnd, Vdd, Intern]], instances: LIST [first, second], name: "Inverter2" ]; }; <<>> CreateInverters: PROC [n: NAT] RETURNS [cellType: CellType] = { args: CoreClasses.SequenceCellType _ NEW [CoreClasses.SequenceCellTypeRec _ [base: CreateInverter[], count: n, sequence: NEW [CoreClasses.SequenceSetRec[2]]]]; args.sequence[0] _ 0; args.sequence[1] _ 1; cellType _ CoreClasses.CreateSequence[name: "ALotOfInverters", args: args]; }; CreateInvertersPlusOne: PROC [n: NAT] RETURNS [cellType: CellType] = { public: Wire _ CoreCreate.Wires["SameIn", CoreCreate.Seq["Outs", n+1], "Gnd", "Vdd"]; pas: LIST OF CoreCreate.PA _ NIL; FOR i: NAT IN [0 .. n) DO pas _ CONS [[CoreCreate.Index["In", i], "SameIn"], pas] ENDLOOP; pas _ CONS [["Out", CoreCreate.Range[public[1], 1, n]], pas]; cellType _ CoreCreate.Cell[ public: public, instances: LIST [ CoreCreate.Instance[CreateInverter[], ["In", "SameIn"], ["Out", public[1][0]], ["Gnd", CoreOps.CreateWire[name: "Gnd"]], ["Vdd", CoreCreate.FindWire[public, "Vdd"]]], CoreCreate.InstanceList[CreateInverters[n], pas] ], name: "InvertersPlusOne" ]; }; CreateUnNamed2Inverter: PROC [] RETURNS [cellType: CellType] = { In: Wire _ CoreOps.CreateWire[]; Out: Wire _ CoreOps.CreateWire[]; Gnd: Wire _ CoreCreate.Seq[size:2]; Vdd: Wire _ CoreCreate.Seq[size:2]; Intern: Wire _ CoreOps.CreateWire[]; inverter: CellType _ CreateInverter[]; first: CoreClasses.CellInstance _ NEW [CoreClasses.CellInstanceRec _ [ actual: CoreOps.CreateWire[LIST [In, Intern, Gnd[0], Vdd[0]]], type: inverter ]]; second: CoreClasses.CellInstance _ NEW [CoreClasses.CellInstanceRec _ [ actual: CoreOps.CreateWire[LIST [Intern, Out, Gnd[1], Vdd[1]]], type: inverter ]]; cellType _ CoreClasses.CreateRecordCell[ public: CoreOps.CreateWire[LIST [In, Out, Gnd, Vdd]], internal: CoreOps.CreateWire[LIST [In, Out, Gnd, Vdd, Intern]], instances: LIST [first, second], name: "Inverter2", giveNames: TRUE ]; }; Test: PROC [] = { AllTheWay: FlattenCellTypeProc = {flatten _ cellType.class#CoreClasses.transistorCellClass}; cellType, ct, unspec: CellType; data: CoreClasses.RecordCellType; public, wire: Wire; wires: Wires; table: RefTab.Ref; wirePath: ROPE; flatWire: CoreFlat.FlatWireRec; cellType _ CreateInverter[]; data _ NARROW [cellType.data]; IF CoreClasses.InstanceIndex[cellType, data[1]]#1 THEN ERROR; cellType _ Create2Inverter[]; IF CoreClasses.InstanceIndex[cellType, data[1]]#-1 THEN ERROR; cellType _ CreateInverters[6]; cellType _ CreateInvertersPlusOne[6]; cellType _ CreateUnNamed2Inverter[]; IF CoreOps.FindWire[cellType.public, "In"]=NIL THEN ERROR; IF CoreOps.FindWire[cellType.public, "Out"]=NIL THEN ERROR; IF CoreOps.FindWire[cellType.public, "Gnd"]#NIL THEN ERROR; IF CoreOps.FindWire[cellType.public, "Vdd"]#NIL THEN ERROR; IF CoreOps.FindWire[cellType.public, "Intern"]#NIL THEN ERROR; wire _ cellType.public[2]; -- Gnd wires _ LIST [wire]; IF NOT GList.EqLists[CoreOps.ParentWires[cellType.public, wire[0]], wires] THEN ERROR; wires _ LIST [cellType.public]; IF NOT GList.EqLists[CoreOps.ParentWires[cellType.public, wire], wires] THEN ERROR; IF NOT GList.EqLists[CoreOps.ParentWires[cellType.public, cellType.public], NIL] THEN ERROR; <> cellType _ Create2Inverter[]; cellType _ Flatten[cellType, AllTheWay]; IF cellType.public.size#6 THEN ERROR; data _ NARROW [cellType.data]; IF data.internal.size#7 THEN ERROR; IF data.size#4 THEN ERROR; cellType _ Create2Inverter[]; flatWire _ CoreFlat.ParseWirePath[cellType, "Intern"]; wirePath _ CoreFlat.WirePathRope[cellType, flatWire]; flatWire _ CoreFlat.ParseWirePath[cellType, "/0.actual.In"]; wirePath _ CoreFlat.WirePathRope[cellType, flatWire]; <> cellType _ Create2Inverter[]; public _ CoreCreate.Wires[CoreCreate.Seq["Gnd", 2], "Out"]; -- no Vdd and In and Out collapsed unspec _ CoreClasses.CreateUnspecified[public]; table _ RefTab.Create[]; [] _ RefTab.Store[table, CoreOps.FindWire[cellType.public, "Gnd"], CoreOps.FindWire[public, "Gnd"]]; [] _ RefTab.Store[table, CoreOps.FindWire[cellType.public, "In"], CoreOps.FindWire[public, "Out"]]; [] _ RefTab.Store[table, CoreOps.FindWire[cellType.public, "Out"], CoreOps.FindWire[public, "Out"]]; ct _ CoreClasses.CreatePermutedRecordCell[public, cellType, table]; <> cellType _ Create2Inverter[]; IF CoreProperties.InheritCellTypeProp[cellType, $foo]#NIL THEN ERROR; CoreProperties.PutCellTypeProp[cellType, $foo, $bar]; IF CoreProperties.InheritCellTypeProp[cellType, $foo]#$bar THEN ERROR; CoreProperties.PutCellTypeProp[cellType, $foo, NIL]; CoreProperties.PutCellClassProp[cellType.class, $foo, $bar]; IF CoreProperties.InheritCellTypeProp[cellType, $foo]#$bar THEN ERROR; CoreProperties.PutCellTypeProp[cellType, $foo, $zob]; IF CoreProperties.InheritCellTypeProp[cellType, $foo]#$zob THEN ERROR; CoreProperties.PutCellTypeProp[cellType, $foo, NIL]; CoreProperties.PutCellClassProp[cellType.class, $foo, NIL]; IF CoreProperties.InheritCellTypeProp[cellType, $foo]#NIL THEN ERROR; CoreProperties.PutWireProp[CoreOps.FindWire[cellType.public, "Gnd"], $bip, $bop]; IF CoreProperties.InheritPublicProp[cellType, CoreOps.FindWire[cellType.public, "Gnd"], $bip]#$bop THEN ERROR; IF CoreProperties.InheritPublicProp[cellType, CoreOps.FindWire[cellType.public, "Gnd"], $burp]#NIL THEN ERROR; }; FlattenCellTypeProc: TYPE = PROC [cellType: CellType] RETURNS [flatten: BOOL]; Flatten: PUBLIC PROC [root: CellType, flattenCellType: FlattenCellTypeProc] RETURNS [flat: CellType] = { BuildPublic: PROC [wire: Wire] = { flatWire: CoreFlat.FlatWire = NEW [CoreFlat.FlatWireRec _ [wire: wire, flatCell: CoreFlat.rootCellType]]; newPublic: Wire; IF RefTab.Fetch[rootFlatsToInternals, flatWire].val#NIL THEN RETURN; -- public already seen newPublic _ CoreOps.CreateWire[]; [] _ RefTab.Store[rootFlatsToInternals, flatWire, newPublic]; internal _ CONS [newPublic, internal]; publics _ CONS [newPublic, publics]; }; BuildActual: PROC [public: Wire, bindings: CoreFlat.Bindings] RETURNS [actual: Wire] = { IF public.size=0 THEN { flatWire: CoreFlat.FlatWire _ NARROW [RefTab.Fetch[bindings, public].val]; IF flatWire=NIL THEN flatWire _ NEW[CoreFlat.FlatWireRec _ [ flatCell: CoreFlat.rootCellType, wire: public]]; actual _ NARROW [RefTab.Fetch[rootFlatsToInternals, flatWire].val]; IF actual#NIL THEN RETURN; actual _ CoreOps.CreateWire[]; [] _ RefTab.Store[rootFlatsToInternals, flatWire, actual]; internal _ CONS [actual, internal]; } ELSE { actual _ CoreOps.CreateWires[size: public.size]; FOR i: NAT IN [0 .. actual.size) DO actual[i] _ BuildActual[public[i], bindings]; ENDLOOP; }; }; FlattenCell: CoreFlat.BoundFlatCellProc = { <<[cell: CellType, target: FlatCellTypeRec _ allFlatCells, flatCell: FlatCellTypeRec _ [], bindings: Bindings _ NIL, instance: CellInstance _ NIL, parent: CellType _ NIL, flatParent: FlatCellTypeRec _ []]>> actual: Wire; IF flattenCellType[cell] THEN CoreFlat.NextBoundCellType[cell, target, flatCell, instance, index, parent, flatParent, data, bindings, FlattenCell] ELSE { actual _ BuildActual[cell.public, bindings]; FOR i: NAT IN [0 .. actual.size) DO IF NOT CoreOps.Member[internal, actual[i]] THEN internal _ CONS [actual[i], internal]; ENDLOOP; instances _ CONS [ CoreClasses.CreateInstance[actual: actual, type: cell], instances]; }; }; rootFlatsToInternals: CoreFlat.Bindings _ RefTab.Create[equal: CoreFlat.FlatWireEqual, hash: CoreFlat.FlatWireHash]; publics: LIST OF Wire _ NIL; internal: LIST OF Wire _ NIL; instances: LIST OF CoreClasses.CellInstance _ NIL; CoreOps.VisitRootAtomics[root.public, BuildPublic]; FlattenCell[root]; flat _ CoreClasses.CreateRecordCell[ public: CoreOps.CreateWire[publics], internal: CoreOps.CreateWire[internal], instances: instances, giveNames: TRUE]; }; END.