SchImpl.mesa
Copyright © 1986 by Xerox Corporation. All rights reserved.
Louis Monier February 13, 1986 3:46:07 pm PST
Barth, April 17, 1986 11:15:55 am PST
DIRECTORY AMBridge, AMTypes, CD, CDDirectory, Core, CoreCreate, CoreOps, IO, Ports, PWCore, Rope, Rosemary, Sinix, Sisyph, Sch, SymTab, TerminalIO;
SchImpl: CEDAR PROGRAM
IMPORTS AMBridge, CDDirectory, CoreCreate, CoreOps, IO, PWCore, Rope, Sinix, Sisyph, SymTab, TerminalIO
EXPORTS Sch
= BEGIN OPEN Sch;
iconRope: ROPE ← ".icon";
schRope: ROPE ← ".sch";
Sch: PUBLIC PROC [cx: Context, name: ROPE] = {
CheckObjectName[cx, Rope.Cat[name, schRope]];
Sisyph.Eval[cx, "coreProps ← CoreProperties.PutProp[coreProps, $PWCoreSourceDesign, design]"];
};
Icon: PUBLIC PROC [cx: Context, name: ROPE] RETURNS [ct: CellType] = {
CheckObjectName[cx, Rope.Cat[name, iconRope]];
ct ← Sisyph.ExtractSchematicByName[Rope.Cat[name, schRope], cx];
};
CheckObjectName: PUBLIC PROC [cx: Context, assertedName: ROPE] = {
objectName: ROPE ← CDDirectory.Name[GetObj[cx]];
IF NOT Rope.Equal[objectName, assertedName] THEN TerminalIO.WriteF["Warning: ChipNDale directory name %g does not correspond to asserted name %g", IO.refAny[objectName], IO.refAny[assertedName]];
};
Orient: PUBLIC PROC [cx: Context, atom: ATOM] RETURNS [ct: CellType] = {
objectName: ROPE ← CDDirectory.Name[GetObj[cx]];
baseCell: Core.CellType ← Sisyph.ExtractSchematicByName[objectName, cx];
ct ← PWCore.RotateCellType[baseCell, atom];
Sisyph.Eval[cx, "coreProps ← NIL"];
};
CSeq: PUBLIC PROC [cx: Sisyph.Context, count: NAT, dir: XorY] RETURNS [ct: Core.CellType] = {
sWires, fsWires: LIST OF CoreCreate.WR;
EachWire: CoreOps.EachWireProc = {
dirInst: XorY;
insts: LIST OF CD.Instance ← Sinix.GetPinsProp[Sisyph.sisyphMode, wire];
IF insts=NIL THEN RETURN; -- wires with pins only
dirInst ← SELECT insts.first.orientation FROM
0, 1, 4, 5 => X, -- vertical wire
2, 3, 6, 7 => Y,
ENDCASE => ERROR;
IF (dirInst=X AND (dir=X OR dir=RX)) OR (dirInst=Y AND (dir=Y OR dir=RY)) THEN IF wire.size=0 THEN sWires ← CONS[wire, sWires] ELSE fsWires ← CONS[wire, fsWires];
subWires ← FALSE;
};
objectName: ROPE ← CDDirectory.Name[GetObj[cx]];
baseCell: Core.CellType ← Sisyph.ExtractSchematicByName[objectName, cx];
[] ← CoreOps.VisitWire[baseCell.public, EachWire];
ct ← CoreCreate.SequenceCell[
name: Rope.Cat[objectName, "Seq", SELECT dir FROM
X => "X", Y => "Y", RX => "RX", RY => "RY", ENDCASE => ERROR],
baseCell: baseCell,
count: count,
sequencePorts: CoreCreate.WireList[sWires],
flatSequencePorts: CoreCreate.WireList[fsWires]
];
SELECT dir FROM
X => PWCore.SetArrayX[ct];
Y => PWCore.SetArrayY[ct];
RX => PWCore.SetLayout[ct, $ReverseArrayX];
RY => PWCore.SetLayout[ct, $ReverseArrayY];
ENDCASE => ERROR;
Sisyph.Eval[cx, "coreProps ← NIL"];
};
WSeq: PUBLIC PROC [name: ROPENIL, size: NAT] RETURNS [wire: Wire] = {
wire ← CoreCreate.Seq[name, size];
};
WRange: PUBLIC PROC [name: ROPE, start: NAT, size: NAT] RETURNS [wire: Core.Wire] = {
wire ← CoreCreate.Seq[size: size];
FOR i: NAT IN [0..size) DO
[] ← CoreOps.SetShortWireName[wire[i], IO.PutFR["%g[%g]", IO.rope[name], IO.int[start+i]]];
ENDLOOP;
};
WIndex: PUBLIC PROC [name: ROPE, index: NAT] RETURNS [wire: Core.Wire] = {
wire ← CoreOps.CreateWire[name: name];
[] ← CoreOps.SetShortWireName[wire, IO.PutFR["%g[%g]", IO.rope[name], IO.int[index]]];
};
InitPort: PUBLIC PROC [cx: Context, initType: Ports.PortType ← b, initDrive: Ports.Drive ← none] = {
Sisyph.Eval[cx, "coreInstProps ← CoreProperties.PutProp[coreInstProps, $PortData,
NEW[Ports.PortDataRec ← [
type: initType,
drive: initDrive]]]"];
};
TSize: PUBLIC PROC [cx: Context, size: Rosemary.TransistorSize] = {
Sisyph.Eval[cx, "coreInstProps ← CoreProperties.PutProp[coreInstProps, $RoseTransistorSize,
NEW[Ports.Drive ← size]]"];
};
SetWire: PUBLIC PROC [cx: Context, level: Ports.Level ← L, size: Rosemary.WireSize ← charge] = {
Sisyph.Eval[cx, "coreInstProps ← CoreProperties.PutProp[coreInstProps, $RoseWireData,
NEW[Rosemary.RoseWireDataRec ← [level, size]]]"];
};
GetObj: PROC [cx: Context] RETURNS [CD.Object] = {
found: BOOL;
ref: SymTab.Val;
[found, ref] ← SymTab.Fetch[cx, Sisyph.cdObjRope];
IF found
THEN RETURN [NARROW [RefFromTV[ref], REF CD.Object]^]
ELSE ERROR
};
RefFromTV: PROC [tv: REF] RETURNS [REF] = {
IF tv=NIL THEN RETURN [NIL];
IF ~ISTYPE [tv, AMTypes.TV] THEN ERROR;
TRUSTED {RETURN [AMBridge.SomeRefFromTV[tv]]};
};
END.