DIRECTORY Basics, Core, CoreCreate, CoreFlat, CoreOps, Ports, Real, RealOps, Rope, Rosemary, SSI; SSIImpl: CEDAR PROGRAM IMPORTS Basics, CoreCreate, CoreFlat, Real, RealOps, Rosemary, Ports EXPORTS SSI = BEGIN OPEN SSI, CoreCreate; PWRule: PROC [nw: NAT, r: REAL, pw: NAT] RETURNS [newpw: NAT] = { foo: INT _ IF pw=0 THEN RealOps.ModalRound[Real.Float[nw] * r, [round: rn]] ELSE pw; IF Basics.HighHalf[foo]#0 THEN ERROR; newpw _ Basics.LowHalf[foo]; }; MakeTransistor: PROC [type: TransistorType, nw: NAT, nl: NAT, r: REAL, pw: NAT, pl: NAT, size: Rosemary.TransistorSize _ drive] RETURNS [t: Core.CellType] = { tWidth: NAT _ SELECT type FROM nE, nD => nw, pE => PWRule[nw, r, pw], ENDCASE => ERROR; t _ Rosemary.SetTransistorCellTypeSize[Transistor[type: type, width: tWidth], size]; }; InverterName: ROPE = Rosemary.Register[roseClassName: "Inverter", evalSimple: InverterSimple]; InverterVdd: NAT = 0; InverterGnd: NAT = 1; InverterInput: NAT = 2; InverternOutput: NAT = 3; Inverter: PUBLIC PROC [nw: NAT _ 4, nl: NAT _ 2, r: REAL _ 2.5, pw: NAT _ 0, pl: NAT _ 2, size: Rosemary.TransistorSize _ drive] RETURNS [ct: CellType] = { ct _ Cell[ name: InverterName, public: Wires["Vdd", "Gnd", "Input", "nOutput"], instances: LIST [ Instance[MakeTransistor[pE, nw, nl, r, pw, pl, size], ["gate", "Input"], ["ch1", "Vdd"], ["ch2", "nOutput"], ["Vdd", "Vdd"]], Instance[MakeTransistor[nE, nw, nl, r, pw, pl, size], ["gate", "Input"], ["ch1", "nOutput"], ["ch2", "Gnd"]]]]; [] _ Rosemary.BindCellType[cellType: ct, roseClassName: InverterName]; [] _ CoreFlat.CellTypeCutLabels[ct, "JustAboveTransistors"]; [] _ Ports.InitPort[wire: ct.public[InverterVdd], levelType: l]; [] _ Ports.InitPort[wire: ct.public[InverterGnd], levelType: l]; [] _ Ports.InitPort[wire: ct.public[InverterInput], levelType: l]; [] _ Ports.InitPort[wire: ct.public[InverternOutput], levelType: l, initDrive: size]; }; InverterSimple: Rosemary.EvalProc = { p[InverternOutput].l _ SELECT TRUE FROM p[InverterInput].l=X OR p[InverterVdd].l#H OR p[InverterGnd].l#L => X, p[InverterInput].l=L => H, p[InverterInput].l=H => L, ENDCASE => ERROR; }; TristateBufferName: ROPE = Rosemary.Register[roseClassName: "TristateBuffer", evalSimple: TristateSimple]; TristateVdd: NAT = 0; TristateGnd: NAT = 1; TristateInput: NAT = 2; TristateDrive: NAT = 3; TristatenDrive: NAT = 4; TristatenOutput: NAT = 5; TristateBuffer: PUBLIC PROC [nw: NAT _ 4, nl: NAT _ 2, r: REAL _ 2.5, pw: NAT _ 0, pl: NAT _ 2] RETURNS [ct: CellType] = { pType: Core.CellType _ MakeTransistor[pE, nw, nl, r, pw, pl]; nType: Core.CellType _ MakeTransistor[nE, nw, nl, r, pw, pl]; ct _ Cell[ name: TristateBufferName, public: Wires["Vdd", "Gnd", "Input", "Drive", "nDrive", "nOutput"], onlyInternal: Wires["pstack", "nstack"], instances: LIST [ Instance[pType, ["gate", "Input"], ["ch1", "Vdd"], ["ch2", "pstack"], ["Vdd", "Vdd"]], Instance[pType, ["gate", "nDrive"], ["ch1", "pstack"], ["ch2", "nOutput"], ["Vdd", "Vdd"]], Instance[nType, ["gate", "Drive"], ["ch1", "nOutput"], ["ch2", "nstack"]], Instance[nType, ["gate", "Input"], ["ch1", "nstack"], ["ch2", "Gnd"]]]]; [] _ Rosemary.BindCellType[cellType: ct, roseClassName: TristateBufferName]; [] _ CoreFlat.CellTypeCutLabels[ct, "JustAboveTransistors"]; }; TristateSimple: Rosemary.EvalProc = { IF NOT p[TristateVdd].b OR p[TristateGnd].b OR (p[TristateDrive].b AND NOT p[TristatenDrive].b) THEN SIGNAL Rosemary.Stop[]; p[TristatenOutput].d _ IF p[TristateDrive].b OR NOT p[TristatenDrive].b THEN drive ELSE none; p[TristatenOutput].b _ NOT p[TristateInput].b; }; NAndName: ROPE = Rosemary.Register[roseClassName: "NAnd", evalSimple: NAndSimple]; NAndVdd: NAT = 0; NAndGnd: NAT = 1; NAndInput: NAT = 2; NAndnOutput: NAT = 3; NAnd: PUBLIC PROC [i: NAT, nw: NAT _ 4, nl: NAT _ 2, r: REAL _ 2.5, pw: NAT _ 0, pl: NAT _ 2] RETURNS [ct: CellType] = { instances: LIST OF CellInstance _ NIL; pType: Core.CellType _ MakeTransistor[pE, nw, nl, r, pw, pl]; nType: Core.CellType _ MakeTransistor[nE, nw, nl, r, pw, pl]; FOR input: NAT IN [0..i) DO instances _ CONS[Instance[pType, ["gate", Index["Input", input]], ["ch1", "Vdd"], ["ch2", "nOutput"], ["Vdd", "Vdd"]], instances]; instances _ CONS[Instance[nType, ["gate", Index["Input", input]], ["ch1", IF input=0 THEN "nOutput" ELSE Index["stack", input-1]], ["ch2", IF input=i-1 THEN "Gnd" ELSE Index["stack", input]]], instances]; ENDLOOP; ct _ Cell[ name: NAndName, public: Wires["Vdd", "Gnd", Seq["Input", i], "nOutput"], onlyInternal: Wires[Seq["stack", i-1]], instances: instances]; [] _ Rosemary.BindCellType[cellType: ct, roseClassName: NAndName]; [] _ CoreFlat.CellTypeCutLabels[ct, "JustAboveTransistors"]; [] _ Ports.InitPort[wire: ct.public[NAndnOutput], levelType: b, initDrive: drive]; }; NAnd2: PUBLIC PROC [nw: NAT _ 4, nl: NAT _ 2, r: REAL _ 2.5, pw: NAT _ 0, pl: NAT _ 2] RETURNS [ct: CellType] ~ { nand: CellType _ NAnd[2, nw, nl, r, pw, pl]; public: Wire _ Wires["Vdd", "Gnd", "Input0", "Input1", "nOutput"]; ct _ Cell[ name: "NAnd2", public: public, instances: LIST[Instance[nand, ["Input", Wires["Input0", "Input1"]]]] ]; }; NAndSimple: Rosemary.EvalProc = { IF NOT p[NAndVdd].b OR p[NAndGnd].b THEN SIGNAL Rosemary.Stop[]; FOR input: NAT IN [0..p[NAndInput].size) DO IF NOT p[NAndInput][input].b THEN { p[NAndnOutput].b _ TRUE; EXIT; }; REPEAT FINISHED => p[NAndnOutput].b _ FALSE; ENDLOOP; }; AndName: ROPE = Rosemary.Register[roseClassName: "And", evalSimple: AndSimple]; AndVdd: NAT = 0; AndGnd: NAT = 1; AndInput: NAT = 2; AndOutput: NAT = 3; And: PUBLIC PROC [i: NAT, nw: NAT _ 4, nl: NAT _ 2, r: REAL _ 2.5, pw: NAT _ 0, pl: NAT _ 2] RETURNS [ct: CellType] = { ct _ Cell[ name: AndName, public: Wires["Vdd", "Gnd", Seq["Input", i], "Output"], onlyInternal: Wires["nOutput"], instances: LIST [ Instance[NAnd[i, nw, nl, r, pw, pl]], -- fix this to scale nand to inverter gate cap. Instance[Inverter[nw, nl, r, pw, pl], ["Input", "nOutput"], ["nOutput", "Output"]]]]; [] _ Rosemary.BindCellType[cellType: ct, roseClassName: AndName]; [] _ CoreFlat.CellTypeCutLabels[ct, "JustAboveTransistors"]; [] _ Ports.InitPort[wire: ct.public[AndOutput], levelType: b, initDrive: drive]; }; AndSimple: Rosemary.EvalProc = { IF NOT p[AndVdd].b OR p[AndGnd].b THEN SIGNAL Rosemary.Stop[]; FOR input: NAT IN [0..p[AndInput].size) DO IF NOT p[AndInput][input].b THEN { p[AndOutput].b _ FALSE; EXIT; }; REPEAT FINISHED => p[AndOutput].b _ TRUE; ENDLOOP; }; NOrName: ROPE = Rosemary.Register[roseClassName: "NOr", evalSimple: NOrSimple]; NOrVdd: NAT = 0; NOrGnd: NAT = 1; NOrInput: NAT = 2; NOrnOutput: NAT = 3; NOr: PUBLIC PROC [i: NAT, nw: NAT _ 4, nl: NAT _ 2, r: REAL _ 2.5, pw: NAT _ 0, pl: NAT _ 2] RETURNS [ct: CellType] = { instances: LIST OF CellInstance _ NIL; pType: Core.CellType _ MakeTransistor[pE, nw, nl, r, pw, pl]; nType: Core.CellType _ MakeTransistor[nE, nw, nl, r, pw, pl]; FOR input: NAT IN [0..i) DO instances _ CONS[Instance[pType, ["gate", Index["Input", input]], ["ch1", IF input=0 THEN "Vdd" ELSE Index["stack", input-1]], ["ch2", IF input=i-1 THEN "nOutput" ELSE Index["stack", input]], ["Vdd", "Vdd"]], instances]; instances _ CONS[Instance[nType, ["gate", Index["Input", input]], ["ch1", "nOutput"], ["ch2", "Gnd"]], instances]; ENDLOOP; ct _ Cell[ name: NOrName, public: Wires["Vdd", "Gnd", Seq["Input", i], "nOutput"], onlyInternal: Wires[Seq["stack", i-1]], instances: instances]; [] _ Rosemary.BindCellType[cellType: ct, roseClassName: NOrName]; [] _ CoreFlat.CellTypeCutLabels[ct, "JustAboveTransistors"]; [] _ Ports.InitPort[wire: ct.public[NOrnOutput], levelType: b, initDrive: drive]; }; NOr2: PUBLIC PROC [nw: NAT _ 4, nl: NAT _ 2, r: REAL _ 2.5, pw: NAT _ 0, pl: NAT _ 2] RETURNS [ct: CellType] ~ { nor: CellType _ NOr[2, nw, nl, r, pw, pl]; public: Wire _ Wires["Vdd", "Gnd", "Input0", "Input1", "nOutput"]; ct _ Cell[ name: "NOr2", public: public, instances: LIST[Instance[nor, ["Input", Wires["Input0", "Input1"]]]] ]; }; NOrSimple: Rosemary.EvalProc = { IF NOT p[NOrVdd].b OR p[NOrGnd].b THEN SIGNAL Rosemary.Stop[]; FOR input: NAT IN [0..p[NOrInput].size) DO IF p[NOrInput][input].b THEN { p[NOrnOutput].b _ FALSE; EXIT; }; REPEAT FINISHED => p[NOrnOutput].b _ TRUE; ENDLOOP; }; OrName: ROPE = Rosemary.Register[roseClassName: "Or", evalSimple: OrSimple]; OrVdd: NAT = 0; OrGnd: NAT = 1; OrInput: NAT = 2; OrOutput: NAT = 3; Or: PUBLIC PROC [i: NAT, nw: NAT _ 4, nl: NAT _ 2, r: REAL _ 2.5, pw: NAT _ 0, pl: NAT _ 2] RETURNS [ct: CellType] = { ct _ Cell[ name: OrName, public: Wires["Vdd", "Gnd", Seq["Input", i], "Output"], onlyInternal: Wires[Seq["nInput", i]], instances: LIST [ Instance[InverterSeq[i, nw, nl, r, pw, pl], ["Input", "Input"], ["nOutput", "nInput"]], Instance[NAnd[i, nw, nl, r, pw, pl], ["Input", "nInput"], ["nOutput", "Output"]]]]; [] _ Rosemary.BindCellType[cellType: ct, roseClassName: OrName]; [] _ CoreFlat.CellTypeCutLabels[ct, "JustAboveTransistors"]; [] _ Ports.InitPort[wire: ct.public[OrOutput], levelType: b, initDrive: drive]; }; OrSimple: Rosemary.EvalProc = { IF NOT p[OrVdd].b OR p[OrGnd].b THEN SIGNAL Rosemary.Stop[]; FOR input: NAT IN [0..p[OrInput].size) DO IF p[OrInput][input].b THEN { p[OrOutput].b _ TRUE; EXIT; }; REPEAT FINISHED => p[OrOutput].b _ FALSE; ENDLOOP; }; InverterSeqName: ROPE = "InverterSeq"; InverterSeq: PROC [i: NAT, nw: NAT _ 4, nl: NAT _ 2, r: REAL _ 2.5, pw: NAT _ 0, pl: NAT _ 2] RETURNS [ct: CellType] = { baseCell: CellType _ Inverter[nw, nl, r, pw, pl]; ct _ SequenceCell[ name: InverterSeqName, baseCell: baseCell, count: i, sequencePorts: Wires[baseCell.public[InverterInput], baseCell.public[InverternOutput]]]; }; END. ΦSSIImpl.mesa Copyright Σ 1985, 1987 by Xerox Corporation. All rights reserved. Barth, October 10, 1986 5:35:29 pm PDT Bertrand Serlet April 6, 1987 3:32:32 pm PDT Louis Monier August 7, 1986 7:46:46 pm PDT Κ …– "cedar" style˜codešœ ™ KšœB™BKšœ#Οk™&Kšœ,™,Kšœ'™*K™—Kš œTœ˜aK˜•StartOfExpansion[]šΠbnœœ˜Kšœ=˜DKšœ˜ Kšœœœœ ˜—K˜šΟnœœœœœœ œ˜AKš œœœœ5œ˜TKšœœœ˜%Kšœ˜Kšœ˜K˜—šŸœœœœœœœ)œ˜žšœœœœ˜Kšœ ˜ Kšœ˜Kšœœ˜—KšœT˜TKšœ˜K˜—KšŸ œœL˜^KšŸ œœ˜KšŸ œœ˜KšŸ œœ˜KšŸœœ˜K˜šŸœœœœ œ œ œ œ-œ˜›šœ ˜ Kšœ˜Kšœ0˜0šœ œ˜šœ5˜5KšœG˜G—šœ5˜5Kšœ9˜9———KšœF˜FKšœ<˜šœœœ˜*šœœœ˜"Kšœœ˜Kšœ˜K˜—Kš˜Kšœœ˜"Kšœ˜—Kšœ˜K˜—KšŸœœB˜OKšŸœœ˜KšŸœœ˜KšŸœœ˜KšŸ œœ˜K˜šžœœœœœ œ œ œ œœ˜wKšœ œœœ˜&Kšœ=˜=Kšœ=˜=šœœœ˜šœ œ˜ Kšœ ˜ Kšœœ œœ˜šœœœ˜*šœœ˜Kšœœ˜Kšœ˜K˜—Kš˜Kšœœ˜#Kšœ˜—Kšœ˜K˜—KšŸœœ@˜LKšŸœœ˜KšŸœœ˜KšŸœœ˜KšŸœœ˜K˜šžœœœœœ œ œ œ œœ˜všœ ˜ Kšœ ˜ Kšœ7˜7Kšœ&˜&šœ œ˜KšœW˜WKšœS˜S——Kšœ@˜@Kšœ<˜