DIRECTORY CD, CDCommandOps, CDProperties, CDSequencer, Combinatorial, Core, CoreClasses, CoreCreate, CoreDirectory, CoreGeometry, CoreOps, CoreProperties, IO, Rope, RopeList, Sinix, SinixOps, Sisyph, SymTab, TerminalIO; TestCombinatorial: CEDAR PROGRAM IMPORTS CDCommandOps, CDProperties, Combinatorial, CoreCreate, CoreDirectory, CoreGeometry, CoreOps, CoreProperties, IO, Rope, RopeList, Sinix, SinixOps, Sisyph, SymTab, TerminalIO ~ BEGIN OPEN Combinatorial; ToLisps: PROC [params: ParseTrees] RETURNS [rope: ROPE _ NIL] = { WHILE params#NIL DO IF rope#NIL THEN rope _ Rope.Cat[rope, " "]; rope _ Rope.Cat[rope, ToLisp[params.first]]; params _ params.rest; ENDLOOP; }; ToLisp: PROC [tree: ParseTree] RETURNS [rope: ROPE] = { rope _ WITH tree SELECT FROM var: ROPE => var, rptr: REF ParseOperRec => IF Rope.Equal[rptr.oper, "~"] OR Rope.Equal[rptr.oper, "*"] OR Rope.Equal[rptr.oper, "+"] THEN Rope.Cat["(", rptr.oper, " ", ToLisps[rptr.params], ")"] ELSE ToLisp[Recast[tree]], ENDCASE => ERROR; }; StdToLisp: PROC [expr: ROPE] RETURNS [ROPE] = { RETURN [ToLisp[ParseExpression[expr]]]; }; FixLibrary: PROC [name, expr: ROPE] = { cell: Core.CellType = NARROW [SymTab.Fetch[CoreDirectory.FetchLibrary["CMOSB"], name].val]; out: Core.Wire = CoreOps.FindWire[cell.public, "X"]; CoreProperties.PutCellTypeProp[cell, $Combinatorial, NEW [BOOL _ TRUE]]; PutOutput[out, expr]; BindCombinatorial[cell]; CheckTransistorsAgainstExpressions[cell]; }; CMOSBCell: PUBLIC PROC [rope: ROPE] RETURNS [Core.CellType] = { library: CoreDirectory.Library _ CoreDirectory.FetchLibrary["CMOSB"]; publics: LIST OF CoreCreate.WR _ LIST ["X"]; inputs: LIST OF ROPE _ NIL; globals: LIST OF ROPE _ NIL; auxiliary: LIST OF CoreCreate.WR _ NIL; instances: CoreCreate.CellInstances _ NIL; ParseExpr: PROC [rptr: REF ParseOperRec, aim: CoreCreate.WR] = { gate: Core.CellType _ NARROW [SymTab.Fetch[library, rptr.oper].val]; pas: LIST OF CoreCreate.PA _ NIL; params: ParseTrees _ rptr.params; EachWire: PROC [public: Core.Wire] = { name: ROPE = CoreOps.GetShortWireName[public]; SELECT TRUE FROM name=NIL => ERROR; Rope.Equal[name, "Vdd"] OR Rope.Equal[name, "Gnd"] => { IF NOT RopeList.Memb[globals, name] THEN globals _ CONS [name, globals]; }; Rope.Equal[name, "X"] => pas _ CONS [[public, aim], pas]; ENDCASE => { WITH params.first SELECT FROM var: ROPE => { IF NOT RopeList.Memb[inputs, var] THEN inputs _ CONS [var, inputs]; pas _ CONS [[public, var], pas]; }; rptr: REF ParseOperRec => { newAim: Core.Wire _ CoreOps.CreateWire[]; auxiliary _ CONS [newAim, auxiliary]; ParseExpr[rptr, newAim]; pas _ CONS [[public, newAim], pas]; }; ENDCASE => ERROR; params _ params.rest; }; }; CoreOps.VisitRootAtomics[gate.public, EachWire]; -- disgusting assumption about the order of VisitRootAtomics here ... IF params#NIL THEN ERROR; instances _ CONS [CoreCreate.InstanceList[gate, pas], instances]; }; ParseExpr[NARROW [ParseExpression[rope]], "X"]; FOR list: LIST OF ROPE _ inputs, list.rest WHILE list#NIL DO publics _ CONS [list.first, publics]; ENDLOOP; FOR list: LIST OF ROPE _ globals, list.rest WHILE list#NIL DO publics _ CONS [list.first, publics]; ENDLOOP; RETURN [CoreCreate.Cell[ public: CoreCreate.WireList[publics], onlyInternal: CoreCreate.WireList[auxiliary], instances: instances ]]; }; AttemptMakeCombinatorialCommand: PROC [command: CDSequencer.Command] = { trans, ok, notOK: INT; root, cellType: Core.CellType; [root: root, cell: cellType] _ SinixOps.SelectedCellType[command.design, Sisyph.mode]; IF root=NIL THEN RETURN; [trans, ok, notOK] _ AttemptMakeCombinatorial[cellType]; TerminalIO.PutF["AttemptMakeCombinatorial: %g trans, %g ok, %g notOK.\n", IO.int[trans], IO.int[ok], IO.int[notOK]]; }; AttemptSplitCommand: PROC [command: CDSequencer.Command] = { FOR cells: LIST OF Core.CellType _ SinixOps.SelectedCellTypes[command.design, Sisyph.mode], cells.rest WHILE cells#NIL DO record, split: Core.CellType; name: ROPE = CoreOps.GetCellTypeName[cells.first]; object: CD.Object = CoreGeometry.GetObject[Sisyph.mode.decoration, cells.first]; iconFor: ROPE _ NARROW [CDProperties.GetObjectProp[object, $IconFor]]; TerminalIO.PutF["AttemptSplit for %g.\n", IO.rope[name]]; IF cells.first.class#Sinix.iconClass THEN {TerminalIO.PutF["*** AttemptSplit can only be applied to icons of record cells.\n"]; LOOP}; record _ NARROW [cells.first.data]; split _ SplitCombinatorial[record]; IF NOT Rope.Equal[iconFor, Rope.Cat[name, ".sch"]] THEN {TerminalIO.PutF["*** AttemptSplit can only be applied to icons from schematics.\n"]; LOOP}; Sinix.FlushCache[object]; CDProperties.PutObjectProp[object, $IconFor, NIL]; CDProperties.PutObjectProp[object, $CodeFor, IO.PutFR["IF combinatorial THEN Combinatorial.SplitCombinatorial[Sisyph.ES[\"%g\", cx]] ELSE Sisyph.ES[\"%g\", cx]", IO.rope[iconFor], IO.rope[iconFor]]]; ENDLOOP; }; CDCommandOps.RegisterWithMenu[ menu: $OtherProgramMenu, entry: "AttemptMakeCombinatorial", doc: "Calls AttemptMakeCombinatorial on selected schematic", proc: AttemptMakeCombinatorialCommand, key: $AttemptMakeCombinatorial]; CDCommandOps.RegisterWithMenu[ menu: $OtherProgramMenu, entry: "AttemptSplit", doc: "Calls AttemptSplit on selected icon", proc: AttemptSplitCommand, queue: doQueueAndMark, key: $AttemptSplit]; END. &TestCombinatorial.mesa Copyright Σ 1987 by Xerox Corporation. All rights reversed. Created by Bertrand Serlet August 24, 1987 9:59:31 pm PDT Bertrand Serlet September 17, 1987 3:38:03 pm PDT Checking the Parser Fixing CMOSB! Fast Input of cells from the library Commands Initialization Κ˜™Jšœ<™˜ΡK˜—šΟnœœ˜ Kšœnœ=˜΄Kšœœœ˜—head™š žœœœœœ˜Ašœœ˜Jšœœœ˜,Jšœ,˜,Jšœ˜Jšœ˜—J˜J˜—šžœœœœ˜7šœœœ˜Jšœœ ˜š œœœœœ˜tJšœ:˜>Jšœ˜—Jšœœ˜—K˜K˜—š ž œœœœœ˜/Kšœ!˜'K˜——šœœ™ šž œœœ˜'Jšœœ?˜[Jšœ4˜4Jšœ5œœœ˜HJšœ˜Jšœ˜Jšœ)˜)K˜——™$š ž œœœœœ˜?Jšœ=Οbœ˜EKš œ œœ œœŸœ˜,Kš œœœœœ˜Kš œ œœœœ˜Kš œ œœ œœ˜'Kšœ&œ˜*šž œœœœ˜@Kšœœ(˜DKš œœœ œœ˜!Kšœ!˜!šžœœ˜&Kšœœ$˜.šœœ˜Kšœœœ˜šœœ˜7Kšœœœ œ˜HKšœ˜—KšœŸœ œ˜9šœ˜ šœœ˜šœœ˜Kšœœœ œ˜CKšœœ˜ K˜—šœœ˜K˜)Kšœ œ˜%Kšœ˜Kšœœ˜#K˜—Kšœœ˜—Kšœ˜K˜——K˜—Kšœ1ΟcE˜vKšœœœœ˜Kšœ œ1˜AK˜—Kšœ œŸœ˜/š œœœœœœ˜