<> <> <> <> <<>> DIRECTORY CD, CDCommandOps, CDProperties, CDSequencer, Combinatorial, Core, CoreClasses, CoreCreate, CoreDirectory, CoreGeometry, CoreOps, CoreProperties, GList, IO, PWCore, Rope, RopeList, Sinix, SinixOps, Sisyph, SymTab, TerminalIO; TestCombinatorial: CEDAR PROGRAM IMPORTS CDCommandOps, CDProperties, Combinatorial, CoreCreate, CoreDirectory, CoreGeometry, CoreOps, CoreProperties, GList, IO, PWCore, 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]]; CoreProperties.PutWireProp[out, $Output, 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] = { iconFor: ROPE; object: CD.Object; root, cellType, record: Core.CellType; rct: CoreClasses.RecordCellType; [root: root, cell: cellType] _ SinixOps.SelectedCellType[command.design, Sisyph.mode]; IF root=NIL THEN RETURN; TerminalIO.PutF["AttemptSplit for %g.\n", IO.rope[CoreOps.GetCellTypeName[cellType]]]; record _ SplitCombinatorial[cellType, HasNoLayout]; rct _ NARROW [record.data]; object _ CoreGeometry.GetObject[Sisyph.mode.decoration, cellType]; TerminalIO.PutF["AttemptSplit done for %g: combinatorial cell with %g outputs and %g non combinatorial cells.\n", IO.rope[CoreOps.GetCellTypeName[cellType]], IO.int[GList.Length[GetTypedWires[rct[0].type, output]]], IO.int[rct.size-1]]; iconFor _ NARROW [CDProperties.GetObjectProp[object, $IconFor]]; IF iconFor=NIL THEN ERROR; Sinix.FlushCache[object]; CDProperties.PutObjectProp[object, $IconFor, NIL]; CDProperties.PutObjectProp[object, $CodeFor, IO.PutFR["Combinatorial.SplitCombinatorial[Sisyph.ES[\"%g\", cx], TestCombinatorial.HasNoLayout]", IO.rope[iconFor]]]; }; HasNoLayout: PROC [ct: Core.CellType] RETURNS [BOOL] = { RETURN [PWCore.GetLayoutAtom[ct]=NIL AND CoreProperties.GetCellTypeProp[ct, $FlattenForCombinatorial]=NIL AND CoreProperties.GetCellTypeProp[ct, $RoseBehave]=NIL]; }; <> 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.