<> <> <> <<>> 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]}; <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <<[ ] _ CoreOps.VisitWire[genericDriver.public, eachWire];>> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <<>> 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]}; <> <> <> <> <> <> <> <> <> < 0>> <> <> <> <> <> <> 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}; <<>> <> <> < dual FALSE>> <> 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}; <> << polarities>> << Input > clk Ouput in ref out>> <> < inv pos inv pos>> < inv inv inv pos>> <> < pos inv pos inv pos>> < inv inv inv pos pos>> < invClk inv pos pos pos>> < invClk inv pos inv pos>> <<>> 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}; <> <> <> <> <> <> <<{new _ CONS[drive, new]; found _ TRUE} ENDLOOP;>> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <<>> log: IO.STREAM _ CoreFrame.GetLog[]; <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <<[ ] _ CoreConnect.Connect[cell];>> <> <> <<[ ] _ PW.Draw[PWCore.Layout[cell]] };>> <<>> <> END. <<>>