WireIconExtrasImpl.mesa
Don Curry May 14, 1987 4:33:34 pm PDT
Last Edited by: Don Curry May 26, 1987 4:25:02 pm PDT
DIRECTORY CD, CDBasics, CDCells, CDCommandOps, CDDirectory, CDInstances, CDLayers, CDOps, CDPanelFonts, CDProperties, CDRects, CDSatellites, CDSequencer, CDTexts, CDViewer, Core, CoreCreate, CoreGeometry, CoreOps, CoreProperties, PopUpMenus, IO, PW, REFBit, Rope, SinixOps, Sisyph, TerminalIO, ViewerClasses, ViewerOps, WireIconExtras;
WireIconExtrasImpl:
CEDAR
PROGRAM
IMPORTS CD, CDBasics, CDCells, CDCommandOps, CDDirectory, CDInstances, CDLayers, CDOps, CDPanelFonts, CDProperties, CDRects, CDSatellites, CDTexts, CDViewer, CoreCreate, CoreGeometry, CoreProperties, CoreOps, IO, PW, REFBit, Rope, SinixOps, Sisyph, TerminalIO, ViewerOps
EXPORTS WireIconExtras =
BEGIN
ROPE: TYPE = Rope.ROPE;
Wire: TYPE = Core.Wire;
ConstructIconCommand:
PROC [comm: CDSequencer.Command] ~ {
schFullName: ROPE;
iconName: ROPE;
icon: CD.Object;
cell: Core.CellType;
selected: CD.Instance;
multiple: BOOL;
cellRef: REF;
sort: BOOL;
[selected, multiple] ← CDOps.SelectedInstance[comm.design];
IF ~IsSingleSelectedAndCell[selected, multiple] THEN RETURN;
schFullName ← CDDirectory.Name[selected.ob, comm.design];
IF schFullName=
NIL
THEN
{TerminalIO.PutF["*** Selected schematic has no name.\n"]; RETURN};
IF NOT Rope.Match["*.sch", schFullName] THEN TerminalIO.PutF["*** Convention for schematics is to suffix them with '.sch'.\n"];
cellRef ← SinixOps.ExtractCDInstance[selected, comm.design, Sisyph.mode].result;
IF
ISTYPE [cellRef, Core.CellType]
THEN cell ← NARROW [cellRef]
ELSE {TerminalIO.PutF["*** Selected cell does not extract to Core CellType\n"]; RETURN};
iconName ← TerminalIO.RequestRope["Type icon short name: "];
IF Rope.IsEmpty[iconName]
THEN iconName ←
IF Rope.Match["*.sch", schFullName]
THEN Rope.Substr[schFullName, 0, Rope.Length[schFullName]-4]
ELSE schFullName;
IF Rope.IsEmpty[schFullName]
THEN
{TerminalIO.PutF["No name provided, no default from schematic.\n"]; RETURN};
IF CDDirectory.Fetch[comm.design, Rope.Cat[iconName, ".icon"]]#
NIL
THEN {
TerminalIO.PutF["*** The icon %g.icon already exists!\n", IO.rope[iconName]];
RETURN};
sort ←
SELECT comm.key
FROM
$ConstructIconCommand => FALSE,
$ConstructIconCommandSort => TRUE,
ENDCASE => ERROR;
icon ← IconFromSchematic[cell, schFullName, iconName, comm.design, sort];
IF icon=NIL THEN RETURN;
CDCells.SetSimplificationTreshhold[cell: icon, val: 30, inPixels: TRUE];
[]Ops.IncludeObjectI[comm.design, icon, comm.pos]};
ConstructRecWireIconCommand:
PROC [comm: CDSequencer.Command] ~ {
type: ROPE ← TerminalIO.RequestRope["Type (eg. Def.Record): "];
wire: Core.Wire ← RecWire[type];
name: ROPE ← type.Substr[type.Index[0,"."]+1];
icon: CD.Object ← ConstructWireIcon[comm, wire, name.Cat[".icon"]];
CDProperties.PutObjectProp[icon, $CodeFor, Rope.Cat["WireIconExtras.RecWire[\"", type, "\"]" ]];
CDProperties.PutObjectProp[icon, Sisyph.mode.extractProcProp, $SisyphExtractNamedWireIcon]};
ConstructDETWireIconCommand:
PROC [comm: CDSequencer.Command] ~ {
type: ROPE ← TerminalIO.RequestRope["Type (eg. Def.Enumerated): "];
pre: ROPE ← TerminalIO.RequestRope["Prefix:"];
suf: ROPE ← TerminalIO.RequestRope["Suffix:"];
wire: Core.Wire ← ETWire[pre, suf, type];
icon: CD.Object ← ConstructWireIcon[comm, wire, Rope.Cat[pre, suf, ".icon"]];
CDProperties.PutObjectProp
[icon, $CodeFor,
IO.PutFR["WireIconExtras.ETWire[\"%g\", \"%g\", \"%g\"]",
IO.rope[pre], IO.rope[suf], IO.rope[type] ]];
CDProperties.PutObjectProp[icon, Sisyph.mode.extractProcProp, $SisyphExtractNamedWireIcon]};
ConstructWireIcon:
PROC [comm: CDSequencer.Command, wire: Core.Wire, name:
ROPE]
RETURNS[icon: CD.Object] ~ {
font: CDTexts.CDFont ← CDPanelFonts.CurrentFont[comm.design];
w: INT ← CDLayers.LayerWidth[comm.design, CD.commentLayer];
fw2: INT ← font.height/2 - w - font.origin.y;
grid: CD.Number ← Grid[comm.design, font];
insts: CD.InstanceList ← NIL;
pinObject: CD.Object ← CDRects.CreateRect[size: [grid/2, w], l: CD.commentLayer];
text: CD.Object;
sat: CD.Instance;
pin: CD.Instance;
maxX: INT ← 0;
FOR i:
INT
IN [0..wire.size)
DO
text ← CDTexts.Create[CoreOps.GetShortWireName[wire[i]], font];
maxX ← MAX[ maxX, CD.InterestSize[text].x];
sat ← CDInstances.NewInst[text, [[x: grid, y: grid*(i+2)-fw2 ]]];
pin ← CDInstances.NewInst[pinObject, [[x: 0, y: grid*(i+2) ]]];
insts ← CONS[sat, CONS[pin, insts]];
CDSatellites.Associate[master: pin, text: sat] ENDLOOP;
text ← CDTexts.Create[CoreOps.GetShortWireName[wire], font];
maxX ← ((MAX[ maxX, CD.InterestSize[text].x] + 3*grid-1)/grid)*grid;
sat ← CDInstances.NewInst[text, [[x: maxX-grid-CD.InterestSize[text].x, y: grid-fw2 ]]];
pin ← CDInstances.NewInst[pinObject, [[x: maxX-grid/2, y: grid ]]];
insts ← CONS[sat, CONS[pin, insts]];
CDSatellites.Associate[master: pin, text: sat];
icon ← PW.CreateCell[instances: insts, ir: [0, 0, maxX, grid*(wire.size+2)+w]];
IF
NOT CDDirectory.Include[comm.design, icon, name]
THEN
{TerminalIO.PutF["*** Directory insertion of %g failed.\n", IO.rope[name]]; ERROR};
CDCells.SetSimplificationTreshhold[cell: icon, val: 30, inPixels: TRUE];
[]Ops.IncludeObjectI[comm.design, icon, comm.pos]};
mark: ATOM ← CoreProperties.RegisterProperty[$TemporaryMark];
IconFromSchematic:
PROC[
schCT: Core.CellType,
schFullName: ROPE,
iconName: ROPE,
design: CD.Design,
sort:
BOOL ]
RETURNS [iconObj: CD.Object] ~ {
L16:
PROC[in:
INT]
RETURNS[
INT] =
{XX: INT ← design.technology.lambda*16; RETURN[((in+XX-1)/XX)*XX]};
font: CDTexts.CDFont ← CDPanelFonts.CurrentFont[design];
grid: CD.Number ← Grid[design, font];
insts: CD.InstanceList ← NIL;
schDeco: CoreGeometry.Decoration ← Sisyph.mode.decoration;
schSize: CD.Position ← CD.InterestSize[CoreGeometry.GetObject[schDeco, schCT]];
iconSize: CD.Position;
hChans: INT;
vChans: INT;
iNmOb: CD.Object ← CDTexts.Create[iconName, font];
pins: ARRAY CoreGeometry.Side OF CD.InstanceList ← ALL[NIL];
cnt: ARRAY CoreGeometry.Side OF NAT ← ALL[0];
smax: ARRAY CoreGeometry.Side OF INT ← ALL[16];
w: INT ← CDLayers.LayerWidth[design, CD.commentLayer];
fw2: INT ← font.height/2 - w - font.origin.y;
iconFullName: ROPE ← iconName.Cat[".icon"];
pinObject: CD.Object;
horWall: CD.Object;
verWall: CD.Object;
clearMark: CoreOps.EachWireProc = {CoreProperties.PutWireProp[wire, mark, NIL]};
FOR side: CoreGeometry.Side
IN CoreGeometry.Side
DO
eachSortedPin: CoreGeometry.EachSortedPinProc = {
IF CoreProperties.GetWireProp[wire, mark]=
NIL
THEN {
text: CD.Object ← CDTexts.Create[CoreOps.GetShortWireName[wire], font];
inst: CD.Instance ← CDInstances.NewInst[text];
CoreProperties.PutWireProp[wire, mark, mark];
pins[side] ← CONS[inst, pins[side]];
cnt[side] ← cnt[side] + 1;
smax[side] ← MAX[ smax[side], CD.InterestSize[text].x] }};
[] ← CoreGeometry.EnumerateSortedSides[schDeco, schCT, side, eachSortedPin];
[]𡤌oreOps.VisitWire[schCT.public, clearMark];
ENDLOOP;
IF sort
THEN
FOR side: CoreGeometry.Side
IN CoreGeometry.Side
DO
DO
ok: BOOL ← TRUE;
FOR insts:
CD.InstanceList ← pins[side], insts.rest
WHILE insts#
NIL
AND insts.rest#
NIL
DO
TwoObj: TYPE = RECORD[ob1, ob2: CD.Object];
r1: ROPE ← NARROW[insts.first.ob.specific, CDTexts.TextSpecific].text;
r2: ROPE ← NARROW[insts.rest.first.ob.specific, CDTexts.TextSpecific].text;
SELECT Rope.Compare[r1, r2]
FROM
less => LOOP;
equal => ERROR; ENDCASE;
[insts.first.ob, insts.rest.first.ob] ← TwoObj[insts.rest.first.ob, insts.first.ob];
ok←FALSE;
ENDLOOP;
IF ok THEN EXIT; ENDLOOP; ENDLOOP;
hChans ← MAX[cnt[left], cnt[right]];
vChans ← MAX[cnt[top], cnt[bottom]];
iconSize.x← L16[(vChans+4)*grid + 2*MAX[smax[left], smax[right],CD.InterestSize[iNmOb].x]];
iconSize.y← L16[(hChans+4)*grid + 2*MAX[smax[top], smax[bottom]]];
IF schSize.x > schSize.y
THEN iconSize.x ← L16[MAX[iconSize.x, (iconSize.y*schSize.x + schSize.y/2) /schSize.y]]
ELSE iconSize.y ← L16[MAX[iconSize.y, (iconSize.x*schSize.y + schSize.x/2) /schSize.x]];
pinObject ← CDRects.CreateRect[size: [grid/2, w], l: CD.commentLayer];
horWall ← CDRects.CreateRect[size: [iconSize.x, w], l: CD.commentLayer];
verWall ← CDRects.CreateRect[size: [w, iconSize.y], l: CD.commentLayer];
FOR side: CoreGeometry.Side
DECREASING
IN CoreGeometry.Side
DO
tr:
CD.Transformation ←
SELECT side
FROM
top => [ [iconSize.x/2 - vChans*grid/2, iconSize.y], rotate270 ],
bottom => [ [iconSize.x/2 - vChans*grid/2, 0], rotate90 ],
left => [ [0, iconSize.y/2 - hChans*grid/2], original],
right => [ [iconSize.x, iconSize.y/2 - hChans*grid/2], rotate180],
ENDCASE => ERROR;
index: INT ← (cnt[side]+(SELECT side FROM top,bottom=>vChans, ENDCASE => hChans)+1)/2;
FOR temp:
CD.InstanceList ← pins[side], temp.rest
WHILE temp#
NIL
DO
pin, sat: CD.Instance;
index ← index-1;
insts ← CONS[(sat ← temp.first), insts];
insts ← CONS[(pin ← CDInstances.NewInst[pinObject]), insts];
sat.trans.orient ← pin.trans.orient ← tr.orient;
CDSatellites.Associate[master: pin, text: sat];
SELECT side
FROM
top => {
pin.trans.off ← CDBasics.AddPoints[tr.off, [index*grid+0, 0 ]];
sat.trans.off ← CDBasics.AddPoints[tr.off, [index*grid+0-fw2, -grid ]]};
bottom => {
pin.trans.off ← CDBasics.AddPoints[tr.off, [index*grid+w, 0 ]];
sat.trans.off ← CDBasics.AddPoints[tr.off, [index*grid+w+fw2, +grid ]]};
left => {
pin.trans.off ← CDBasics.AddPoints[tr.off, [0, index*grid+0 ]];
sat.trans.off ← CDBasics.AddPoints[tr.off, [+grid, index*grid+0-fw2 ]]};
right => {
pin.trans.off ← CDBasics.AddPoints[tr.off, [0, index*grid+w ]];
sat.trans.off ← CDBasics.AddPoints[tr.off, [-grid, index*grid+w+fw2 ]]};
ENDCASE => ERROR;
ENDLOOP;
ENDLOOP;
insts ← CONS[CDInstances.NewInst[horWall, [off:[0, 0 ]]], insts];
CDProperties.PutInstanceProp[insts.first, Sisyph.mode.extractProcProp, $ExtractNull];
insts ← CONS[CDInstances.NewInst[horWall, [off:[0, iconSize.y-w ]]], insts];
CDProperties.PutInstanceProp[insts.first, Sisyph.mode.extractProcProp, $ExtractNull];
insts ← CONS[CDInstances.NewInst[verWall, [off:[0, 0 ]]], insts];
CDProperties.PutInstanceProp[insts.first, Sisyph.mode.extractProcProp, $ExtractNull];
insts ← CONS[CDInstances.NewInst[verWall, [off:[iconSize.x-w, 0 ]]], insts];
CDProperties.PutInstanceProp[insts.first, Sisyph.mode.extractProcProp, $ExtractNull];
insts ← CONS[CDInstances.NewInst[iNmOb, [off:[grid, iconSize.y-2*grid ]]], insts];
iconObj ← PW.CreateCell[instances: insts];
IF
NOT CDDirectory.Include[design, iconObj, iconFullName]
THEN
{TerminalIO.PutF["*** Directory insertion of %g failed.\n", IO.rope[iconFullName]]; ERROR};
CDProperties.PutObjectProp[iconObj, Sisyph.mode.extractProcProp, $SisyphExtractCellIcon];
CDProperties.PutObjectProp[iconObj, $IconFor, schFullName]};
Grid:
PROC[design:
CD.Design, font: CDTexts.CDFont ←
NIL]
RETURNS[grid:
NAT] = {
viewers: CDViewer.ViewerList ← CDViewer.ViewersOf[design];
IF viewers#
NIL
THEN
WITH ViewerOps.GetViewer[viewers.first, $Grid]
SELECT
FROM
rgrid: REF CD.Number => grid ← rgrid^; ENDCASE => NULL
ELSE grid ← design.technology.lambda*2;
IF font#NIL THEN WHILE font.height > (grid*4)/3 DO grid ← grid*2 ENDLOOP};
SisyphExtractAndStaticLeafConnections: PROC [comm: CDSequencer.Command] = {
root, cellType: Core.CellType;
cutSet: CoreFlat.CutSet;
[root: root, cell: cellType] ← SinixOps.SelectedCellType[comm.design, Sisyph.mode];
IF root=NIL THEN RETURN; -- Extraction ended in error, message already printed
TerminalIO.PutF["\nStatic checking (Leaf connections) %g.\n",
IO.rope[CoreOps.GetCellTypeName[cellType]]];
cutSet ← IF CoreProperties.GetCellTypeProp[cellType, Static.staticCutSetProp]=NIL
THEN CoreFlat.CreateCutSet[labels: LIST["Logic", "LogicMacro"]]
ELSE NIL;
Static.CountLeafConnections[cellType, Static.CheckCount, cutSet];
TerminalIO.PutF["Finished static checking %g.\n",
IO.rope[CoreOps.GetCellTypeName[cellType]]]};
LayoutStructureAndDrcCheckOfSelectedIcons: PROC [comm: CDSequencer.Command] = {
count: INT ← 0;
drcErrors: INT ← 0;
errs: INT ← 0;
result: REF;
badguys: LIST OF ROPE;
objName: ROPE;
errorMsg: ROPE;
errorType: ATOM;
sourceCT: Core.CellType;
indirectOb: CD.Object;
directOb: CD.Object;
directCT: Core.CellType;
drcAtomDesign: ATOM ← DesignRules.FetchRulesID[comm.design];
drcAtom: ATOM ← IF drcAtomDesign#NIL THEN drcAtomDesign ELSE $VTI;
rules: DesignRules.Rules ← DesignRules.GetRuleSet[drcAtom];
tech: Drc.Tech ← DrcCMOSB.NewTechnology[DrcCMOSB.cMosBcompleteKey, rules];
IF comm.design.actual.rest#NIL THEN
{TerminalIO.PutF["Can't handle pushed in cell\n"]; RETURN};
TerminalIO.PutF["Using %g design rules\n", IO.atom[drcAtom]];
FOR w: CD.InstanceList ← CDOps.InstList[comm.design], w.rest WHILE w#NIL DO
IF NOT w.first.selected THEN LOOP;
objName ← CDDirectory.Name[w.first.ob, comm.design];
IF Rope.Find[objName, ".icon"]=-1 THEN
{TerminalIO.PutF["%g is not an icon.\n", IO.rope[objName]]; LOOP};
result ← SinixOps.ExtractCDInstance[w.first, comm.design, Sisyph.mode].result;
IF result=NIL OR NOT ISTYPE[result, Core.CellType] THEN
{TerminalIO.PutF["%g does not extract as a cell.\n", IO.rope[objName]]; LOOP};
sourceCT ← NARROW[result];
errorType ← NIL;
indirectOb ← PWCore.Layout[sourceCT !
PWCore.Error => {errorType ← type; errorMsg ← message; CONTINUE}];
IF errorType#NIL THEN {
TerminalIO.PutF["Cell for %g has Layout %g ERROR\n %g.\n",
IO.rope[objName], IO.atom[errorType], IO.rope[errorMsg]]; LOOP};
PWCoreLichen.Compare[sourceCT];
TerminalIO.PutF["Done extracting and comparing.\n"];
directOb ← CDDirectory.Expand1[indirectOb].new;
IF directOb=NIL THEN ERROR;
directCT ← NARROW[Sinix.Extract[directOb, PWCore.extractMode].result];
IF directCT=NIL THEN ERROR;
errs ← Drc.CheckDesignRules[directCT, CoreOps.CopyWire[directCT.public], tech, TRUE, NIL, PWCore.extractMode.decoration];
TerminalIO.PutF[" %2g errors in %g.\n", IO.int[errs],
IO.rope[CoreOps.GetCellTypeName[directCT]]];
IF errs#0 THEN {
[]ug.Draw[directOb, comm.design.technology, objName];
badguys ← CONS[objName, badguys]};
drcErrors ← drcErrors+errs;
count ← count+1;
ENDLOOP;
TerminalIO.PutF["%2g drc errors in %g cells.\n", IO.int[drcErrors], IO.int[count]];
FOR badguys ← badguys, badguys.rest WHILE badguys#NIL DO
TerminalIO.PutF[" %g\n", IO.rope[badguys.first]]; ENDLOOP};
AddProp: PROC [comm: CDSequencer.Command] ~ {
selected: CD.Instance; multiple: BOOL;
[selected, multiple] ← CDOps.SelectedInstance[comm.design];
IF ~IsSingleSelected[selected, multiple] THEN RETURN;
IF selected.ob.immutable THEN
{TerminalIO.PutRope["*** Can't modify an immutable object\n"]; RETURN};
CDProperties.PutObjectProp[selected.ob, Sisyph.mode.extractProcProp, (SELECT comm.key FROM
$AWireAddProp => $SisyphExtractUnNamedWireIcon,
$PWireAddProp => $SisyphExtractNamedWireIcon,
ENDCASE => ERROR)]};
DelProp: PROC [comm: CDSequencer.Command] ~ {
selected: CD.Instance; multiple: BOOL;
[selected, multiple] ← CDOps.SelectedInstance[comm.design];
IF ~IsSingleSelected[selected, multiple] THEN RETURN;
IF selected.ob.immutable THEN
{TerminalIO.PutRope["*** Can't modify an immutable object\n"]; RETURN};
CDProperties.PutObjectProp[selected.ob, Sisyph.mode.extractProcProp, NIL]};
IsSingleSelected:
PROC [selected:
CD.Instance, multiple:
BOOL]
RETURNS [
BOOL] = {
IF selected=
NIL
THEN
{TerminalIO.PutF["*** No current selection--can't do it.\n"]; RETURN[FALSE]};
IF multiple
THEN
{TerminalIO.PutF["*** Multiple instances selected--can't do it.\n"]; RETURN[FALSE]};
RETURN[TRUE]};
IsSingleSelectedAndCell:
PROC [selected:
CD.Instance, multiple:
BOOL]
RETURNS [
BOOL] = {
IF ~IsSingleSelected[selected, multiple] THEN RETURN [FALSE];
IF ~CDCells.IsCell[selected.ob]
THEN
{TerminalIO.PutF["*** Selected instance is not a cell—can't do it.\n"]; RETURN[FALSE]};
RETURN[TRUE]};
GridComposer:
PW.GeneratorProc = {
name: ROPE;
grid: INT ← Grid[design];
n: INT ← TerminalIO.RequestInt["Size of the composer? "];
w: INT ← CDLayers.LayerWidth[design, CD.commentLayer];
IF n<1 THEN {TerminalIO.PutF["*** Invalid parameter.\n"]; RETURN};
name ← IO.PutFR["Grid%gW%gComposer[%g].icon", IO.int[grid], IO.int[w], IO.int[n]];
ob ← CDDirectory.Fetch[design, name].object;
IF ob=
NIL
THEN {
ob ← GridComposeObj[design, grid, n].obj;
[] ← CDDirectory.Include[design, ob, name]}};
GridComposeWire:
PUBLIC
PROC[n:
NAT]
RETURNS [wire: Wire] ~ {
wire ← CoreOps.CreateWires[n, "w"];
FOR ii:
INT
IN [0..n)
DO wire[ii] ← CoreOps.CreateWires[0, IO.PutFR["w%g", IO.int[ii]]] ENDLOOP};
GridComposeObj:
PROC [design:
CD.Design, grid, n:
INT]
RETURNS [obj: CD.Object] = {
Add:
PROC[name:
ROPE ←
NIL, size, pos:
CD.Position] = {
list ← CONS[CDInstances.NewInst[CDRects.CreateRect[size, CD.commentLayer], [pos]], list];
IF name#
NIL
THEN {
names: LIST OF ROPE ← LIST[name];
CDProperties.PutInstanceProp[list.first, Sisyph.expressionsProp, names]}};
list: CD.InstanceList ← NIL;
w: INT ← CDLayers.LayerWidth[design, CD.commentLayer];
l: INT ← MAX[w, grid/4];
Add[size:[2*l, grid*2*n+w], pos:[l, 0]];
CDProperties.PutInstanceProp[list.first, Sisyph.mode.extractProcProp, $ExtractNull];
Add[name: "w", size:[l, w], pos:[0, grid]];
FOR ii:
INT
IN [0..n)
DO
Add[name: IO.PutFR["w%g", IO.int[ii]], size:[l, w], pos:[3*l, (2*ii+1)*grid]] ENDLOOP;
obj ← PW.CreateCell[instances: list];
CDProperties.PutObjectProp
[obj, $CodeFor, IO.PutFR["WireIconExtras.GridComposeWire[%g]", IO.int[n]]];
CDProperties.PutObjectProp[obj, Sisyph.mode.extractProcProp, $SisyphExtractUnNamedWireIcon];
CDCells.SetSimplificationTreshhold[obj, 20]};
RecWire:
PUBLIC
PROC[rec:
ROPE, dual:
BOOL ←
FALSE]
RETURNS[wire: Wire] =
{RETURN[RefWire[REFBit.NEWFromName[rec], rec.Substr[rec.Index[0,"."]+1]]]};
RefWire:
PUBLIC
PROC[ref:
REF, name:
ROPE, dual:
BOOL ←
FALSE]
RETURNS[wire: Wire] = {
ZeroIfOne: PROC[s: INT] RETURNS[INT] = {RETURN[IF s=1 THEN 0 ELSE s]};
fieldForm: REFBit.Format ← REFBit.Desc[ref].fieldForm;
wires: LIST OF Wire ← NIL;
temp: LIST OF Wire ← NIL;
FOR field:
INT
IN[0..fieldForm.size)
DO
fieldName: ROPE ← BitRopeToSigRope[fieldForm[field].name];
SELECT fieldForm[field].bitSize
FROM
1 =>
{wires ← CONS[CoreCreate.Seq[fieldName, IF dual THEN 2 ELSE 0], wires]};
>1 => {
fieldWire: Wire ← CoreOps.CreateWires[fieldForm[field].bitSize, fieldName];
wires ← CONS[fieldWire, wires];
FOR bit:
INT
IN[0..fieldWire.size)
DO
fieldWire[bit] ← CoreCreate.Seq[NIL, IF dual THEN 2 ELSE 0] ENDLOOP};
ENDCASE => ERROR;
ENDLOOP;
temp ← wires; wires ← NIL;
FOR temp ← temp, temp.rest WHILE temp#NIL DO wires ← CONS[temp.first, wires] ENDLOOP;
wire ← CoreOps.CreateWire[wires, name]};
ETWire:
PUBLIC
PROC[prefix, suffix, type:
ROPE]
RETURNS[wire: Wire] = {
bitName, bitNameInv: ROPE;
refREF: REF ← REFBit.NEWFromName[type];
format: REFBit.Format ← REFBit.Desc[refREF].bitForm;
wire ← CoreOps.CreateWires[MAX[2, format.size], prefix.Cat[suffix]];
FOR i:
INT
IN[0..format.size)
DO
bitName ← BitRopeToSigRope[format[i].name];
bitNameInv ← BitRopeToSigRope[format[i].nameInv];
IF ((format.size#1) = (i+1=format.size)) = (bitName#NIL) THEN ERROR;
IF ((format.size#1) = (bitNameInv#NIL)) = (bitName#NIL) THEN ERROR;
IF bitName=NIL THEN bitName ← bitNameInv;
wire[i] ← CoreOps.CreateWires[0, prefix.Cat[bitName, suffix]];
IF format.size=1
THEN
wire[1] ← CoreOps.CreateWires[0, prefix.Cat[bitNameInv, suffix]];
ENDLOOP};
BitRopeToSigRope:
PROC [name:
ROPE]
RETURNS [
ROPE] ~ {
Cap:
PROC[rope:
ROPE, idx:
INT]
RETURNS[
ROPE] = {
char: CHAR ← rope.Fetch[idx+1];
IF char IN ['a..'z] THEN char ← char + LOOPHOLE['A - 'a];
RETURN[IO.PutFR["%g", IO.char[char]]]};
IF name = NIL THEN RETURN[NIL];
name ← Rope.Cat[Cap[name, -1], name.Substr[1]];
DO
-- remove peiods and Capitalize next letters until end or next char is number
index: INT ← name.Index[0, "."];
IF index+1 >= name.Length[] OR name.Fetch[index+1] IN ['0..'9] THEN RETURN[name];
name ← Rope.Cat[name.Substr[0,index], Cap[name, index], name.Substr[index+2]];
ENDLOOP };
CDCommandOps.RegisterWithMenu[
menu: $SisyphIconMenu,
entry: "Create Cell Icon from schematics - Grid 2",
doc: "Pins on grid 2. Overall size in units of 16.",
key: $ConstructIconCommand,
proc: ConstructIconCommand ];
CDCommandOps.RegisterWithMenu[
menu: $SisyphIconMenu,
entry: "Create Cell Icon from schematics - Grid 2 - Sorted",
doc: "Pins on grid 2. Overall size in units of 16. Names sorted.",
key: $ConstructIconCommandSort,
proc: ConstructIconCommand ];
CDCommandOps.RegisterWithMenu[
menu: $SisyphIconMenu,
entry: "Create Wire Icon from Cedar Record Type",
doc: "RECORDs with field types such as: RECORD, INT, BOOL, enumerated, subranges",
key: $ConstructRecWireIconCommand,
proc: ConstructRecWireIconCommand ];
CDCommandOps.RegisterWithMenu[
menu: $SisyphIconMenu,
entry: "Create Wire Icon from Cedar Enumerated Type",
doc: "Decoded Enumerated types encoded as: 0, 3, 5, 9, 17 etc.",
key: $ConstructDETWireIconCommand,
proc: ConstructDETWireIconCommand ];
menu: PopUpMenus.Menu ← CDPopUpMenus.MakeMenu[
key: $AWireMenu,
header: "Sisyph: Anonymous Wire extraction",
doc: "Change Wire extraction property" ];
CDCommandOps.RegisterWithMenu[
menu: $OtherProgramMenu,
entry: "Sisyph: Anonymous/Public Wire",
doc: "Change Anonymous or Public Wire extraction property",
key: $AWireMenu,
proc: NIL];
CDCommandOps.RegisterWithMenu[
menu: $AWireMenu,
entry: "Make Wire Anonymous",
doc: "Forces Sisyph extraction to return a wire with all names removed. In the case of cell extraction, the result is the anonymous public.",
key: $AWireAddProp,
proc: AddProp];
CDCommandOps.RegisterWithMenu[
menu: $AWireMenu,
entry: "Make Wire Public",
doc: "Forces Sisyph extraction to return a wire even when the result would normally be a cell.",
key: $PWireAddProp,
proc: AddProp];
CDCommandOps.RegisterWithMenu[
menu: $AWireMenu,
entry: "Default Wire",
doc: NIL,
key: $AWireDelProp,
proc: DelProp];
CDCommandOps.RegisterWithMenu[
menu: $OtherProgramMenu,
entry: "Sisyph Extract And Static (Leaf Connections)",
doc: "Sisyph Extract And Static (Leaf Connections)",
key: $SisyphExtractAndStaticLeafConnections,
proc: SisyphExtractAndStaticLeafConnections];
CDCommandOps.RegisterWithMenu[
menu: $OtherProgramMenu,
entry: "Library Layout Check",
doc: "Lichen structure check and design rule check of the layouts of all selected icons",
key: $LayoutStructureAndDrcCheckOfSelectedIcons,
proc: LayoutStructureAndDrcCheckOfSelectedIcons];
PW.RegisterGenerator[GridComposer, "Composer - variable grid and width"];
END.