DIRECTORY Basics, CD, CDFrame, CDPinObjects, IO, PLAOps, PW, IFUPW, IFUPWControl, REFBit, Rope, SymTab, ViewerClasses; IFUPWContPLA: CEDAR PROGRAM IMPORTS Basics, CD, CDFrame, CDPinObjects, IFUPW, IFUPWControl, IO, PLAOps, PW, REFBit, Rope EXPORTS IFUPWControl = BEGIN OPEN IFUPWControl; MakePLA: PUBLIC PROC [ name: ROPE, plaType: PLAType, drIn, drInClk, plaIn, drOutClk, drOut: Ph_unk, design: CD.Design, orCols: INT_0, termCols: INT_1, fullWidthTerms: BOOL_FALSE, termsPerHeader: INT _ 1000] RETURNS[new: Frame] = { fileName: ROPE _ Rope.Cat["IFUPLA", name, ".ttt"]; desc: IFUPWControl.PLADescription; plaFm, outFm, inFm: Frame; pla: PLAOps.PLA _ PLAOps.ReadPLAFile[fileName, log]; IF plaType = precharged AND termsPerHeader=1000 THEN termsPerHeader_20; outFm _ DrPLA[name, pla, plaType, plaIn, drOutClk, drOut]; desc _ NARROW[outFm.data]; plaFm _ DrivenPLA[ outFm, design, orCols, termCols, fullWidthTerms, termsPerHeader]; inFm _ RefToDriverFrame[name: name.Cat["InDrs"], xory: y, data: NIL, unordered: FALSE, refRec: pla.data, initial: [drDir: in, dualOut: TRUE, in:[pos, drIn], ref:[pos, drInClk], out:[pos, plaIn] ] ]; IF plaType # precharged THEN DeleteUnusedStaticInDrs[desc, inFm]; new _ IFUPW.NFS[name, x, LIST[ CDFrame.Glue[l: ext, r: conn], IFUPW.NFS[name.Cat["Main"], y, LIST[ plaFm, IFUPW.NFS[name.Cat["InputsSBDr"], x, LIST[ CDFrame.Glue[t: conn, r: conn], inFm ] ] ] ] ] ] }; DrPLA: PUBLIC PROC [name: ROPE, pla: PLAOps.PLA, plaType: PLAType, plaIn, plaOut, drOut: Ph_unk] RETURNS[new: Frame] = { desc: REF PLADescriptionRec _ NEW[PLADescriptionRec]; inForm: REFBit.Format _ REFBit.Desc[pla.data].bitForm; outForm: REFBit.Format _ REFBit.Desc[pla.out].bitForm; new _ IFUPWControl.RefToDriverFrame[ name: name, xory: y, data: desc, unordered: TRUE, refRec: pla.out, initial: [drDir: out, in: [neg, plaOut], ref: [pos, plaOut], out: [pos, drOut] ] ]; new _ new[1]; -- throw away xheader and xfooter frames desc.ttt _ pla; desc.name _ name; desc.plaType _ plaType; desc.drFrame _ new; -- can change FOR i: CARDINAL DECREASING IN [0..inForm.size) DO namePos: ROPE _ BitNameToSigName[inForm[i].name]; nameInv: ROPE _ BitNameToSigName[inForm[i].nameInv]; desc.plaInNames _ CONS[ SignalName[TRUE, namePos, nameInv, plaIn], desc.plaInNames]; desc.plaInNames _ CONS[ SignalName[FALSE, namePos, nameInv, plaIn], desc.plaInNames]; ENDLOOP; FOR i: CARDINAL DECREASING IN [0..outForm.size) DO namePos: ROPE _ BitNameToSigName[outForm[i].name]; nameInv: ROPE _ BitNameToSigName[outForm[i].nameInv]; desc.plaOutNames _ CONS[ SignalName[FALSE, namePos, nameInv, plaOut], desc.plaOutNames]; ENDLOOP}; DrivenPLA: PUBLIC PROC [ drFrame: Frame, design: CD.Design, orCols: INT_0, termCols: INT_1, fullWidthTerms: BOOL_FALSE, termsPerHeader: INT _ 1000] RETURNS [new: Frame] = { desc: REF PLADescriptionRec _ NARROW[drFrame.data]; log.PutRope["\n"]; desc.design _ design; desc.drFrame _ drFrame; desc.nofOrCols _ MAX[orCols, desc.nofOrCols]; desc.nofTermCols _ MAX[termCols, desc.nofTermCols]; desc.termsPerHeader _ MIN[termsPerHeader, desc.termsPerHeader]; desc.fullWidthTerms _ fullWidthTerms OR desc.fullWidthTerms; BuildSignalOrderListFromDrFrame[desc]; BuildConnTranslationArray[desc]; SELECT desc.plaType FROM precharged => MakePreChargedPLA[desc]; ENDCASE => MakeStaticPLASection[desc]; new _ CDFrame.NewFrame[2, x, desc.name.Cat["-PlaDr"] ]; new[0] _ CDFrame.NewObjectFrame[desc.cell]; new[1] _ desc.drFrame; log.PutRope["\n"]}; BuildSignalOrderListFromDrFrame: PUBLIC PROC[desc: REF PLADescriptionRec] = { proc: CDFrame.EnumProc = { rec: REF DriveRec _ NARROW[frame.data]; name: ROPE _ BitNameToSigName[rec.name]; nameInv: ROPE _ BitNameToSigName[rec.nameInv]; desc.drSignalOrder _ CONS[ SignalName[FALSE, name, nameInv, rec.in.ph], desc.drSignalOrder]}; CDFrame.EnumFrameBotOnly[desc.drFrame, proc]; desc.drSignalOrder _ ReverseList[desc.drSignalOrder]}; BuildConnTranslationArray: PROC [desc: PLADescription ] = { index: INT _ -1; smlOutNames: LIST OF ROPE; log.PutRope["\n Building pla translation array"]; desc.connSeq _ NEW[ConnSeq[ListLength[desc.drSignalOrder]]]; FOR list: LIST OF ROPE _ desc.drSignalOrder, list.rest WHILE list#NIL DO pos: INT _ ListItemIndex[desc.plaInNames, list.first]; index _ index+1; IF pos#-1 THEN { desc.connSeq[index] _ [index: pos/2, isOutput: FALSE, isLeftSide: (pos MOD 2 = 0)]; LOOP}; pos _ ListItemIndex[desc.plaOutNames, list.first]; IF pos=-1 THEN ERROR; -- Signal name not found; smlOutNames _ CONS[list.first, smlOutNames]; desc.connSeq[index] _ [index: pos, isOutput: TRUE, isLeftSide: FALSE]; ENDLOOP; smlOutNames _ ReverseList[smlOutNames]; desc.smlToBigOut _ NEW[XsFormSeqRec[ListLength[smlOutNames]]]; FOR i: CARDINAL IN [0..desc.smlToBigOut.size) DO desc.smlToBigOut[i] _ ListItemIndex[desc.plaOutNames, ListIndexItem[smlOutNames, i]] ENDLOOP; desc.plaOutNames _ smlOutNames; IF desc.drFrame#NIL THEN { index: INT _ 0; proc: CDFrame.EnumProc = { desc.connSeq[index].dr _ NARROW[frame.data]; index _ index+1}; CDFrame.EnumFrameBotOnly[desc.drFrame, proc]} }; ZeroUnusedTTTOutputs: PROC [desc: PLADescription ] = { maskTerm: PLAOps.Term _ PLAOps.CopyTerm[desc.ttt.termList.begin]; log.PutRope["\n Zero unused TTT outputs"]; FOR i: CARDINAL IN [0..maskTerm.out.wdSize) DO maskTerm.out[i] _ PLAOps.initOutQrtWz ENDLOOP; FOR index: INT IN [0..desc.smlToBigOut.size) DO pos: INT _ desc.smlToBigOut[index]; PLAOps.SetOutQrt[one, maskTerm, REFBit.Desc[desc.ttt.out].bitForm[pos].firstBit] ENDLOOP; FOR term: PLAOps.Term _ desc.ttt.termList.begin, term.next WHILE term#NIL DO FOR i: CARDINAL IN [0..maskTerm.out.wdSize) DO term.out[i].d _ Basics.BITAND[term.out[i].d, maskTerm.out[i].d] ENDLOOP ENDLOOP }; CheckPLACompress: PROC [desc: PLADescription ] = { IF desc.doCompleteSum THEN { [ ] _ PLAOps.ConvertTermListToCompleteSum[ list: desc.ttt.termList, addMerges: desc.csAddMerges, addConsensus: desc.csAddConsensus, log: log ]}; IF desc.doMinimization THEN { [ ] _ PLAOps.FindAMinimalCover[ list: desc.ttt.termList, time: desc.timeOutMinutes, log: log ]} }; ToRopeList: PROC [ refList: LIST OF REF ] RETURNS [ ropeList: LIST OF ROPE ] = { FOR l: LIST OF REF _ refList, l.rest UNTIL l = NIL DO IF l.first # NIL AND NOT ISTYPE[l.first, ROPE] THEN ERROR; ENDLOOP; TRUSTED {ropeList _ LOOPHOLE[refList]} }; MakePreChargedPLA: PROC[desc: PLADescription] = { ZeroUnusedTTTOutputs [desc]; CheckPLACompress [desc]; DefinePLARows [desc]; MakeOutDrs [desc]; MakePla [desc]}; PreChargedParams: TYPE = RECORD[ minConnSpace: INT _ 2, -- SPACING rows between driver rows; insPerExtra: INT _ 10, -- SPACING cols between extra columns; outsPerExtra: INT _ 10, nextTerm: PLAOps.Term _ NIL, -- specific parameter nextConn: INT _ 0, -- specific parameter rows: REF RowsRec _ NIL ]; -- specific parameter RowsRec: TYPE = RECORD[SEQUENCE size: CARDINAL OF REF RowRec]; RowRec: TYPE = RECORD[ dr: REF DriveRec, type: RowType, and: ColSeqRef, or: ColSeqRef ]; ColSeqRef: TYPE = REF ColSeqRec; ColSeqRec: TYPE = RECORD[SEQUENCE size: CARDINAL OF NormalCellType]; DefinePLARows: PROC [desc: PLADescription] = { pp: REF PreChargedParams _ NEW[PreChargedParams _ [nextTerm: desc.ttt.termList.begin]]; firstRow: BOOL _ TRUE; index: INT _ 0; termUp: BOOL _ TRUE; nofOuts: INT _ MAX[ListLength[desc.plaOutNames], desc.nofOrCols]; nofIns: INT _ ListLength[desc.plaInNames]; cRowsLeft: INT _ ListLength[desc.drSignalOrder]; dRowsLeft: INT _ desc.ttt.termList.length; hRowsLeft: INT; dRowsLeft _ MAX[dRowsLeft, cRowsLeft*(pp.minConnSpace)]; hRowsLeft _ MAX[1, (dRowsLeft+ desc.termsPerHeader/2)/desc.termsPerHeader]; log.PutRope["\n Assign precharged pla row types"]; desc.data _ pp; desc.nofAndCols _ nofIns/2 + (nofIns/2 -1) / pp.insPerExtra; desc.nofOrCols _ nofOuts + (nofOuts -1) / pp.outsPerExtra; pp.rows _ NEW[RowsRec[cRowsLeft+dRowsLeft+2*hRowsLeft]]; WHILE hRowsLeft#0 DO -- actually one more header is appended afterwards RperH: INT _ (cRowsLeft+dRowsLeft+hRowsLeft + hRowsLeft/2)/hRowsLeft; IF firstRow THEN firstRow_FALSE ELSE {pp.rows[index] _ NextRow[desc, xheader]; index_index+1}; pp.rows[index] _ NextRow[desc, header]; index_index+1; RperH_RperH-1; hRowsLeft_hRowsLeft-1; WHILE RperH > 0 DO CperD, DperC: INT; CperD _ MAX[1, (cRowsLeft + dRowsLeft/2)/dRowsLeft]; DperC _ MAX[1, (dRowsLeft + cRowsLeft/2)/cRowsLeft]; IF DperC < pp.minConnSpace OR (CperD>1) AND (pp.minConnSpace>0) THEN ERROR; RperH _ RperH - CperD - DperC; WHILE CperD > 0 DO pp.rows[index] _ NextRow[desc, conn]; index_index+1; cRowsLeft_cRowsLeft-1; CperD_CperD-1; ENDLOOP; termUp _ TRUE; WHILE DperC > 0 DO pp.rows[index] _ NextRow[desc, IF termUp THEN dataUp ELSE dataDn]; index_index+1; dRowsLeft_dRowsLeft-1; DperC_DperC-1; termUp _ NOT termUp; ENDLOOP; ENDLOOP; ENDLOOP; IF index+1#pp.rows.size THEN ERROR; pp.rows[index] _ NextRow[desc, footer]}; NextRow: PROC [desc: PLADescription, type: RowType] RETURNS[row: REF RowRec] = { pp: REF PreChargedParams _ NARROW[desc.data]; andIndex, orIndex, index: INT _ 0; data: PLAOps.Term; conn: Connection; row _ NEW[RowRec _ [type: type]]; row.and _ NEW[ColSeqRec[desc.nofAndCols]]; IF desc.nofOrCols#0 THEN row.or _ NEW[ColSeqRec[desc.nofOrCols]]; SELECT type FROM header => { }; conn => {conn _ NextConnection[desc]; row.dr _ conn.dr}; dataUp, dataDn => { data _ NextDataTerm[desc]; row.dr _ NIL; IF data=NIL THEN type _ row.type _ blank}; ENDCASE; FOR index IN[0..desc.nofAndCols) DO IF (index+1) MOD (pp.insPerExtra+1) = 0 THEN row.and[index] _ extra ELSE { SELECT type FROM dataUp, dataDn => SELECT PLAOps.GetInQrt [data, REFBit.Desc[desc.ttt.data].bitForm[andIndex].firstBit] FROM zero => row.and[index] _ left; one => row.and[index] _ right; ENDCASE => row.and[index] _ nc; conn => IF conn.isOutput OR conn.index#andIndex THEN row.and[index] _ nc ELSE IF conn.isLeftSide THEN row.and[index] _ left ELSE row.and[index] _ right; ENDCASE => row.and[index] _ nc; andIndex_andIndex+1 } ENDLOOP; IF desc.nofOrCols#0 THEN FOR index IN[0..desc.nofOrCols) DO IF (index+1) MOD (pp.outsPerExtra+1) = 0 THEN row.or[index] _ extra ELSE { row.or[index] _ nc; IF orIndex < desc.smlToBigOut.size THEN { IF (type=dataUp OR type=dataDn) AND PLAOps.GetOutQrt [data, REFBit.Desc[desc.ttt.out].bitForm[desc.smlToBigOut[orIndex]].firstBit]=one THEN row.or[index] _ left; IF type=conn AND conn.isOutput AND conn.index=desc.smlToBigOut[orIndex] THEN row.or[index] _ left }; orIndex_orIndex+1 } ENDLOOP}; NextDataTerm: PROC [desc: PLADescription] RETURNS[term: PLAOps.Term] = { pp: REF PreChargedParams _ NARROW[desc.data]; term _ pp.nextTerm; IF term#NIL THEN pp.nextTerm _ pp.nextTerm.next}; NextConnection: PROC [desc: PLADescription] RETURNS[conn: Connection] = { pp: REF PreChargedParams _ NARROW[desc.data]; conn _ desc.connSeq[pp.nextConn]; pp.nextConn _ pp.nextConn+1}; MakeOutDrs: PROC[desc: PLADescription] = { pp: REF PreChargedParams _ NARROW[desc.data]; new: Frame; last: INT _ -1-pp.minConnSpace; cnt: INT _ 0; list: LIST OF Frame; FOR driverIndex: INT IN [0..pp.rows.size) DO SELECT pp.rows[driverIndex].type FROM header, xheader, footer => { IF (driverIndex-last) <= pp.minConnSpace THEN ERROR; last _ driverIndex-pp.minConnSpace}; blank, dataUp, dataDn => { IF (driverIndex-last) <= pp.minConnSpace THEN LOOP}; conn => { IF (driverIndex-last) <= pp.minConnSpace THEN ERROR; last _ driverIndex} ENDCASE => ERROR; list _ CONS[CDFrame.NewObjectFrame[ DriverCell [precharged, pp.rows[driverIndex].type, pp.rows[driverIndex].dr, desc.design]], list]; cnt _ cnt+1; ENDLOOP; new _ CDFrame.NewFrame[cnt, y, desc.name.Cat["-OutDr"]]; FOR ii: INT IN [0..cnt) DO new[ii] _ list.first; list _ list.rest ENDLOOP; desc.drFrame _ new}; MakePla: PROC[desc: PLADescription] = { tiles: REF TileVarieties _ GetPLATiles[ ]; pp: REF PreChargedParams _ NARROW[desc.data]; refPhase: Ph _ unk; rowList: PW.ListOb _ NIL; log.PutRope["\n Assemble precharged pla row cells"]; FOR rowIndex: INT IN [0..pp.rows.size) DO objects: PW.ListOb _ NIL; row: REF RowRec _ pp.rows[rowIndex]; IF pp.rows[rowIndex].dr#NIL THEN refPhase _ pp.rows[rowIndex].dr.ref.ph; objects _ CONS[tiles.glue[row.type][leftSide], objects]; FOR index: INT IN [0..row.and.size) DO objects _ CONS[tiles.and[row.type][row.and[index]], objects] ENDLOOP; IF desc.nofOrCols#0 THEN { objects _ CONS[tiles.glue[row.type][between], objects]; FOR index: INT IN [0..row.or.size) DO objects _ CONS[tiles.or[row.type][row.or[index]], objects] ENDLOOP; objects _ CONS[tiles.glue[row.type][rightSide], objects] }; rowList _ CONS[PW.AbutListX[desc.design, PW.Reverse[objects]], rowList] ENDLOOP; desc.cell _ PW.AbutListY[desc.design, rowList]; ReNamePLAInputPins[desc]}; ReNamePLAInputPins: PROC[desc: PLADescription] = { pp: REF PreChargedParams _ NARROW[desc.data]; tiles: REF TileVarieties _ GetPLATiles[ ]; format: REFBit.Format _ REFBit.Desc[desc.ttt.data].bitForm; leftSize: INT _ CD.InterestSize[tiles.glue[blank][leftSide]].x; andWidth: INT _ CD.InterestSize[tiles.and[blank][nc]].x; extraWidth: INT _ CD.InterestSize[tiles.and[blank][extra]].x; renameProc: IFUPW.PinNameProc ~ { list: LIST OF ROPE _ desc.plaInNames; index: INT; oldRope: Rope.ROPE _ CDPinObjects.GetName[pin]; in0: BOOL _ Rope.Equal[oldRope, "in0"]; in1: BOOL _ Rope.Equal[oldRope, "in1"]; IF NOT(in0 OR in1) THEN RETURN[oldRope]; index _ (pin.location.x - leftSize)/(pp.insPerExtra*andWidth+extraWidth); index _ (pin.location.x - leftSize - extraWidth*index)/andWidth; WHILE index#0 DO list _ list.rest.rest; index _ index-1 ENDLOOP; name _ IF in1 THEN list.rest.first ELSE list.first}; desc.cell _ IFUPW.RenameObjAndPins[desc.design, desc.cell, desc.name, renameProc] }; plaTilesDesign: CD.Design; tileBuffer: REF TileVarieties; TileVarieties: TYPE = RECORD[glue: REF GlueTiles, and, or: REF NormalTiles]; GlueTiles: TYPE = ARRAY RowType OF ARRAY GlueCellType OF CD.Object; GlueCellType: TYPE = {leftSide, between, rightSide}; NormalTiles: TYPE = ARRAY RowType OF ARRAY NormalCellType OF CD.Object; NormalCellType: TYPE = {left, right, nc, extra}; GetPLATiles: PROC RETURNS[tiles: REF TileVarieties] = { tDesign: CD.Design; IF tileBuffer#NIL THEN RETURN[tileBuffer]; log.PutRope["\n Initialize precharged PLA tiles"]; tDesign _ plaTilesDesign_ PW.OpenDesign["IFUPWControl.dale"]; IF tDesign=NIL THEN ERROR PW.Error[MissingDesign, "TileSet design not found or empty"]; tiles _ tileBuffer _ NEW[TileVarieties]; tiles.glue _ NEW[GlueTiles]; tiles.and _ NEW[NormalTiles]; tiles.or _ NEW[NormalTiles]; tiles.glue [xheader][leftSide] _ PW.Get[design: tDesign, name: "XLeftSide" ]; tiles.glue [xheader][between] _ PW.Get[design: tDesign, name: "XBetween" ]; tiles.glue [xheader][rightSide] _ PW.Get[design: tDesign, name: "XOrEx" ]; tiles.and [xheader][nc] _ PW.Get[design: tDesign, name: "XAnd" ]; tiles.and [xheader][extra] _ PW.Get[design: tDesign, name: "XAndEx" ]; tiles.or [xheader][nc] _ PW.Get[design: tDesign, name: "XOr" ]; tiles.or [xheader][extra] _ PW.Get[design: tDesign, name: "XOrEx" ]; tiles.glue [header][leftSide] _ PW.Get[design: tDesign, name: "HLeftSide" ]; tiles.glue [header][between] _ PW.Get[design: tDesign, name: "HBetween" ]; tiles.glue [header][rightSide] _ PW.Get[design: tDesign, name: "HOrEx" ]; tiles.and [header][nc] _ PW.Get[design: tDesign, name: "HAnd" ]; tiles.and [header][extra] _ PW.Get[design: tDesign, name: "HAndEx" ]; tiles.or [header][nc] _ PW.Get[design: tDesign, name: "HOr" ]; tiles.or [header][extra] _ PW.Get[design: tDesign, name: "HOrEx" ]; tiles.glue [footer][leftSide] _ PW.FlipY[tDesign, tiles.glue [header][leftSide] ]; tiles.glue [footer][between] _ PW.FlipY[tDesign, tiles.glue [header][between] ]; tiles.glue [footer][rightSide] _ PW.FlipY[tDesign, tiles.glue [header][rightSide] ]; tiles.and [footer][nc] _ PW.FlipY[tDesign, tiles.and [header][nc] ]; tiles.and [footer][extra] _ PW.FlipY[tDesign, tiles.and [header][extra] ]; tiles.or [footer][nc] _ PW.FlipY[tDesign, tiles.or [header][nc] ]; tiles.or [footer][extra] _ PW.FlipY[tDesign, tiles.or [header][extra] ]; tiles.glue [blank][leftSide] _ PW.Get[design: tDesign, name: "BLeftSide" ]; tiles.glue [blank][between] _ PW.Get[design: tDesign, name: "BBetween" ]; tiles.glue [blank][rightSide] _ PW.Get[design: tDesign, name: "BOrEx" ]; tiles.and [blank][nc] _ PW.Get[design: tDesign, name: "BAnd" ]; tiles.and [blank][extra] _ PW.Get[design: tDesign, name: "BAndEx" ]; tiles.or [blank][nc] _ PW.Get[design: tDesign, name: "BOr" ]; tiles.or [blank][extra] _ PW.Get[design: tDesign, name: "BOrEx" ]; tiles.glue [conn][leftSide] _ PW.Get[design: tDesign, name: "BLeftSide" ]; tiles.glue [conn][between] _ PW.Get[design: tDesign, name: "BBetween" ]; tiles.glue [conn][rightSide] _ PW.Get[design: tDesign, name: "CRightSide" ]; tiles.and [conn][left] _ PW.Get[design: tDesign, name: "CAndLt" ]; tiles.and [conn][right] _ PW.Get[design: tDesign, name: "CAndRt" ]; tiles.and [conn][nc] _ PW.Get[design: tDesign, name: "BAnd" ]; tiles.and [conn][extra] _ PW.Get[design: tDesign, name: "BAndEx" ]; tiles.or [conn][left] _ PW.Get[design: tDesign, name: "COr" ]; tiles.or [conn][nc] _ PW.Get[design: tDesign, name: "COrNC" ]; tiles.or [conn][extra] _ PW.Get[design: tDesign, name: "COrEx" ]; tiles.glue [dataUp][leftSide] _ PW.Get[design: tDesign, name: "DLeftSide" ]; tiles.glue [dataUp][between] _ PW.Get[design: tDesign, name: "DBetween" ]; tiles.glue [dataUp][rightSide] _ PW.Get[design: tDesign, name: "DRightSide" ]; tiles.and [dataUp][left] _ PW.Get[design: tDesign, name: "DAndLt" ]; tiles.and [dataUp][right] _ PW.Get[design: tDesign, name: "DAndRt" ]; tiles.and [dataUp][nc] _ PW.Get[design: tDesign, name: "DAnd" ]; tiles.and [dataUp][extra] _ PW.Get[design: tDesign, name: "DAndEx" ]; tiles.or [dataUp][left] _ PW.Get[design: tDesign, name: "DOr" ]; tiles.or [dataUp][nc] _ PW.Get[design: tDesign, name: "DOrNC" ]; tiles.or [dataUp][extra] _ PW.Get[design: tDesign, name: "DOrEx" ]; tiles.glue [dataDn][leftSide] _ tiles.glue [dataUp][leftSide]; tiles.glue [dataDn][between] _ tiles.glue [dataUp][between]; tiles.glue [dataDn][rightSide] _ PW.FlipY[tDesign, tiles.glue [dataUp][rightSide] ]; tiles.and [dataDn][left] _ tiles.and [dataUp][left]; tiles.and [dataDn][right] _ tiles.and [dataUp][right]; tiles.and [dataDn][nc] _ tiles.and [dataUp][nc]; tiles.and [dataDn][extra] _ tiles.and [dataUp][extra]; tiles.or [dataDn][left] _ PW.FlipY[tDesign, tiles.or [dataUp][left] ]; tiles.or [dataDn][nc] _ PW.FlipY[tDesign, tiles.or [dataUp][nc] ]; tiles.or [dataDn][extra] _ PW.FlipY[tDesign, tiles.or [dataUp][extra] ]; RETURN[tiles]}; ReverseList: PUBLIC PROC [list: LIST OF ROPE] RETURNS [new: LIST OF ROPE] = {FOR list _ list, list.rest WHILE list#NIL DO new _ CONS[list.first, new] ENDLOOP}; ListLength: PUBLIC PROC [list: LIST OF ROPE] RETURNS[size: INT] = {FOR size _ 0, size+1 WHILE list#NIL DO list_list.rest ENDLOOP}; ListIndexItem: PUBLIC PROC [list: LIST OF ROPE, index: INT] RETURNS[item: ROPE] = { FOR index _ index, index-1 WHILE index#0 AND list#NIL DO list_list.rest ENDLOOP; RETURN[IF list=NIL THEN NIL ELSE list.first]}; ListItemIndex: PUBLIC PROC [list: LIST OF ROPE, item: ROPE] RETURNS[index: INT] = { IF item=NIL THEN RETURN[-1]; FOR index _ 0, index+1 WHILE list#NIL DO IF Rope.Equal[list.first, item, FALSE] THEN RETURN[index]; list_list.rest ENDLOOP; RETURN[-1]}; ListConcat: PUBLIC PROC [list1, list2: LIST OF ROPE] RETURNS[new: LIST OF ROPE] = { FOR i: INT DECREASING IN [0..ListLength[list2]) DO new _ CONS[ ListIndexItem[list2, i], new] ENDLOOP; FOR i: INT DECREASING IN [0..ListLength[list1]) DO new _ CONS[ ListIndexItem[list1, i], new] ENDLOOP}; log: IO.STREAM _ CDFrame.GetLog[]; END. žIFUPWContPLA.mesa Copyright c 1985 by Xerox Corporation. All rights resersed. The tile set used by this module was derived from /IVY/McCreight/IFUDataCells/SelfTimedPLATiles2.dale Last Edited by: Curry, January 28, 1986 4:48:30 pm PST Example specification file: InstrDecode.plaSpec => InstrDecode.ttt CheckSize: PROC[obj1, obj2: CD.Object, xory: CDFrame.XorY, design: CD.Design] = { size1: CD.Position _ CD.InterestSize[obj1]; size2: CD.Position _ CD.InterestSize[obj2]; IF (IF xory=x THEN size1.x#size2.x ELSE size1.y#size2.y) THEN { viewer: ViewerClasses.Viewer; log.PutRope["\n Checksize error \n"]; viewer _ CDViewer.CreateViewer[design]; CDOps.SetInstList[design, NIL]; CDOps.AddAnObject[design, obj1, [0, 0]]; CDOps.AddAnObject[design, obj2, [(IF xory=y THEN size1.x ELSE 0), (IF xory=x THEN size1.y ELSE 0)]]; CDViewer.ShowAndScale[viewer, CDExtras.BoundingBox[design]]; ERROR} }; CreatePLAFromDesc: PUBLIC PROC [desc: PLADescription] RETURNS [drives, pla: CD.Object] = { log.PutRope["\n"]; CheckSufficientDesc[desc]; BuildConnTranslationArray[desc]; [pla, drives] _ SELECT desc.plaType FROM static => MakeStaticPLASection[desc], precharged => MakePreChargedPLA[desc], ENDCASE => ERROR; log.PutRope["\n"]}; IFUPWControlProc: PUBLIC PW.UserProc = { drives, pla: CD.Object; fileName: ROPE _ TerminalIO.RequestRope["PLA specification file: "]; desc: PLADescription _ ReadParameters[fileName]; CheckSufficientDesc[desc]; desc.design _ design; [drives, pla] _ CreatePLAFromDesc[desc]; RETURN[PW.AbutX[desc.design, drives, pla]]}; See InstrDecode.plaSpec for example of a .plaSpec file. ReadParameters: PROC [fileName: ROPE] RETURNS [desc: PLADescription] = { symTab: SymTab.Ref _ NIL; ref: REF; desc _ NEW[PLADescriptionRec _ [plaSpecFile: fileName] ]; symTab _ CDExpr.ReadFile[desc.plaSpecFile]; -- Read xxx.plaSpec ref _ CDExpr.FetchRef[symTab, "TypedTruthTableName"].val; IF ref = NIL OR NOT ISTYPE[ref, REF ROPE] THEN ERROR; desc.name _ NARROW[ref, REF ROPE]^; desc.ttt _ PLAOps.ReadPLAFile[desc.name.Cat[".ttt"]]; ref _ CDExpr.FetchRef[symTab, "InputNames"].val; IF ref # NIL THEN desc.plaInNames _ ToRopeList[NARROW[ref]]; ref _ CDExpr.FetchRef[symTab, "OutputNames"].val; IF ref # NIL THEN desc.plaOutNames _ ToRopeList[NARROW[ref]]; ref _ CDExpr.FetchRef[symTab, "Signals"].val; IF ref # NIL THEN desc.drSignalOrder _ ToRopeList[NARROW[ref]]}; CheckSufficientDesc: PROC [desc: PLADescription] = { IF desc.drFrame#NIL THEN ERROR; IF desc.ttt=NIL THEN ERROR; IF desc.design=NIL THEN ERROR; IF desc.plaInNames=NIL THEN { desc.plaInNames _ REFBit.BitNameList[ref: desc.ttt.data, both: TRUE]; FOR list: LIST OF ROPE _ desc.plaInNames, list.rest WHILE list#NIL DO list.first _ BitNameToSigName[list.first] ENDLOOP}; IF desc.plaOutNames=NIL THEN { desc.plaOutNames _ REFBit.BitNameList[ref: desc.ttt.out, both: FALSE]; FOR list: LIST OF ROPE _ desc.plaOutNames, list.rest WHILE list#NIL DO list.first _ BitNameToSigName[list.first] ENDLOOP}; IF desc.drSignalOrder=NIL THEN desc.drSignalOrder _ ListConcat[desc.plaInNames, desc.plaOutNames]; IF desc.design=NIL THEN ERROR}; desc.connSeq will contain indexes relative to the big (original) PLA PW.Register[userProc: IFUPWControlProc, name: "IFUPWControl"]; Κv˜šœ™Jšœ<™<codešœ1™1Kšœ3™3—K™6—J™JšœC™CšΟk ˜ Jšœ˜Jšœ˜Jšœ˜Jšœ ˜ Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ ˜ Jšœ˜Jšœ˜Jšœ˜Jšœ˜—J˜šœœ˜Jš œ œœœ œ˜\Jšœ˜Jšœœ˜J™šΠbnœœœ˜JšœœD˜OJšœœœœ˜3šœœœœ˜7Jšœ˜—Jšœ2˜2Jšœ"˜"Jšœ˜JšΟbœ œ%˜5Jšœœœ˜GJšŸœŸœ#˜:JšŸœœŸœ˜JšŸœŸœ;Πbl˜TšŸœ=œ˜Ešœ œ˜#Jšœœ;˜]——Jšœœ%˜Ašœœœ œ˜Jšœ˜šœœŸœœ˜$JšŸ˜šœœŸœœ˜*Jšœ˜JšŸœ˜————J˜šΟnœœ˜šœœœ1˜MJšœ˜—Jšœœœ˜6Jšœ:˜:Jšœ:˜:šœ$˜$Jšœ,œ˜BJšœS˜S—JšœΟc(˜6Jšœ˜Jšœ˜Jšœ˜Jšœ’ ˜!š œœ œœ˜1Jšœ œ$˜1Jšœ œ'˜4Jšœœ œ-˜TJšœœ œ-˜UJšœ˜—š œœ œœ˜2Jšœ œ%˜2Jšœ œ(˜5šœ˜Jšœ œ/˜E—Jšœ˜ ——J˜š‘ œœœ˜Jšœœ˜#Jšœœœ˜ Jšœœœœ˜7Jšœ˜Jšœœœ˜3Jšœ˜J˜Jšœ˜Jšœœ˜2Jšœœ˜6Jšœœ'˜AJšœ%œ˜šœœœ˜0JšœT˜TJšœ˜—Jšœ˜šœœœ˜Jšœœ˜šœ˜Jšœœ ˜,Jšœ˜—Jšœ0˜0——J˜š‘œœ˜6JšœA˜AJšœ*˜*šœœœ˜+Jšœ'œ˜1—šœœœ˜/Jšœœ˜#JšœQœ˜Y—šœ8œœ˜Lšœœœ˜.Jšœœ#œœ˜R——J˜—š‘œœ˜2šœœ˜šœ*˜*Jšœ˜Jšœ˜Jšœ"˜"Jšœ˜——šœœ˜šœ ˜ Jšœ˜Jšœ˜Jšœ˜—J˜——š‘ œœ œœœœ œœœ˜Pš œœœœœœ˜5Jšœ œœœœ œœœ˜:Jšœ˜—Jšœ œ ˜)—J˜J˜J˜J˜š‘œœ˜1Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜—J˜šœœœ˜ Jšœœ ’$˜@Jšœœ ’&˜CJšœœ ˜Jšœœ’˜5Jšœ œ ’˜.Jšœ œ œ’˜4—Jš œ œœœœœœ ˜@šœ œœ˜Jšœœ ˜Jšœ˜Jšœ˜Jšœ˜—Jšœ œœ ˜"Jš œ œœœœœ˜FJ˜š‘ œœ˜.šœœ˜Jšœ9˜<—Jšœ œœ˜Jšœ œ˜Jšœ œœ˜Jšœ œœ/˜BJšœ œ˜+Jšœ œ"˜0Jšœ œ˜*Jšœ œ˜Jšœ œ)˜8Jšœ œ<˜KJšœ2˜2Jšœ˜Jšœ<˜—Jšœ'˜'Jšœ4˜4šœ ˜Jšœœ˜Jšœœ)˜4Jšœœ)˜4šœ˜Jšœ œœœ˜-—Jšœ˜šœ ˜Jšœ%˜%Jšœ4˜4Jšœ˜—Jšœ œ˜šœ ˜Jšœœœœ ˜BJšœ4˜4Jšœ œ˜Jšœ˜—Jšœ˜—Jšœ˜—Jšœœœ˜#Jšœ(˜(—J˜š‘œœ'œœ ˜PJšœœœ ˜-Jšœœ˜"Jšœ˜Jšœ˜Jšœœ˜"Jšœ œ˜*Jšœœ œ˜Ašœ˜Jšœ˜Jšœ;˜;šœ˜Jšœ˜Jšœ œ˜ Jšœœœ˜*—Jšœ˜—šœœ˜#šœ œ˜'Jšœ˜ šœ˜šœ˜šœœO˜kJšœ˜Jšœ˜Jšœ˜—šœ œœ˜0Jšœ˜šœœ˜Jšœ˜Jšœ˜——Jšœ˜#—Jšœœ˜———š œœœœ˜;šœ œ˜(Jšœ˜ šœ˜Jšœ˜šœ!œ˜)šœœœ˜4JšœQ˜QJšœ˜—šœ œœ%˜GJšœ˜——Jšœœ˜———J˜—š‘ œœœ˜HJšœœœ ˜-Jšœ˜Jšœœœ!˜1—J˜š‘œœœ˜IJšœœœ ˜-Jšœ!˜!Jšœ˜—J˜š‘ œœ˜*Jšœœœ ˜-Jšœ ˜ Jšœœ˜Jšœœ˜ Jšœœœ˜šœœœ˜,šœ˜%šœ˜Jšœ'œœ˜4Jšœ$˜$—šœ˜Jšœ'œœ˜4—šœ˜Jšœ'œœ˜4Jšœ˜—Jšœœ˜—šœœ#˜.JšœV˜V—Jšœ ˜ Jšœ˜—Jšœ8˜8Jš œœœ œ(˜JJšœ˜—J˜šžœœ˜'Jšœœ ˜*Jšœœœ ˜-Jšœ˜Jšœ œ œ˜Jšœ4˜4šœ œœ˜)Jšœ œ œ˜Jšœœ˜$Jšœœœ(˜HJšœ œ*˜8šœœœ˜&Jšœ œ/œ˜E—šœœ˜Jšœ œ)˜7šœœœ˜%Jšœ œ-œ˜C—Jšœ œ-˜;—Jšœ œœœ˜GJšœ˜—Jšœ œ!˜/Jšœ˜—J˜š‘œœ˜2Jšœœœ ˜-Jšœœ ˜*Jšœ<˜J˜Jšœ˜J˜——…—MVsj