DIRECTORY CD, CDDirectory, CDOrient, Core, CoreBlock, CoreCreate, CoreFrame, CoreInstCell, CoreIO, CoreLibrary, CoreName, CoreOps, CoreProperties, IFUCoreCells, IFUCoreDrive, IO, PW, PWCore, PWPins, REFBit, Rope; IFUCoreDriveImpl: CEDAR PROGRAM IMPORTS CDDirectory, CoreBlock, CoreCreate, CoreFrame, CoreInstCell, CoreIO, CoreLibrary, CoreName, CoreOps, CoreProperties, IFUCoreCells, IO, PW, PWCore, REFBit, Rope EXPORTS IFUCoreDrive = BEGIN ROPE: TYPE = Core.ROPE; CellType: TYPE = Core.CellType; Wire: TYPE = Core.Wire; PLAType: TYPE = IFUCoreDrive.PLAType; Drive: TYPE = IFUCoreDrive.Drive; Drives: TYPE = IFUCoreDrive.Drives; DriveRec: TYPE = IFUCoreDrive.DriveRec; DrNmType: TYPE = IFUCoreDrive.DrNmType; RowType: TYPE = IFUCoreDrive.RowType; Dir: TYPE = IFUCoreDrive.Dir; DrGate: TYPE = IFUCoreDrive.DrGate; Ph: TYPE = IFUCoreDrive.Ph; Polarity: TYPE = IFUCoreDrive.Polarity; DrTileRec: TYPE = IFUCoreDrive.DrTileRec; DrTileNonConn: TYPE = IFUCoreDrive.DrTileNonConn; DrTileConn: TYPE = IFUCoreDrive.DrTileConn; DrTileArray: TYPE = IFUCoreDrive.DrTileArray; DriveTileType: TYPE = IFUCoreDrive.DriveTileType; Signal: SIGNAL = CODE; driveCellClass: PUBLIC Core.CellClass _ CoreOps.SetClassPrintProc[ NEW[Core.CellClassRec _ [name: "IFUCoreDrive", recast: NIL]], ClassPrintProc]; ClassPrintProc: CoreOps.PrintClassProc = { drData: Drive _ NARROW[data]; IO.PutF[out, "\nDriver: %g", IO.rope[ DrRope[drData] ] ] }; drShiftIn: PUBLIC ATOM _ CoreIO.RegisterProperty[ CoreProperties.RegisterProperty[ $DShiftIn, CoreProperties.Props[ [CoreProperties.propCompare, NEW[CoreProperties.PropCompareProc _ CompareRope]], [CoreProperties.propCopy, NEW[CoreProperties.PropCopyProc _ CopyRope ]], [CoreProperties.propPrint, NEW[CoreProperties.PropPrintProc _ PrintRopeIn ]] ]], WriteRope, ReadRope ]; drShiftOut: PUBLIC ATOM _ CoreIO.RegisterProperty[ CoreProperties.RegisterProperty[ $DShiftOut, CoreProperties.Props[ [CoreProperties.propCompare, NEW[CoreProperties.PropCompareProc _ CompareRope]], [CoreProperties.propCopy, NEW[CoreProperties.PropCopyProc _ CopyRope ]], [CoreProperties.propPrint, NEW[CoreProperties.PropPrintProc _ PrintRopeOut]]]], WriteRope, ReadRope ]; WriteRope: CoreIO.PropWriteProc = {rope: ROPE _ NARROW[value]; CoreIO.WriteRope[h, rope]}; ReadRope: CoreIO.PropReadProc = {rope: ROPE _ CoreIO.ReadRope[h]; RETURN[ rope ]}; CopyRope: CoreProperties.PropCopyProc = {RETURN[value]}; CompareRope: CoreProperties.PropCompareProc = { rope1: ROPE _ NARROW[value1]; rope2: ROPE _ NARROW[value2]; RETURN[Rope.Equal[rope1, rope2]]}; PrintRopeIn: CoreProperties.PropPrintProc = {rope: ROPE _ NARROW[val]; to.PutF["DShiftIn: %g", IO.rope[rope]]}; PrintRopeOut: CoreProperties.PropPrintProc = {rope: ROPE _ NARROW[val]; to.PutF["DShiftOut: %g", IO.rope[rope]]}; SetDShiftIO: PUBLIC PROC[cellType: CellType, sIn, sOut: ROPE] = { CoreProperties.PutCellTypeProp[cellType, drShiftIn, sIn]; CoreProperties.PutCellTypeProp[cellType, drShiftOut, sOut]}; GetDShiftIO: PUBLIC PROC[cellType: CellType] RETURNS [sIn, sOut: ROPE] = { sIn _ NARROW[CoreProperties.GetCellTypeProp[cellType, drShiftIn ]]; sOut _ NARROW[CoreProperties.GetCellTypeProp[cellType, drShiftOut ]]}; CellProc: PUBLIC PROC [ name: ROPE _ NIL, data: Drive _ NIL ] RETURNS [cellType: CellType] = { cellType _ CoreOps.SetCellTypeName[ NEW [ Core.CellTypeRec _ [ class: driveCellClass, public: CoreOps.CreateWires[0], data: data] ], name]; CoreFrame.SetFrameExpandProc[soft, cellType, NEW[CoreFrame.ExpandProc _ Expand] ]; CoreFrame.SetFrameExpandProc[hard, cellType, NEW[CoreFrame.ExpandProc _ Expand] ]}; Expand: CoreFrame.ExpandProc = { drive: Drive _ NARROW[frameCT.data]; frame: REF CoreFrame.FrameRec _ NEW[CoreFrame.FrameRec _ [first: left]]; genericDriver: CellType _ GetGenericDriver[drive]; driverName: ROPE _ DriveName[drive, out]; renameProc: CoreInstCell.RenameProc = {new _ SpecificNames[old, drive]}; frame.cell _ CoreInstCell.SpecificGeneric[genericDriver, renameProc]; frame.seq _ NEW[CoreFrame.FrameSeq[0]]; frameCT.data _ frame; frameCT.class _ CoreFrame.frameCellClass; CoreFrame.SetFrameExpandProc[soft, frameCT, NIL]; CoreFrame.SetFrameExpandProc[hard, frameCT, NIL]}; GetGenericDriver: PROC[drive: Drive] RETURNS[genericDriver: CellType] = { obj: CD.Object; basicDrName, drName: ROPE; decoderOut: BOOL _ drive.plaType=decoder AND drive.drRowType=conn AND drive.drDir=out; library: CoreLibrary.Library _ IFUCoreCells.library; drTiles: REF DrTileRec _ GetDriverTiles[]; IF drive.drRowType#conn THEN { plaType: PLAType _ SELECT drive.plaType FROM hot, precharged => drive.plaType, ENDCASE => static; RETURN[drTiles.nconn[plaType][drive.drRowType]]}; basicDrName _ GenericDriverName[drive]; drName _ IF decoderOut THEN Rope.Cat["D", basicDrName] ELSE basicDrName; genericDriver _ CoreLibrary.Get[library, basicDrName]; IF genericDriver=NIL THEN { Inst: PROC[type: DriveTileType] = {cells _ CONS[ drTiles.conn[drive.drDir][type], cells]}; cells: LIST OF CellType _ NIL; IF drive.ref.ph=unk -- Debug driver, clears node on either phase THEN Inst[inGndAB] ELSE { IF drive.ref.pol=drive.in.pol THEN Inst[inPos] ELSE Inst[inNeg]; IF drive.ref.ph=A THEN Inst[latchA] ELSE Inst[latchB]}; Inst[latch]; IF drive.drDir#in THEN SELECT drive.gate FROM pos => Inst[gateP]; neg => Inst[gateN]; negAc => Inst[gateNA]; negBc => Inst[gateNB]; ENDCASE => ERROR; IF drive.dualOut THEN { IF (drive.ref.pol=drive.out.pol)=(drive.gate=pos) THEN Inst[posDual] ELSE Inst[negDual]} ELSE IF (drive.ref.pol=drive.out.pol)=(drive.gate=pos) THEN Inst[posSing] ELSE Inst[negSing]; genericDriver _ CoreBlock.AbutCellList [basicDrName, (IF drive.drDir=out THEN right ELSE left), cells]; CoreLibrary.Set[library, basicDrName, genericDriver]; obj _ PWCore.Layout[genericDriver]}; -- Make sure PWCore is happy with construction genericDriver _ CoreLibrary.Get[library, drName]; IF genericDriver=NIL THEN { thinDriver: CellType _ CoreLibrary.Get[library, basicDrName]; genericDriver _ CoreCreate.Cell[ public: CoreOps.CopyWire[thinDriver.public], onlyInternal: NIL, instances: LIST[ CoreCreate.Instance[drTiles.nconn[decoder][blank], [dShDataRp, dShDataInRp]], CoreCreate.Instance[thinDriver]], name: drName ]; PWCore.SetAbutY[genericDriver]; CoreBlock.PutCellSide[genericDriver, CoreFrame.SideSides[bottom]]; CoreBlock.MergeSides[genericDriver]; CoreLibrary.Set[library, drName, genericDriver]; obj _ PWCore.Layout[genericDriver]} }; -- Make sure PWCore is happy with construction inRp: ROPE _ CoreName.RopeNm["in"]; ioRp: ROPE _ CoreName.RopeNm["io"]; outRp: ROPE _ CoreName.RopeNm["out"]; out0Rp: ROPE _ CoreName.RopeNm["out0"]; out1Rp: ROPE _ CoreName.RopeNm["out1"]; dShDataRp: ROPE _ CoreName.RopeNm["DShData"]; dShDataInRp: ROPE _ CoreName.RopeNm["DShDataIn"]; dShDataOutRp: ROPE _ CoreName.RopeNm["DShDataOut"]; SpecificNames: PUBLIC PROC[generic: ROPE, drive: Drive] RETURNS [specific: ROPE] = { specific _ SELECT generic FROM inRp => DriveName[drive,in], out0Rp => DriveName[drive,out], out1Rp => IF ~drive.dualOut THEN NIL ELSE DriveName[drive,nout], dShDataRp => SELECT TRUE FROM drive.inSh=NIL AND drive.outSh=NIL => CoreName.ID[generic], drive.inSh = drive.outSh => drive.inSh, drive.inSh#NIL AND drive.outSh=NIL => drive.inSh, drive.inSh=NIL AND drive.outSh#NIL => drive.outSh, ENDCASE => ERROR, dShDataInRp => IF drive.inSh=NIL THEN CoreName.ID[generic] ELSE drive.inSh, dShDataOutRp => IF drive.outSh=NIL THEN CoreName.ID[generic] ELSE drive.outSh, ENDCASE => generic; IF specific#NIL THEN specific _ CoreName.RopeNm[specific]}; tileBuffer: REF DrTileRec _ NIL; GetDriverTiles: PUBLIC PROC RETURNS[tiles: REF DrTileRec] = { Get: PROC[name: ROPE] RETURNS[cell: CellType] = {cell _ CoreLibrary.Get[library, name]}; FlipY: PROC[ref: ROPE] RETURNS[cell: CellType] = { name: ROPE _ CoreName.RopeNm[ref.Cat["FlipY"]]; obj: CD.Object _ CDDirectory.Fetch[library.design, ref].object; cell _ CoreLibrary.Get[library, name]; IF cell#NIL THEN RETURN[cell]; cell _ CoreLibrary.ObjCell[PW.FlipY[obj], name]; CoreLibrary.Set[library, name, cell]}; driveTop: CellType; driveBot: CellType; library: CoreLibrary.Library _ IFUCoreCells.library; IF tileBuffer # NIL THEN RETURN[tileBuffer]; log.PutRope["\n Initialize drive tiles"]; tiles _ tileBuffer _ NEW[DrTileRec]; tiles.conn[in] _ NEW[DrTileArray]; tiles.conn[out] _ NEW[DrTileArray]; tiles.nconn [precharged][header] _ Get[ "DrHead" ]; tiles.nconn [precharged][xheader] _ Get[ "DrXHead"]; tiles.nconn [precharged][extend] _ Get[ "DrExtend" ]; tiles.nconn [precharged][blank] _ Get[ "DrBlank" ]; tiles.nconn [precharged][dataUp] _ tiles.nconn [precharged][blank]; tiles.nconn [precharged][dataDn] _ tiles.nconn [precharged][blank]; tiles.nconn [precharged][footer] _ FlipY[ "DrHead"]; tiles.nconn [precharged][xfooter] _ FlipY[ "DrXHead"]; tiles.nconn [hot][header] _ Get[ "HPlaDrHead" ]; tiles.nconn [hot][xheader] _ Get[ "DrXHead"]; tiles.nconn [hot][extend] _ Get[ "DrExtend" ]; tiles.nconn [hot][blank] _ Get[ "DrBlank" ]; tiles.nconn [hot][dataUp] _ tiles.nconn [hot][blank]; tiles.nconn [hot][dataDn] _ tiles.nconn [hot][blank]; tiles.nconn [hot][footer] _ FlipY[ "HPlaDrHead"]; tiles.nconn [hot][xfooter] _ FlipY[ "DrXHead"]; tiles.nconn [static][header] _ Get[ "SPlaDrHead" ]; tiles.nconn [static][xheader] _ Get[ "DrXHead" ]; tiles.nconn [static][extend] _ Get[ "DrExtend" ]; tiles.nconn [static][blank] _ Get[ "SPlaDrBlank24" ]; tiles.nconn [static][dataUp] _ tiles.nconn [static][blank]; tiles.nconn [static][dataDn] _ tiles.nconn [static][blank]; tiles.nconn [static][footer] _ FlipY[ "SPlaDrHead"]; tiles.nconn [static][xfooter] _ FlipY[ "DrXHead"]; tiles.nconn [decoder][blank] _ Get[ "DPlaDrBlank6" ]; --1 use tiles.conn [in][inPos] _ Get[ "DrInInPos" ]; tiles.conn [in][inNeg] _ Get[ "DrInInNeg" ]; tiles.conn [in][latchA] _ Get[ "DrInA" ]; tiles.conn [in][latchB] _ Get[ "DrInB" ]; tiles.conn [in][latch] _ Get[ "DrLatch" ]; tiles.conn [in][posSing] _ Get[ "DrInPosSing" ]; tiles.conn [in][negSing] _ Get[ "DrInNegSing" ]; tiles.conn [in][posDual] _ Get[ "DrInPosDual" ]; tiles.conn [in][negDual] _ Get[ "DrInNegDual" ]; tiles.conn [out][inPos] _ Get[ "DrOutInPos" ]; tiles.conn [out][inNeg] _ Get[ "DrOutInNeg" ]; tiles.conn [out][inGndAB] _ Get[ "DrOutInGndAB" ]; tiles.conn [out][latchA] _ Get[ "DrOutLatchA" ]; tiles.conn [out][latchB] _ Get[ "DrOutLatchB" ]; tiles.conn [out][latch] _ Get[ "DrLatch" ]; tiles.conn [out][gateP] _ Get[ "DrOutPos" ]; tiles.conn [out][gateN] _ Get[ "DrOutNeg" ]; tiles.conn [out][gateNA] _ Get[ "DrOutNegAc" ]; tiles.conn [out][gateNB] _ Get[ "DrOutNegBc" ]; tiles.conn [out][posSing] _ Get[ "DrOutPosSing" ]; tiles.conn [out][negSing] _ Get[ "DrOutNegSing" ]; tiles.conn [out][posDual] _ Get[ "DrOutPosDual" ]; tiles.conn [out][negDual] _ Get[ "DrOutNegDual" ]; driveTop _ CoreLibrary.Get[library, "DrTop"]; driveBot _ CoreFrame.RotateCellType[driveTop, CDOrient.mirrorY]; CoreLibrary.Set[library, "DrBot", driveBot]; RETURN[tiles]}; DrRope: PROC[rec: Drive] RETURNS[rope: ROPE] = { dirRope: ARRAY Dir OF ROPE = [" in", "out"]; polRope: ARRAY Polarity OF ROPE = ["pos", "neg", "unk"]; phRope: ARRAY Ph OF ROPE _ CoreName.PhRope; gateRope: ARRAY DrGate OF ROPE = [" neg", "negAc", "negBc", " pos"]; dualSing: ARRAY BOOL OF ROPE = ["sing", "dual"]; rowType: ARRAY RowType OF ROPE= ["Header", "Xheader", "Footer", "Xfooter", "Conn", "DataUp", "DataDn", "Blank", "Extend"]; SELECT rec.drRowType FROM conn => { rope _ IO.PutFR["%3g %12g %12g", IO.rope[dirRope[rec.drDir]], IO.rope[rec.name], IO.rope[rec.nameInv] ]; rope _ rope.Cat[IO.PutFR[" %g.%g", IO.int[rec.cy], IO.int[rec.idx] ] ]; rope _ rope.Cat[IO.PutFR[" %g", IO.rope[rec.inNm] ] ]; rope _ rope.Cat[IO.PutFR[" %g%g %g%g", IO.rope[polRope [rec.in.pol]], IO.rope[phRope [rec.in.ph]], IO.rope[polRope [rec.ref.pol]], IO.rope[phRope [rec.ref.ph]] ] ]; rope _ rope.Cat[IO.PutFR[" %g %g %g%g", IO.rope[gateRope [rec.gate]], IO.rope[dualSing [rec.dualOut]], IO.rope[polRope [rec.out.pol]], IO.rope[phRope [rec.out.ph]] ] ]}; ENDCASE => rope _ rowType[rec.drRowType]}; GenericDriverName: PUBLIC PROC[drive: Drive] RETURNS[name: ROPE] = { IF drive.drDir = out THEN { IF drive.out.ph=Ac THEN drive.gate _ negAc; IF drive.out.ph=Bc THEN drive.gate _ negBc }; name _ "Drive"; name _ name.Cat[IF drive.drDir = in THEN "In" ELSE "Out"]; name _ name.Cat[IF drive.ref.pol=drive.in.pol THEN "Pos" ELSE "Neg"]; name _ name.Cat[SELECT drive.ref.ph FROM A => "A", B => "B", unk => "GndAB", ENDCASE => ERROR]; name _ name.Cat[SELECT drive.gate FROM neg => "Neg", negAc => "NAc", negBc => "NBc", pos => "", ENDCASE => ERROR]; name _ name.Cat[ IF (drive.ref.pol=drive.out.pol)=(drive.gate=pos) THEN "Pos" ELSE "Neg"]; name _ name.Cat[IF drive.dualOut THEN "Dual" ELSE "Sing"]}; CapDrives: PUBLIC PROC[drives: Drives, sIn, altOut: ROPE _ NIL] RETURNS[newDrives: Drives, sOut: ROPE _ NIL] = { sOut _ ConnectDrives[drives, sIn]; newDrives _ CONS[NEW[DriveRec _ [drRowType: xfooter, inSh: sIn, outSh: sIn]], drives]; FOR drives _ newDrives, drives.rest WHILE drives.rest#NIL DO ENDLOOP; sOut _ IF altOut#NIL THEN altOut ELSE drives.first.outSh; drives.first.outSh _ sOut; drives.rest _ CONS[NEW[DriveRec _ [drRowType: xheader, inSh: sOut, outSh: sOut]], NIL]}; RefToDriverFrame: PUBLIC PROC[name: ROPE, refRec: REF, initial: DriveRec] RETURNS[cell: CellType, outSh: ROPE]= { top, bot: Drive; drName: ROPE _ IF initial.drDir = in THEN name.Cat["In"] ELSE name.Cat["Out"]; [cell, outSh] _ RefToDriverFrameBasic[drName, refRec, initial]; top _ NEW[DriveRec _ [drRowType: xheader, inSh: outSh, outSh: outSh]]; bot _ NEW[DriveRec _ [drRowType: xfooter, inSh: initial.inSh, outSh: initial.inSh]]; cell _ CoreFrame.NewFrameCells[ name: name, rec: [first: top], cells: LIST[ CellProc[name: DrRope[top], data: top], cell, CellProc[name: DrRope[bot], data: bot] ] ] }; RefToDriverFrameBasic: PUBLIC PROC [name: ROPE, refRec: REF, initial: DriveRec] RETURNS[cell: CellType, outSh: ROPE]= { drives: Drives _ RefToDrives[refRec, initial]; outSh _ ConnectDrives[drives]; cell _ DrivesToFrame[name, drives]}; RefToDrives: PUBLIC PROC [refRec: REF, initial: DriveRec] RETURNS[drives: Drives]= { dualOut: BOOL _ FALSE; bitForm: REFBit.Format _ REFBit.Desc[refRec].bitForm; FOR bit: INT DECREASING IN [0..bitForm.size) DO inverted: BOOL; drive: Drive _ NEW[DriveRec _ initial]; [drive.name, drive.nameInv, dualOut, inverted, drive.cy, drive.idx] _ CoreName.NormalFormatNames[bitForm[bit]]; drive.dualOut _ initial.dualOut OR dualOut; IF inverted THEN drive.in.pol _ SELECT drive.in.pol FROM pos=>neg, neg=>pos, ENDCASE=>ERROR; drive.outSh _ DriveName[drive, outSh]; drives _ CONS[drive, drives]; ENDLOOP}; LatchPh: PUBLIC PROC[ph: Ph] RETURNS[latch: Ph] = { latch _ SELECT ph FROM A, AB, ABB, ABBB, Bc => A, B, BA, BAA, BAAA, Ac => B, ENDCASE => unk}; SpecificDrive: PUBLIC PROC[dir: Dir, in: ROPE, out: ROPE, inverted, dual: BOOL _ FALSE] RETURNS[dr: IFUCoreDrive.Drive] = { sigIn: CoreName.SigRec _ CoreName.NameSig[in]; sigOut: CoreName.SigRec _ CoreName.NameSig[out]; clocked: BOOL _ SELECT sigOut.ph FROM Ac, Bc=>TRUE, ENDCASE=>FALSE; dr _ NEW[ IFUCoreDrive.DriveRec _ [ name: sigOut.root, inNm: in, drDir: dir, gate: SELECT sigOut.ph FROM Ac=>negAc, Bc=>negBc, ENDCASE=>pos, idx: sigOut.idx, cy: sigOut.cy, dualOut: dual, in: [ph: sigIn.ph ], ref: [ph: LatchPh[ sigOut.ph ] ], out: [ph: sigOut.ph, pol: pos ] ]]; IF dr.ref.ph=unk THEN RETURN[dr]; SELECT dir FROM in => IF ~inverted THEN {dr.in.pol _ pos; dr.ref.pol _ neg} ELSE {dr.in.pol _ neg; dr.ref.pol _ neg}; out => SELECT TRUE FROM ~inverted AND ~clocked => {dr.in.pol _ pos; dr.ref.pol _ neg; dr.gate _ pos}; inverted AND ~clocked => {dr.in.pol _ neg; dr.ref.pol _ pos; dr.gate _ neg}; ~inverted AND clocked => {dr.in.pol _ pos; dr.ref.pol _ pos}; inverted AND clocked => {dr.in.pol _ pos; dr.ref.pol _ neg}; ENDCASE => ERROR; ENDCASE}; AdjustDriveOutPh: PUBLIC PROC[drives: Drives, names: ROPE] = { ris: IO.STREAM _ IO.RIS[names]; DO drive: Drive; signal: CoreName.SigRec; item: ROPE _ ris.GetTokenRope[! IO.EndOfStream => EXIT].token; signal _ CoreName.NameSig[item]; drive _ FindSignalDrive[signal, drives]; drive.ref.ph _ unk; drive.out.ph _ unk; ENDLOOP; ris _ IO.RIS[names]; DO drive: Drive; signal: CoreName.SigRec; item: ROPE _ ris.GetTokenRope[! IO.EndOfStream => EXIT].token; signal _ CoreName.NameSig[item]; drive _ FindSignalDrive[signal, drives]; IF signal.not THEN drive.dualOut _ TRUE; drive.idx _ signal.idx; drive.cy _ signal.cy; IF drive.ref.ph#unk AND drive.ref.ph#LatchPh[signal.ph] THEN Signal[]; IF drive.out.ph#unk AND drive.out.ph#signal.ph THEN Signal[]; drive.ref.ph _ LatchPh[signal.ph]; drive.out.ph _ signal.ph; ENDLOOP}; FindSignalDrive: PROC[sig: CoreName.SigRec, drives: Drives] RETURNS[drive: Drive] = { FOR drives _ drives, drives.rest WHILE drives # NIL DO IF drives.first.name = sig.root THEN { IF drives.first.cy#-1 AND drives.first.cy#sig.cy THEN LOOP; IF drives.first.idx#-1 AND drives.first.idx#sig.idx THEN LOOP; RETURN[drives.first]}; IF drives.first.nameInv = sig.root THEN { IF drives.first.cy#-1 AND drives.first.cy#sig.cy THEN LOOP; IF drives.first.idx#-1 AND drives.first.idx#sig.idx THEN LOOP; RETURN[drives.first]}; ENDLOOP; drive _ NIL; Signal[]}; ConnectDrives: PUBLIC PROC [drives: Drives, inSh: ROPE _ NIL] RETURNS[outSh: ROPE] = { outSh _ inSh; FOR list: Drives _ drives, list.rest WHILE list#NIL DO list.first.inSh _ IF outSh#NIL THEN outSh ELSE list.first.inSh; list.first.outSh _ IF list.first.drRowType#conn THEN list.first.inSh ELSE list.first.outSh; outSh _ list.first.outSh; ENDLOOP}; DrivesToFrame: PUBLIC PROC [name: ROPE, drives: Drives] RETURNS[cell: CellType]= { cnt: INT _ 0; frame: CoreFrame.Frame; FOR list: Drives _ drives, list.rest WHILE list#NIL DO cnt _ cnt+1 ENDLOOP; cell _ CoreFrame.NewFrameCell[cnt, name, [first: bottom]]; frame _ CoreFrame.FCT[cell]; FOR bit: INT IN [0..cnt) DO frame.seq[bit] _ CellProc[DriveName[drives.first, out], drives.first]; drives _ drives.rest ENDLOOP}; DriveName: PUBLIC PROC[drive: Drive, type: DrNmType _ unk] RETURNS[ name: ROPE] = { relSig: CoreName.RelativeSignal; inv: BOOL _ SELECT type FROM nin, nref, nout, ninSh, noutSh=>TRUE, ENDCASE=>FALSE; IF type=unk THEN type _ IF drive.drDir=in THEN in ELSE out; SELECT type FROM inSh => RETURN[drive.inSh]; outSh => RETURN[CoreName.RopeNm[Rope.Cat["drShOut", DriveName[drive, nref]]]]; ninSh => Signal[]; -- {RETURN[Rope.Cat["Not", drive.inSh]]}; noutSh => Signal[]; -- {RETURN[Rope.Cat["Not", drive.outSh]]}; in => {IF drive.inNm#NIL THEN RETURN[drive.inNm]; relSig _ drive.in}; nin => {IF drive.inNm#NIL THEN Signal[]; relSig _ drive.in}; ref, nref => relSig _ drive.ref; out, nout => relSig _ drive.out; ENDCASE => ERROR; IF drive.drRowType#conn THEN name _ DrRope[drive] ELSE { [inv, name] _ CoreName.SelectName[(relSig.pol=neg)#inv, drive.name, drive.nameInv]; name _ CoreName.SigName[[inv, name, relSig.ph, drive.cy, drive.idx]]}; name _ CoreName.RopeNm[name]}; FindDrive: PUBLIC PROC[drives: Drives, name: ROPE] RETURNS[drive: Drive] = { FOR drives _ drives, drives.rest WHILE drives # NIL DO driveNm: ROPE _ DriveName[drives.first]; IF Rope.Equal[name, DriveName[drives.first]] THEN RETURN[drives.first] ENDLOOP; RETURN[NIL]}; ReverseDrives: PUBLIC PROC[drives: Drives] RETURNS[new: Drives] = { FOR drives _ drives, drives.rest WHILE drives#NIL DO new _ CONS[drives.first, new] ENDLOOP}; log: IO.STREAM _ CoreFrame.GetLog[]; END. xIFUCoreDriveImpl.mesa, Copyright c 1986 by Xerox Corporation. All rights reserved. Last Edited by Curry, June 26, 1986 12:25:51 pm PDT OldExpand: CoreFrame.ExpandProc = { drive: Drive _ NARROW[frameCT.data]; frame: REF CoreFrame.FrameRec _ NEW[CoreFrame.FrameRec _ [first: left]]; public: CoreName.Context _ CoreName.NewContext[]; genericDriver: CellType _ GetGenericDriver[drive]; driverName: ROPE _ DriveName[drive, out]; pas: LIST OF CoreCreate.PA; eachWire: CoreOps.EachWireProc = { specificName: ROPE; specific: Wire; IF wire.size#0 THEN RETURN; specificName _ SpecificNames[CoreName.WireNm[wire].n, drive ]; IF specificName=NIL THEN Signal[]; specific _ CoreName.CtxWire[public, specificName ]; pas _ CONS[ [wire, specific], pas]}; [ ] _ CoreOps.VisitWire[genericDriver.public, eachWire]; frame.cell _ CoreCreate.Cell[ public: CoreName.WireFromCtx[public], onlyInternal: NIL, instances: LIST[CoreCreate.InstanceList[genericDriver, pas]], name: driverName ]; public _ CoreName.KillContext[public]; CoreBlock.PutCellSide[frame.cell, CoreFrame.SideSides[frame.first]]; CoreBlock.MergeSides[frame.cell]; PWCore.SetAbutX[frame.cell]; frame.seq _ NEW[CoreFrame.FrameSeq[0]]; frameCT.data _ frame; frameCT.class _ CoreFrame.frameCellClass; CoreFrame.SetFrameExpandProc[soft, frameCT, NIL]; CoreFrame.SetFrameExpandProc[hard, frameCT, NIL]}; DriverFill: PUBLIC PROC RETURNS[frame: Frame] = { frame _ CDF.NewFrame[2, x, CDF.ID["DriverFill"]]; frame[0] _ CDF.Glue[]; frame[1] _ CDF.NewObjectFrame[DriverCell[static, extend]]}; DriverExt: PUBLIC PROC[up: BOOL _ FALSE] RETURNS[frame: Frame] = { frame _ CDF.NewFrame[2, x, CDF.ID["DriverFill"]]; frame[0] _ IF up THEN CDF.Glue[t:ext, b:conn] ELSE CDF.Glue[t:conn, b:ext]; frame[1] _ CDF.NewObjectFrame[DriverCell[static, extend]]}; BuildDrivers: PUBLIC PROC[frame: Frame, design: CD.Design] = { IF frame.seqSize > 0 THEN FOR index: INT IN [0..frame.seqSize) DO BuildDrivers[frame[index], design] ENDLOOP ELSE { drive: Drive _ NARROW[frame.data]; frame.data _ DriverCell[static, conn, drive, design]; frame.shell _ CDF.ShellFromObject[NARROW[frame.data]]} }; NormalFormatNames name #NIL nameInv =NIL <=> dual FALSE NotFoo becomes Foo with inverted=TRUE Driver Configurations generated by SpecificDrive polarities Input > clk Ouput in ref out Core To Control or Core To Pad (input) Positive inv > inv pos inv pos Negative inv-inv > inv inv inv pos Control To Core or Pad To Core (output) Positive UnClocked inv > pos inv pos inv pos Negative UnClocked inv > inv inv inv pos pos Positive Clocked inv-inv > invClk inv pos pos pos Negative Clocked inv > invClk inv pos inv pos AddDrive: PUBLIC PROC[drive: Drive, drives: Drives] RETURNS[new: Drives] = { found: BOOL _ FALSE; name: ROPE _ IF drive.name # NIL THEN drive.name ELSE drive.nameInv; FOR drives _ drives, drives.rest WHILE drives # NIL DO new _ CONS[drives.first, new]; IF Rope.Equal[name, drives.first.name] OR Rope.Equal[name, drives.first.nameInv] THEN {new _ CONS[drive, new]; found _ TRUE} ENDLOOP; IF NOT found THEN new _ CONS[drive, new]; new _ ReverseDrives[new]}; ReplaceDrive: PUBLIC PROC[drive: Drive, drives: Drives] RETURNS[new: Drives] = { found: BOOL _ FALSE; name: ROPE _ IF drive.name # NIL THEN drive.name ELSE drive.nameInv; FOR drives _ drives, drives.rest WHILE drives # NIL DO IF Rope.Equal[name, drives.first.name] OR Rope.Equal[name, drives.first.nameInv] THEN {new _ CONS[drive, new]; found _ TRUE} ELSE {new _ CONS[drives.first, new]} ENDLOOP; IF NOT found THEN Signal[]; new _ ReverseDrives[new]}; DelDrive: PUBLIC PROC[drive: Drive, drives: Drives] RETURNS [new: Drives] = { found: BOOL _ FALSE; name: ROPE _ IF drive.name # NIL THEN drive.name ELSE drive.nameInv; FOR drives _ drives, drives.rest WHILE drives # NIL DO IF Rope.Equal[name, drives.first.name] OR Rope.Equal[name, drives.first.nameInv] THEN found _ TRUE ELSE new _ CONS[drives.first, new] ENDLOOP; IF NOT found THEN Signal[]; new _ ReverseDrives[new]}; TestProc: PROC[name: ROPE] = { cellName: ROPE _ "Testee"; refRec: REF _ name; initial: DriveRec _ [ name: NIL, nameInv: NIL, drDir: in, gate: pos, dualOut: FALSE, inSh: "testShDataIn", in: [pol: pos, ph: A, cycle: 0], ref: [pol: pos, ph: A, cycle: 0], out: [pol: pos, ph: AB, cycle: 0], pass: FALSE, plaType: static, drRowType: conn ]; cell: CellType _ RefToDriverFrame[cellName, refRec, initial].cell; CoreFrame.Expand[cell]; [ ] _ CoreConnect.Connect[cell]; cell _ CoreOps.Recast[cell]; CoreOps.PrintCellType[cell, log]; [ ] _ PW.Draw[PWCore.Layout[cell]] }; TestProc[ "Test.TestRec" ]; ÊK˜šœ™Jšœ<™™>Jšœœœ ™"Jšœ4™4Jšœœ™&—Jšœ8™8šœ™Jšœ&™&Jšœœ™Jšœ œ.™>Jšœ™—Jšœ(™(Jšœ,Ÿ œ™DJšœ!™!Jšœ™Jšœœ™)Jšœ™Jšœ)™)Jšœ,œ™1šœ,œ™2J™——šžœœ˜$Jšœ˜$Jšœœ˜Jšœœ˜šœ œ˜Jšœœœ˜C—Jšœ8˜8Jšœ œ˜,šœœ˜šœ˜Jšœœ#œ ˜N—Jšœ+˜1—Jšœ'˜'šœ œ ˜Jšœ˜Jšœ ˜—Jšœ6˜6šœœœ˜Jšžœœ!œ+˜ZJšœœœ˜šœÏc,˜@JšœŸœ˜šœ˜šœ˜JšœŸœ˜JšœŸœ˜—šœ˜JšœŸœ˜JšœŸœ˜———JšœŸœ˜ šœœœ ˜-Jšœ Ÿœ˜Jšœ Ÿœ˜JšœŸœ˜JšœŸœ˜Jšœœ˜—šœ˜šœ˜šœ/˜1JšœŸœ˜JšœŸœ˜——š˜šœ/˜1JšœŸœ˜JšœŸœ˜———šœ&˜&Jšœœœœ˜@—Jšœ5˜5Jšœ%¡.˜S—Jšœ1˜1šœœœ˜Jšœ=˜=šœ ˜ Jšœ-˜-Jšœœ˜šœ œ˜šœ2˜2Jšœ˜—Jšœ!˜!—Jšœ˜—Jšœ˜JšœB˜BJšœ$˜$Jšœ0˜0Jšœ'¡.˜UJ˜——Jšœ œ˜&Jšœ œ˜&Jšœ œ˜'Jšœ œ˜)Jšœ œ˜)Jšœ œ˜.Jšœ œ ˜1Jšœœ!˜3J˜šž œœœ œ˜7Jšœ œ˜šœ œ ˜JšœŸ œ ˜(Jšœž œ ˜*Jš œ œœœž œ ˜@šœœœ˜Jš œ œœ œ œ ˜;Jšœ*˜*Jšœ œœ œ˜1Jšœ œœ œ˜2Jšœ œ˜—Jšœœ œœ ˜MJš œœ œœœ ˜OJšœ˜—Jšœ œœ'˜;—J˜Jšœ œ œ˜ J˜šžœ œœœ˜=šžœœœœ˜/Jšœ(˜(—šžœœœœ˜2Jšœœ&˜0Jšœœ8˜?Jšœ&˜&Jšœœœœ˜Jšœœ˜0Jšœ&˜&—Jšœ˜Jšœ˜Jšœ4˜4Jšœœœœ ˜,Jšœ)˜)Jšœœ ˜(Jšœœ˜'Jšœœ˜(J˜Jšœ3˜3Jšœ4˜4Jšœ5˜5Jšœ3˜3JšœC˜CJšœC˜CJšœ4˜4Jšœ6˜6J˜Jšœ2˜2Jšœ/˜/Jšœ0˜0Jšœ.˜.Jšœ7˜7Jšœ7˜7Jšœ3˜3Jšœ1˜1J˜Jšœ5˜5Jšœ2˜2Jšœ3˜3Jšœ7˜7Jšœ=˜=Jšœ<˜J˜Jšœ/˜/Jšœ/˜/Jšœ,˜,Jšœ,˜,Jšœ-˜-Jšœ3˜3Jšœ2˜2Jšœ2˜2Jšœ2˜2J˜Jšœ1˜1Jšœ1˜1Jšœ4˜4Jšœ2˜2Jšœ3˜3Jšœ.˜.Jšœ/˜/Jšœ/˜/Jšœ1˜1Jšœ1˜1Jšœ4˜4Jšœ4˜4Jšœ4˜4Jšœ4˜4J˜Jšœ-˜-Jšœ@˜@Jšœ0˜0Jšœ ˜—J˜šžœœ œœ˜0Jšœ œœœ˜-Jšœ œ œœ˜8Jšœœœœ˜-Jšœ œœœ(˜FJš œ œœœœ˜1šœ œ œœ˜JšœZ˜Z—šœ˜šœ ˜ šœœ˜ Jšœ˜Jšœ˜Jšœ˜—šœœ˜"Jšœ ˜Jšœ˜—šœœ˜!Jšœ˜—šœœ˜*Jšœ˜Jšœ˜Jšœ˜Jšœ˜!—šœœ˜+Jšœ˜Jšœ˜ Jšœ˜Jšœ ˜"——Jšœ#˜*——J˜šœ1™1Jšœ2™2Jšœ™Jšœ;™;—šœB™BJšœ2™2JšœK™KJšœ;™;—J˜šœ>™>šœ™šœ)™)Jšœ-™-—šœ™Jšœ"™"Jšœ5™5Jšœ9™9———J˜š žœœœœœ˜Dšœœ˜Jšœœ˜+Jšœœ˜-—Jšœ˜Jšœœœœ˜>Jšœœœœ˜Fšœœ ˜#Jšœ%œœ˜;—šœœ ˜&Jšœ˜Jšœ˜Jšœ˜Jšœ ˜ Jšœœ˜—šœ˜Jšœ1œœ˜J—Jšœœœœ ˜@—J˜šž œ œœœ˜?Jšœ œ˜0Jšœ"˜"Jšœ œœŸœ#˜VJšœ!œ œœ˜EJš œœœœœ˜9Jšœ˜Jš œœœŸœœ˜X—J˜š žœœœœ œ˜IJšœœ˜'Jšœ˜šœœœ˜$Jšœ˜Jšœ˜—Jšœ?˜?Jšœœ?˜HJšœœL˜Ušœ!˜!Jšœ ˜ Jšœ˜šœœ˜ Jšœ'˜'Jšœ˜Jšœ-˜-———J˜š žœœœœ œ˜OJšœœ˜'Jšœ.˜.Jšœ!˜!Jšœ'˜'—J˜šž œœœ œ˜9Jšœ˜Jšœ œœ˜Jšœ5˜5š œœ œœ˜/Jšœ˜Jšœœ˜(šœE˜EJšžœ˜)—Jšœ œ ˜+šœ œœ ˜3Jšœœœ˜(—Jšœ'˜'Jšœ œ˜Jšœ˜ ——J™šž™Jšœ ™ J™J™%—J˜šžœœœ œ˜3šœœ˜Jšœœœœ ˜Jšœœœœ ˜Jšœ ˜—J˜—šŸ0™0JšŸ"™"JšŸ+™+™'J™-J™0—™(J™5J™5J™9J™6J™——š Ÿ œ œœœ œ˜WJšœ˜#Jšœ/˜/Jšœ0˜0Jš œ œœ œ œœœ˜Cšœœ˜%Jšœ˜Jšœ ˜ Jšœ ˜ Jšœœ œœ˜@Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ"˜"Jšœ'˜'—Jšœœœ˜!šœ˜šœœ ˜Jšœ,˜0Jšœ,˜0—šœœœ˜Jšœ œA˜NJšœ œ@˜NJšœ œ3˜@Jšœ œ3˜AJšœœ˜—Jšœ˜ ——J˜šžœœœœ˜>Jš œœœœœ˜š˜Jšœ˜Jšœ˜Jšœœœœ˜?Jšœ ˜ Jšœžœ˜(Jšœ˜Jšœ˜Jšœ˜—Jšœœœ˜š˜Jšœ˜Jšœ˜Jšœœœœ˜?Jšœ ˜ Jšœžœ˜(Jšœ œœ˜(Jšœ˜Jšœ˜Jšœœ!œ ˜FJšœœœ ˜@Jšœ"˜"Jšœ˜Jšœ˜ ——J˜šžœœ&˜;Jšœ˜šœœ œ˜6šœ˜&Jšœœœœ˜Jšœ˜—šœ!˜)Jšœœœœ˜Jšœ˜—Jšœ˜—Jšœœ ˜—J˜šž œœœœœœœ˜VJšœœ˜ šœ"œœ˜6Jš œœœœ œ˜GJšœœœœ˜[Jšœ˜Jšœ˜ ——J˜šž œœœœ˜7Jšœ˜Jšœœ˜Jšœ˜Jš œ"œœœ œ˜KJšœ;˜;Jšœ˜šœœ ˜Jšœž œ#˜FJšœœ˜——J˜š ž œœœ%œœ˜SJšœ ˜ Jš œœœœ!œœœ˜RJš œ œœœœ˜;šœ˜Jšœ œ ˜Jšœ œ?˜OJšœ¡)˜=Jšœ¡*˜>Jš œ œ œœœ"˜HJšœ œ œœ"˜AJšœ ˜ Jšœ ˜ Jšœœ˜—šœ˜Jšœ˜šœ˜JšœS˜SJšœF˜F——Jšœ˜—J˜š ž œœœœœ˜Lšœœ œ˜6Jšœ œž œ˜(Jšœ+ œœ˜O—Jšœœ˜ —J˜šž œ œœ˜Cšœœœ˜4Jšœœœ˜'——J˜šžœœœœ™LJšœœœ™Jš œœœœœ œ™Ešœœ œ™6Jšœœ™šœ%œ(™UJšœœœœ™/——Jšœœœœ ™)Jšœ™—J˜šž œœœœ™PJšœœœ™Jš œœœœœ œ™Ešœœ œ™6šœ%œ'™PJšœœœ™,Jšœœœ™-——Jšœœœ ™Jšœ™—J˜šžœœœœ™MJšœœœ™Jš œœœœœ œ™Ešœœ œ™6šœ%œ'™PJšœ ™Jšœœœ™+——Jšœœœ ™Jšœ™J™—Jšœœœ˜$J˜šžœœœ™Jšœ œ ™Jšœœ ™šœ™Jšœœ™ Jšœ œ™Jšœ ™ Jšœ ™ Jšœ œ™Jšœ™Jšœ#™#Jšœ#™#Jšœœ ™$Jšœœ™Jšœ™Jšœ™—JšœB™BJšœ™Jšœ™ Jšœ™Jšœ!™!Jšœœ™%—J™Jšœ™J˜Jšœ˜—J™—…—MyÛ