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
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;
Checking the Parser
ToLisps: PROC [params: ParseTrees] RETURNS [rope: ROPENIL] = {
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]]];
};
Fixing CMOSB!
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 [BOOLTRUE]];
PutOutput[out, expr];
BindCombinatorial[cell];
CheckTransistorsAgainstExpressions[cell];
};
Fast Input of cells from the library
CMOSBCell: PUBLIC PROC [rope: ROPE] RETURNS [Core.CellType] = {
library: CoreDirectory.Library ← CoreDirectory.FetchLibrary["CMOSB"];
publics: LIST OF CoreCreate.WRLIST ["X"];
inputs: LIST OF ROPENIL;
globals: LIST OF ROPENIL;
auxiliary: LIST OF CoreCreate.WRNIL;
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.PANIL;
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
]];
};
Commands
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: ROPENARROW [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;
};
Initialization
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.