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Û