Pads.rose
Last Edited by: Barth, June 18, 1985 6:37:56 pm PDT
Imports IO, RoseTypes;
Directory Basics;
Library SSI, Transistors;
CELLTYPE "BasicPad"
PORTS [Vdd, Gnd < BOOL, Pad = BOOL, nDataOut > BOOL]
EvalSimple
nDataOut ← NOT Pad;
Expand
The protection devices need to be inserted here.
invert: Inverter[Input: Pad, Output: nDataOut]
ENDCELLTYPE;
CELLTYPE "InputPad"
PORTS [Vdd, Gnd, Pad < BOOL, DataOut > BOOL]
EvalSimple
DataOut ← Pad;
Expand
nbasicDataOut: BOOL;
inputBasic: BasicPad[nDataOut: nbasicDataOut];
invert: Inverter[Input: nbasicDataOut, Output: DataOut]
ENDCELLTYPE;
CELLTYPE "DifferentialInputPad"
PORTS [Vdd, Gnd, Pad < BOOL, DataOut, nDataOut > BOOL]
EvalSimple
DataOut ← Pad;
nDataOut ← NOT Pad;
Expand
basicDataOut, nbasicDataOut: BOOL;
inputBasic: BasicPad[nDataOut: nbasicDataOut];
invert1: Inverter[Input: nbasicDataOut, Output: DataOut];
invert2: Inverter[Input: nbasicDataOut, Output: basicDataOut];
invert3: Inverter[Input: basicDataOut, Output: nDataOut]
ENDCELLTYPE;
CELLTYPE "BidirectionalPad"
PORTS [Vdd, Gnd, Read, nRead, Write, nWrite < BOOL, Pad, Data = BOOL]
EvalSimple
IF (Read AND nRead) OR (NOT Read AND NOT nRead) OR (Write AND nWrite) OR (NOT Write AND NOT nWrite) OR (Read AND Write) THEN RoseTypes.Stop["Bad control signals in bidirectional pad", $FailedAssertion];
IF Read THEN Pad ← Data;
IF Write THEN Data ← Pad;
Expand
nor, nand, nbasicDataOut: BOOL;
drivep: Nand2[Input1: Read, Input2: Data, Output: nand];
driven: Nor2[Input1: nRead, Input2: Data, Output: nor];
p: pE[gate: nand, ch1: Vdd, ch2: Pad];
n: nE[gate: nor, ch1: Pad, ch2: Gnd];
inputBasic: BasicPad[nDataOut: nbasicDataOut];
buffer: TristateBuffer[nDataIn: nbasicDataOut, Drive: Write, nDrive: nWrite, Output: Data]
ENDCELLTYPE;
BidirectionalPadSequence: LAMBDA [count: |NAT|] RETURN CELLTYPE
NameMaker
name ← IO.PutFR["BidirectionalPad%g", IO.int[count]]
PortsProc
portNumber: CARDINAL ← 0;
InitPort: PROC[name: ROPE, input: BOOLTRUE, output: BOOLFALSE, type: NodeType ← NumTypes.boolType ] = {
compilerBugBypass: Field ← [0, 0, 0];
ports[portNumber] ← [
simple: compilerBugBypass,
switch: compilerBugBypass,
name: name,
type: type,
input: input,
output: output];
portNumber ← portNumber + 1;
};
IF count<1 THEN ERROR;
ports ← NEW [PortsRep[8]];
InitPort["Vdd"];
InitPort["Gnd"];
InitPort["Read"];
InitPort["nRead"];
InitPort["Write"];
InitPort["nWrite"];
InitPort[name: "Pads", output: TRUE, type: NumTypes.NumType[count]];
InitPort[name: "Data", output: TRUE, type: NumTypes.NumType[count]];
Expand
Cedar
padSubNodes: RoseTypes.UnnamedConsNE ← NEW[RoseTypes.NodeExpressionRep.unnamedCons ← [unnamedCons [elts: NIL]]];
dataSubNodes: RoseTypes.UnnamedConsNE ← NEW[RoseTypes.NodeExpressionRep.unnamedCons ← [unnamedCons [elts: NIL]]];
FOR ip: CARDINAL DECREASING IN [0..count) DO
padSubNodes.elts ← CONS[NEW[ NodeExpressionRep.primary ← [primary[ node: to.class.NodeInstance[erInstance: to.instance, name: IO.PutFR["Pad%g", IO.int[ip]], type: NumTypes.boolType], selector: [whole [ ]]]]], padSubNodes.elts];
dataSubNodes.elts ← CONS[NEW[ NodeExpressionRep.primary ← [primary[ node: to.class.NodeInstance[erInstance: to.instance, name: IO.PutFR["Data%g", IO.int[ip]], type: NumTypes.boolType], selector: [whole [ ]]]]], dataSubNodes.elts];
[] ← to.class.CellInstance[erInstance: to.instance, instanceName: IO.PutFR["BidirPad%g", IO.int[ip]], typeName: "BidirectionalPad", interfaceNodes: IO.PutFR["Pad:Pad%g, Data:Data%g", IO.int[ip], IO.int[ip]]];
ENDLOOP;
to.class.Equivalence[erInstance: to.instance, a: NEW[NodeExpressionRep.primary ← [primary [node: RoseCreate.LookupNode[from: thisCell, path: LIST["Pads"]], selector: [whole [ ]]]]], b: padSubNodes];
to.class.Equivalence[erInstance: to.instance, a: NEW[NodeExpressionRep.primary ← [primary [node: RoseCreate.LookupNode[from: thisCell, path: LIST["Data"]], selector: [whole [ ]]]]], b: dataSubNodes]
ENDCELLTYPE;
CEDAR
bpw: NAT = Basics.bitsPerWord;
InputPadSeqSimpleIORef: TYPE = REF InputPadSeqSimpleIORec;
InputPadSeqSimpleIORec: TYPE = MACHINE DEPENDENT RECORD [
Fill0(0: 0..14): [0..32768),
Vdd(0: 15..15): BOOL,
Fill1(1: 0..14): [0..32768),
Gnd(1: 15..15): BOOL,
Pad(2: 0..15): CARDINAL,
DataOut(3: 0..15): CARDINAL
];
InputPadSeqSwitchIORef: TYPE = REF InputPadSeqSwitchIORec;
InputPadSeqSwitchIORec: TYPE = MACHINE DEPENDENT RECORD [
Vdd(0): SwitchTypes.SwitchVal,
Gnd(1): SwitchTypes.SwitchVal,
ports(2): SEQUENCE COMPUTED CARDINAL OF SwitchTypes.SwitchVal];
InputPadSeqDriveRec: TYPE = RECORD [tag: DriveTagType, drive: PACKED ARRAY InputPadSeqPort OF DriveLevel];
InputPadSeqPort: TYPE = {Vdd, Gnd, Pad, DataOut};
;
InputPadSequence: LAMBDA [count: |NAT|] RETURN CELLTYPE
NameMaker
name ← IO.PutFR["InputPad%g", IO.int[count]]
PortsProc
IF count<1 OR count>bpw THEN ERROR; -- doesn't handle wide buses yet
ports ← NEW [PortsRep[4]];
ports[0] ← [
simple: [0, bpw-1, 1],
switch: [0, 0, bpw],
name: "Vdd",
type: NumTypes.boolType,
input: TRUE];
ports[1] ← [
simple: [1, bpw-1, 1],
switch: [1, 0, bpw],
name: "Gnd",
type: NumTypes.boolType,
input: TRUE];
ports[2] ← [
simple: [2, bpw-count, count],
switch: [2, 0, count*bpw],
name: "Pad",
type: NumTypes.NumType[count],
input: TRUE];
ports[3] ← [
simple: [3, bpw-count, count],
switch: [2+count, 0, count*bpw],
name: "DataOut",
type: NumTypes.NumType[count],
output: TRUE];
SimpleIOAux RecType InputPadSeqSimpleIORec
SimpleIOAux InitialValue |NEW[InputPadSeqSimpleIORec[?count?]]|
SwitchIOAux RecType InputPadSeqSwitchIORec
SwitchIOAux InitialValue |NEW[InputPadSeqSwitchIORec[2*count]]|
DriveAux RecType InputPadSeqDriveRec
EvalSimple
DataOut ← Pad;
Expand
Cedar
padSubNodes: RoseTypes.UnnamedConsNE ← NEW[RoseTypes.NodeExpressionRep.unnamedCons ← [unnamedCons [elts: NIL]]];
dataOutSubNodes: RoseTypes.UnnamedConsNE ← NEW[RoseTypes.NodeExpressionRep.unnamedCons ← [unnamedCons [elts: NIL]]];
FOR ip: CARDINAL DECREASING IN [0..count) DO
padSubNodes.elts ← CONS[NEW[ NodeExpressionRep.primary ← [primary[ node: to.class.NodeInstance[erInstance: to.instance, name: IO.PutFR["Pad%g", IO.int[ip]], type: NumTypes.boolType], selector: [whole [ ]]]]], padSubNodes.elts];
dataOutSubNodes.elts ← CONS[NEW[ NodeExpressionRep.primary ← [primary[ node: to.class.NodeInstance[erInstance: to.instance, name: IO.PutFR["DataOut%g", IO.int[ip]], type: NumTypes.boolType], selector: [whole [ ]]]]], dataOutSubNodes.elts];
[] ← to.class.CellInstance[erInstance: to.instance, instanceName: IO.PutFR["InputPad%g", IO.int[ip]], typeName: "InputPad", interfaceNodes: IO.PutFR["Pad:Pad%g, DataOut:DataOut%g", IO.int[ip], IO.int[ip]]];
ENDLOOP;
to.class.Equivalence[erInstance: to.instance, a: NEW[NodeExpressionRep.primary ← [primary [node: RoseCreate.LookupNode[from: thisCell, path: LIST["Pad"]], selector: [whole [ ]]]]], b: padSubNodes];
to.class.Equivalence[erInstance: to.instance, a: NEW[NodeExpressionRep.primary ← [primary [node: RoseCreate.LookupNode[from: thisCell, path: LIST["DataOut"]], selector: [whole [ ]]]]], b: dataOutSubNodes]
ENDCELLTYPE