SimpleTest:
CEDAR
PROGRAM
IMPORTS IO, NumTypes, RoseCreate
={OPEN RoseCreate, RoseTypes;
bpw: NAT = Basics.bitsPerWord;
bps: NAT = SwitchTypes.bitsPerSwitchVal;
InverterSimpleIORef: TYPE = REF InverterSimpleIORec;
InverterSimpleIORec: TYPE = RECORD [fil: [0 .. 16384) ← 0, in, out: BOOL];
InverterSwitchIORef: TYPE = REF InverterSwitchIORec;
InverterSwitchIORec: TYPE = RECORD [in, out: SwitchTypes.SwitchVal];
InverterDriveRef: TYPE = REF InverterDriveRec;
InverterDriveRec:
TYPE =
RECORD [
tag: DriveTagType,
s: PACKED ARRAY InverterPort OF DriveLevel];
InverterPort: TYPE = MACHINE DEPENDENT {in, out, (3)};
CreateInverterIO:
PROC [ct: CellType, switch:
BOOL]
RETURNS [ioAsAny:
REF
ANY]
--IOCreator-- =
{ioAsAny ← IF switch THEN NEW[InverterSwitchIORec] ELSE NEW[InverterSimpleIORec]};
CreateInverterDrive:
PROC [ct: CellType]
RETURNS [driveAsAny:
REF
ANY]
--DriveCreator-- =
{driveAsAny ← NEW[InverterDriveRec]};
InitializeInverter:
PROC [cell: Cell]
--Initializer-- = {
drive: InverterDriveRef ← NARROW[cell.realCellStuff.newDriveAsAny];
drive.s[in] ← ignore;
drive.s[out] ← drive;
};
EvalInverter:
PROC [cell: Cell, perturb:
PROC [portIndex: PortIndex]]
--SimpleEval-- = {
newIO: InverterSimpleIORef ← NARROW[cell.realCellStuff.newIO];
newIO.out ← NOT newIO.in;
};
inverterPorts: Ports ← NEW [PortsRep[2]];
RegisterInverter:
PROC = {
inverterPorts[0] ← [
simple: [0, 14, 1],
switch: [0, 0, bps],
name: "in",
type: NumTypes.boolType,
input: TRUE];
inverterPorts[1] ← [
simple: [0, 15, 1],
switch: [1, 0, bps],
name: "out",
type: NumTypes.boolType,
output: TRUE];
[] ← RegisterCellType[
name: "Inverter",
ioCreator: CreateInverterIO,
driveCreator: CreateInverterDrive,
initializer: InitializeInverter,
evals: [EvalSimple: EvalInverter],
ports: inverterPorts
];
};
DriverSimpleIORef: TYPE = REF DriverSimpleIORec;
DriverSimpleIORec:
TYPE =
RECORD [
in, out: CARDINAL,
str: [0 .. 16)];
DriverSwitchIORef: TYPE = REF DriverSwitchIORec;
DriverSwitchIORec:
TYPE =
RECORD [
in, out: ARRAY [0 .. 16) OF SwitchTypes.SwitchVal,
str: ARRAY [0 .. 4) OF SwitchTypes.SwitchVal];
DriverDriveRef: TYPE = REF DriverDriveRec;
DriverDriveRec:
TYPE =
RECORD [
tag: DriveTagType,
s: PACKED ARRAY DriverPort OF DriveLevel];
DriverPort: TYPE = MACHINE DEPENDENT {in, out, str, (3)};
CreateDriverIO:
PROC [ct: CellType, switch:
BOOL]
RETURNS [ioAsAny:
REF
ANY] =
{ioAsAny ← IF switch THEN NEW [DriverSwitchIORec] ELSE NEW [DriverSimpleIORec]};
CreateDriverDrive:
PROC [ct: CellType]
RETURNS [driveAsAny:
REF
ANY] =
{driveAsAny ← NEW [DriverDriveRec]};
EvalDriver:
PROC [cell: Cell, perturb:
PROC [portIndex: PortIndex]]
--SimpleEval-- = {
io: DriverSimpleIORef ← NARROW[cell.realCellStuff.newIO];
drive: DriverDriveRef ← NARROW[cell.realCellStuff.newDriveAsAny];
drive.s[out] ← VAL[io.str];
io.out ← io.in;
};
driverPorts: Ports ← NEW [PortsRep[3]];
RegisterDriver:
PROC = {
driverPorts[0] ← [
simple: [0, 0, 1*bpw],
switch: [0, 0, 16*bpw],
name: "in",
type: NumTypes.NumType[16],
input: TRUE
];
driverPorts[1] ← [
simple: [1, 0, 1*bpw],
switch: [16, 0, 16*bpw],
name: "out",
type: NumTypes.NumType[16],
output: TRUE
];
driverPorts[2] ← [
simple: [2, 12, 4],
switch: [32, 0, 4*bpw],
name: "str",
type: NumTypes.NumType[4],
input: TRUE
];
[] ← RegisterCellType[
name: "Driver",
ioCreator: CreateDriverIO,
driveCreator: CreateDriverDrive,
evals: [EvalSimple: EvalDriver],
ports: driverPorts
];
};
IncrementerSimpleIORef: TYPE = REF IncrementerSimpleIORec;
IncrementerSimpleIORec:
TYPE =
RECORD [
in, out: CARDINAL];
IncrementerSwitchIORef: TYPE = REF IncrementerSwitchIORec;
IncrementerSwitchIORec:
TYPE =
RECORD [
in, out: ARRAY [0 .. 16) OF SwitchTypes.SwitchVal];
IncrementerDriveRef: TYPE = REF IncrementerDriveRec;
IncrementerDriveRec:
TYPE =
RECORD [
tag: DriveTagType,
s: PACKED ARRAY IncrementerPort OF DriveLevel];
IncrementerPort: TYPE = MACHINE DEPENDENT {in, out, (3)};
CreateIncrementerIO:
PROC [ct: CellType, switch:
BOOL]
RETURNS [ioAsAny:
REF
ANY] =
{ioAsAny ← IF switch THEN NEW [IncrementerSwitchIORec] ELSE NEW [IncrementerSimpleIORec]};
CreateIncrementerDrive:
PROC [ct: CellType]
RETURNS [driveAsAny:
REF
ANY] =
{driveAsAny ← NEW [IncrementerDriveRec]};
EvalIncrementer:
PROC [cell: Cell, perturb:
PROC [portIndex: PortIndex]]
--SimpleEval-- = {
io: IncrementerSimpleIORef ← NARROW[cell.realCellStuff.newIO];
drive: IncrementerDriveRef ← NARROW[cell.realCellStuff.newDriveAsAny];
io.out ← io.in + 1;
};
incrementerPorts: Ports ← NEW [PortsRep[2]];
RegisterIncrementer:
PROC = {
incrementerPorts[0] ← [
simple: [0, 0, 1*bpw],
switch: [0, 0, 16*bpw],
name: "in",
type: NumTypes.NumType[16],
input: TRUE
];
incrementerPorts[1] ← [
simple: [1, 0, 1*bpw],
switch: [16, 0, 16*bpw],
name: "out",
type: NumTypes.NumType[16],
output: TRUE
];
[] ← RegisterCellType[
name: "Incrementer",
ioCreator: CreateIncrementerIO,
driveCreator: CreateIncrementerDrive,
evals: [EvalSimple: EvalIncrementer],
ports: incrementerPorts
];
};
ExpandContest:
PROC [thisCell: Cell, to: ExpansionReceiver] = {
contestants: REF NAT ← NARROW[thisCell.type.typeData];
[] ← to.class.NodeInstance[
erInstance: to.instance,
name: "outcome",
type: NumTypes.NumType[16]];
FOR i:
NAT
IN [0 .. contestants^)
DO
[] ← to.class.CellInstance[
erInstance: to.instance,
instanceName: IO.PutFR["d[%g]", IO.int[i]],
typeName: "Driver",
interfaceNodes: IO.PutFR["in: c[%g].in, out: outcome, str: c[%g].str", IO.int[i], IO.int[i]]
];
ENDLOOP;
[] ← to.class.CellInstance[
erInstance: to.instance,
instanceName: "inc",
typeName: "Incrementer",
interfaceNodes: "in: outcome, out: incedOutcome"
];
};
RegisterContest:
PROC [contestants:
NAT] = {
contestPorts: Ports ← NEW [PortsRep[contestants*2+1]];
FOR i:
NAT
IN [0 .. contestants)
DO
contestPorts[2*i] ← [
simple: noField,
switch: noField,
name: IO.PutFR["c[%g].in", IO.int[i]],
type: NumTypes.NumType[16],
input: TRUE];
contestPorts[2*i+1] ← [
simple: noField,
switch: noField,
name: IO.PutFR["c[%g].str", IO.int[i]],
type: NumTypes.NumType[4],
input: TRUE];
ENDLOOP;
contestPorts[2*contestants] ← [
simple: noField,
switch: noField,
name: "incedOutcome",
type: NumTypes.NumType[16],
output: TRUE];
[] ← RegisterCellType[
name: IO.PutFR["Contest[%g]", IO.int[contestants]],
expandProc: ExpandContest,
ports: contestPorts,
typeData: NEW [NAT ← contestants]
];
};
RegisterInverter[];
RegisterDriver[];
RegisterIncrementer[];
RegisterContest[3];
}.