DIRECTORY Basics, CD, CDExpr, CDPinObjects, IO, PLAOps, PW, IFUPW, IFUPWControl, REFBit, Rope, SymTab, TerminalIO, ViewerIO; IFUPWContALPs: CEDAR PROGRAM IMPORTS Basics, CDExpr, CDPinObjects, IFUPW, IFUPWControl, IO, PLAOps, PW, REFBit, Rope, TerminalIO, ViewerIO EXPORTS IFUPWControl = BEGIN OPEN IFUPWControl; CreateAlpsFromDrivers: PUBLIC PROC [desc: PLADescription, log: IO.STREAM] RETURNS [drives, pla: CD.Object] = { CheckSufficientDesc[desc]; BuildConnTranslationArray[desc]; ZeroUnusedTTTOutputs[desc]; CheckPLACompress[desc, log]; LoadPLATiles[desc]; DefinePLARows[desc]; drives _ AssembleDrivers[desc]; pla _ AssembleRows[desc] }; IFUPWControlProc: PUBLIC PW.UserProc = { logName: Rope.ROPE; log: IO.STREAM; drives, pla: CD.Object; fileName: ROPE _ TerminalIO.RequestRope["PLA specification file: "]; desc: PLADescription _ ReadParameters[fileName]; CheckSufficientDesc[desc]; desc.design _ design; logName _ fileName.Cat[".log"]; log _ ViewerIO.CreateViewerStreams[logName, NIL, logName].out; [drives, pla] _ CreatePLAFromDesc[desc, log]; RETURN[PW.AbutX[desc.design, drives, pla]]}; ReadParameters: PROC [fileName: ROPE] RETURNS [desc: PLADescription] = { ref: REF; desc _ NEW[PLADescriptionRec _ [plaSpecFile: fileName] ]; desc.symTab _ CDExpr.ReadFile[desc.plaSpecFile]; -- Read xxx.plaSpec ref _ CDExpr.FetchRef[desc.symTab, "TypedTruthTableFile"].val; IF ref = NIL OR NOT ISTYPE[ref, REF ROPE] THEN ERROR; desc.tttFile _ NARROW[ref, REF ROPE]^; desc.ttt _ PLAOps.ReadPLAFile[desc.tttFile]; ref _ CDExpr.FetchRef[desc.symTab, "InputNames"].val; IF ref # NIL THEN desc.plaInNames _ ToRopeList[NARROW[ref]]; ref _ CDExpr.FetchRef[desc.symTab, "OutputNames"].val; IF ref # NIL THEN desc.plaOutNames _ ToRopeList[NARROW[ref]]; ref _ CDExpr.FetchRef[desc.symTab, "Signals"].val; IF ref # NIL THEN desc.drSignalOrder _ ToRopeList[NARROW[ref]]; ref _ CDExpr.FetchRef[desc.symTab, "PLAParams"].val; IF ref = NIL OR NOT ISTYPE[ref, PLAParams] THEN ERROR; desc.plaParams _ NARROW[ref]; IF desc.plaParams.tileFile = NIL OR NOT ISTYPE[desc.plaParams.tileFile, ROPE] THEN ERROR}; CheckSufficientDesc: PROC [desc: PLADescription] = { IF desc.drivers#NIL THEN { drivers: REF DriveSeq _ NARROW[desc.drivers]; plaInputRecordRef: REF _ NIL; FOR index: INT DECREASING IN [0..drivers.size) DO driver: REF DriveRec _ NARROW[drivers[index]]; name: ROPE _ driver.name; IF name=NIL THEN name _ Rope.Cat["Not",driver.nameInv]; SELECT driver.cellType FROM pla => { IF desc.ttt = NIL THEN desc.ttt _ NARROW[driver.cellData]; IF desc.ttt=NIL THEN ERROR; IF driver.drDir = out THEN desc.plaOutNames _ CONS[name, desc.plaOutNames]; 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}}; alps => ERROR; conn => ERROR; ENDCASE => ERROR; desc.drSignalOrder _ CONS[name, desc.drSignalOrder]; ENDLOOP } ELSE { 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; IF desc.plaParams=NIL THEN desc.plaParams _ NEW[PLAParamsRec _ [ ]]; IF desc.plaParams.tileFile=NIL THEN desc.plaParams.tileFile _ "IFUPWControl.dale"; IF desc.drivers#NIL THEN desc.plaParams.minConnSpace _ 2}; BuildConnTranslationArray: PROC [desc: PLADescription ] = { index: INT _ -1; smlOutNames: LIST OF ROPE; PW.Output["Building pla translation array\n"]; desc.connSeq _ NEW[ConnSeqRec[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.drivers#NIL THEN { drivers: REF DriveSeq _ NARROW[desc.drivers]; FOR index IN [0..desc.connSeq.size) DO driver: REF DriveRec _ NARROW[drivers[index]]; IF driver=NIL THEN ERROR; desc.connSeq[index].dr _ driver ENDLOOP} }; ZeroUnusedTTTOutputs: PROC [desc: PLADescription ] = { maskTerm: PLAOps.Term _ PLAOps.CopyTerm[desc.ttt.termList.begin]; PW.Output["Zero unused TTT outputs\n"]; 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, log: IO.STREAM ] = { 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 ]}; desc.nextTerm _ desc.ttt.termList.begin }; ToRopeList: PROC [ refList: LIST OF REF ] RETURNS [ ropeList: RopeList ] = { 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]} }; GlobalTiles: RECORD[glue: REF GlueTiles, and, or: REF NormalTiles]; LoadPLATiles: PROC [desc: PLADescription ] = { OPEN desc.plaParams; tileDefDesign: CD.Design; IF glueTiles#NIL AND andTiles#NIL AND orTiles#NIL THEN RETURN; glueTiles _ GlobalTiles.glue; andTiles _ GlobalTiles.and; orTiles _ GlobalTiles.or; IF glueTiles#NIL AND andTiles#NIL AND orTiles#NIL THEN RETURN; PW.Output["Initialize pla tiles\n"]; tileDefDesign _ PW.OpenDesign[tileFile]; IF tileDefDesign=NIL THEN ERROR PW.Error[MissingDesign, "TileSet design not found or empty"]; glueTiles _ NEW[GlueTileArray]; andTiles _ NEW[NormalTileArray]; orTiles _ NEW[NormalTileArray]; glueTiles [xheader][leftSide] _ PW.Get[design: tileDefDesign, name: "XLeftSide" ]; glueTiles [xheader][between] _ PW.Get[design: tileDefDesign, name: "XBetween" ]; glueTiles [xheader][rightSide] _ PW.Get[design: tileDefDesign, name: "XOrEx" ]; andTiles [xheader][nc] _ PW.Get[design: tileDefDesign, name: "XAnd" ]; andTiles [xheader][extra] _ PW.Get[design: tileDefDesign, name: "XAndEx" ]; orTiles [xheader][nc] _ PW.Get[design: tileDefDesign, name: "XOr" ]; orTiles [xheader][extra] _ PW.Get[design: tileDefDesign, name: "XOrEx" ]; glueTiles [header][leftSide] _ PW.Get[design: tileDefDesign, name: "HLeftSide" ]; glueTiles [header][between] _ PW.Get[design: tileDefDesign, name: "HBetween" ]; glueTiles [header][rightSide] _ PW.Get[design: tileDefDesign, name: "HOrEx" ]; andTiles [header][nc] _ PW.Get[design: tileDefDesign, name: "HAnd" ]; andTiles [header][extra] _ PW.Get[design: tileDefDesign, name: "HAndEx" ]; orTiles [header][nc] _ PW.Get[design: tileDefDesign, name: "HOr" ]; orTiles [header][extra] _ PW.Get[design: tileDefDesign, name: "HOrEx" ]; glueTiles [footer][leftSide] _ PW.FlipY[tileDefDesign, glueTiles [header][leftSide] ]; glueTiles [footer][between] _ PW.FlipY[tileDefDesign, glueTiles [header][between] ]; glueTiles [footer][rightSide] _ PW.FlipY[tileDefDesign, glueTiles [header][rightSide] ]; andTiles [footer][nc] _ PW.FlipY[tileDefDesign, andTiles [header][nc] ]; andTiles [footer][extra] _ PW.FlipY[tileDefDesign, andTiles [header][extra] ]; orTiles [footer][nc] _ PW.FlipY[tileDefDesign, orTiles [header][nc] ]; orTiles [footer][extra] _ PW.FlipY[tileDefDesign, orTiles [header][extra] ]; glueTiles [blank][leftSide] _ PW.Get[design: tileDefDesign, name: "BLeftSide" ]; glueTiles [blank][between] _ PW.Get[design: tileDefDesign, name: "BBetween" ]; glueTiles [blank][rightSide] _ PW.Get[design: tileDefDesign, name: "BRightSide" ]; andTiles [blank][nc] _ PW.Get[design: tileDefDesign, name: "BAnd" ]; andTiles [blank][extra] _ PW.Get[design: tileDefDesign, name: "BAndEx" ]; orTiles [blank][nc] _ PW.Get[design: tileDefDesign, name: "BOr" ]; orTiles [blank][extra] _ PW.Get[design: tileDefDesign, name: "BOrEx" ]; glueTiles [conn][leftSide] _ PW.Get[design: tileDefDesign, name: "CLeftSide" ]; glueTiles [conn][between] _ PW.Get[design: tileDefDesign, name: "CBetween" ]; glueTiles [conn][rightSide] _ PW.Get[design: tileDefDesign, name: "CRightSide" ]; andTiles [conn][left] _ PW.Get[design: tileDefDesign, name: "CAndLt" ]; andTiles [conn][right] _ PW.Get[design: tileDefDesign, name: "CAndRt" ]; andTiles [conn][nc] _ PW.Get[design: tileDefDesign, name: "CAndNC" ]; andTiles [conn][extra] _ PW.Get[design: tileDefDesign, name: "CAndEx" ]; orTiles [conn][left] _ PW.Get[design: tileDefDesign, name: "COr" ]; orTiles [conn][nc] _ PW.Get[design: tileDefDesign, name: "COrNC" ]; orTiles [conn][extra] _ PW.Get[design: tileDefDesign, name: "COrEx" ]; glueTiles [dataUp][leftSide] _ PW.Get[design: tileDefDesign, name: "DLeftSide" ]; glueTiles [dataUp][between] _ PW.Get[design: tileDefDesign, name: "DBetween" ]; glueTiles [dataUp][rightSide] _ PW.Get[design: tileDefDesign, name: "DRightSide" ]; andTiles [dataUp][left] _ PW.Get[design: tileDefDesign, name: "DAndLt" ]; andTiles [dataUp][right] _ PW.Get[design: tileDefDesign, name: "DAndRt" ]; andTiles [dataUp][nc] _ PW.Get[design: tileDefDesign, name: "DAndNC" ]; andTiles [dataUp][extra] _ PW.Get[design: tileDefDesign, name: "DAndEx" ]; orTiles [dataUp][left] _ PW.Get[design: tileDefDesign, name: "DOr" ]; orTiles [dataUp][nc] _ PW.Get[design: tileDefDesign, name: "DOrNC" ]; orTiles [dataUp][extra] _ PW.Get[design: tileDefDesign, name: "DOrEx" ]; glueTiles [dataDn][leftSide] _ glueTiles [dataUp][leftSide]; glueTiles [dataDn][between] _ glueTiles [dataUp][between]; glueTiles [dataDn][rightSide] _ PW.FlipY[tileDefDesign, glueTiles [dataUp][rightSide] ]; andTiles [dataDn][left] _ andTiles [dataUp][left]; andTiles [dataDn][right] _ andTiles [dataUp][right]; andTiles [dataDn][nc] _ andTiles [dataUp][nc]; andTiles [dataDn][extra] _ andTiles [dataUp][extra]; orTiles [dataDn][left] _ PW.FlipY[tileDefDesign, orTiles [dataUp][left] ]; orTiles [dataDn][nc] _ PW.FlipY[tileDefDesign, orTiles [dataUp][nc] ]; orTiles [dataDn][extra] _ PW.FlipY[tileDefDesign, orTiles [dataUp][extra] ]; GlobalTiles _ [glueTiles, andTiles, orTiles]}; DefinePLARows: PROC [desc: PLADescription] = { firstRow: BOOL _ TRUE; index: INT _ 0; termUp: BOOL _ TRUE; nofIns: INT _ ListLength[desc.plaInNames]; nofOuts: INT _ ListLength[desc.plaOutNames]; cRowsLeft: INT _ ListLength[desc.drSignalOrder]; dRowsLeft: INT _ desc.ttt.termList.length; hRowsLeft: INT; dRowsLeft _ MAX[dRowsLeft, cRowsLeft*(desc.plaParams.minConnSpace)]; hRowsLeft _ (dRowsLeft+ desc.plaParams.termsPerHeader/2)/desc.plaParams.termsPerHeader; PW.Output["Assign pla row types\n"]; desc.nofAndCols _ nofIns/2 + (nofIns/2 -1) / desc.plaParams.insPerExtra; desc.nofOrCols _ nofOuts + (nofOuts -1) / desc.plaParams.outsPerExtra; desc.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 {desc.rows[index] _ NextRow[desc, xheader]; index_index+1}; desc.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 < desc.plaParams.minConnSpace OR (CperD>1) AND (desc.plaParams.minConnSpace>0) THEN ERROR; RperH _ RperH - CperD - DperC; WHILE CperD > 0 DO desc.rows[index] _ NextRow[desc, conn]; index_index+1; cRowsLeft_cRowsLeft-1; CperD_CperD-1; ENDLOOP; termUp _ TRUE; WHILE DperC > 0 DO desc.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#desc.rows.size THEN ERROR; desc.rows[index] _ NextRow[desc, footer] }; NextRow: PROC [desc: PLADescription, type: RowType] RETURNS[row: RowRef] = { 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 (desc.plaParams.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 (desc.plaParams.outsPerExtra+1) = 0 THEN row.or[index] _ extra ELSE { SELECT type FROM dataUp, dataDn => SELECT PLAOps.GetOutQrt [data, REFBit.Desc[desc.ttt.out].bitForm[desc.smlToBigOut[orIndex]].firstBit] FROM one => row.or[index] _ left; ENDCASE => row.or[index] _ nc; conn => IF conn.isOutput AND conn.index=desc.smlToBigOut[orIndex] THEN row.or[index] _ left ELSE row.or[index] _ nc; ENDCASE => row.or[index] _ nc; orIndex_orIndex+1 } ENDLOOP}; NextDataTerm: PROC [desc: PLADescription] RETURNS[term: PLAOps.Term] = { term _ desc.nextTerm; IF term#NIL THEN desc.nextTerm _ desc.nextTerm.next}; NextConnection: PROC [desc: PLADescription] RETURNS[conn: Connection] = { conn _ desc.connSeq[desc.nextConn]; desc.nextConn _ desc.nextConn+1}; AssembleDrivers: PROC[desc: PLADescription] RETURNS[drivers: CD.Object] = { driverList: PW.ListOb _ NIL; FOR driverIndex: INT IN [0..desc.rows.size) DO driverList _ CONS[DriverCell [desc.rows[driverIndex].type, desc.rows[driverIndex].dr, desc.design], driverList]; ENDLOOP; drivers _ PW.AbutListY[desc.design, driverList]}; AssembleRows: PROC[desc: PLADescription] RETURNS[pla: CD.Object] = { refPhase, inputPh: Ph _ unk; rowList: PW.ListOb _ NIL; PW.Output["Assemble pla row cells\n"]; FOR rowIndex: INT IN [0..desc.rows.size) DO objects: PW.ListOb _ NIL; row: RowRef _ desc.rows[rowIndex]; IF desc.rows[rowIndex].dr#NIL THEN refPhase _ desc.rows[rowIndex].dr.ref.ph; objects _ CONS[desc.plaParams.glueTiles[row.type][leftSide], objects]; FOR index: INT IN [0..row.and.size) DO objects _ CONS[desc.plaParams.andTiles[row.type][row.and[index]], objects] ENDLOOP; IF desc.nofOrCols#0 THEN { objects _ CONS[desc.plaParams.glueTiles[row.type][between], objects]; FOR index: INT IN [0..row.or.size) DO objects _ CONS[desc.plaParams.orTiles[row.type][row.or[index]], objects] ENDLOOP; objects _ CONS[desc.plaParams.glueTiles[row.type][rightSide], objects] }; rowList _ CONS[PW.AbutListX[desc.design, PW.Reverse[objects]], rowList] ENDLOOP; pla _ PW.AbutListY[desc.design, rowList]; inputPh _ SELECT refPhase FROM A=>BA, B=>AB, ENDCASE => ERROR; pla _ ReNamePLAInputPins[pla, inputPh, desc]}; ReNamePLAInputPins: PROC[pla: CD.Object, inputPh: Ph, desc: PLADescription] RETURNS[cell: CD.Object] = { format: REFBit.Format _ REFBit.Desc[desc.ttt.data].bitForm; leftSize: INT _ PW.IRSize[desc.plaParams.glueTiles[blank][leftSide]].x; andWidth: INT _ PW.IRSize[desc.plaParams.andTiles[blank][nc]].x; extraWidth: INT _ PW.IRSize[desc.plaParams.andTiles[blank][extra]].x; renameProc: IFUPW.PinNameProc ~ { 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)/(desc.plaParams.insPerExtra*andWidth+extraWidth); index _ (pin.location.x - leftSize - extraWidth*index)/andWidth; name _ SignalName[in1, format[index].name, format[index].nameInv, inputPh]}; cell _ IFUPW.RenameObjAndPins[desc.design, pla, "PLA", renameProc] }; 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}; PW.Register[userProc: IFUPWControlProc, name: "IFUPWControl"]; END. `IFUPWContAlps.mesa Copyright c 1985 by Xerox Corporation. All rights resersed. Last Edited by: Curry, October 3, 1985 1:44:09 pm PDT See InstrDecode.plaSpec for example of a .plaSpec file. Check for renaming parameters and renamed signals conn => { IF desc.plaInNames=NIL THEN { desc.plaInNames _ REFBit.BitNameList[ref: driver.refRec, both: TRUE]; FOR list: LIST OF ROPE _ desc.plaInNames, list.rest WHILE list#NIL DO list.first _ BitNameToSigName[list.first] ENDLOOP} }; desc.connSeq will contain indexes relative to the big (original) PLA PROC[pin: CD.Instance, side: Side] RETURNS[name: ROPE] Κδ˜šΠbl™Jšœ Οmœ1™JšŸœŸœŸœŸœŸœŸœŸœŸœŸœ˜5JšœŸœŸœŸœ˜&Jšœ,˜,šœ$‘ œ˜5JšŸœŸœŸœŸœ˜<—šœ$‘ œ˜6JšŸœŸœŸœŸœ˜=—šœ$‘œ˜2JšŸœŸœŸœ!Ÿœ˜?—J™1šœ$‘ œ˜4JšŸœŸœŸœŸœŸœŸœŸœ˜6—šœŸœ˜JšŸœ‘œŸœŸœŸœŸœŸœŸœŸœ˜Z—J˜—š œŸœ˜4šŸœŸ˜šŸœ˜Jšœ Ÿœ Ÿœ˜-JšœŸœŸœ˜š ŸœŸœŸ œŸœŸ˜1JšœŸœ Ÿœ˜.JšœŸœ˜JšŸœŸœŸœ'˜7šŸœŸ˜šœ ˜ JšŸœ ŸœŸœ Ÿœ˜:JšŸœ ŸœŸœŸœ˜JšŸœŸœŸœ˜KšŸœŸœŸœ˜Jšœ?Ÿœ˜Eš ŸœŸœŸœŸœŸœŸœŸ˜EJšœ ‘œ Ÿœ˜4———Jšœ Ÿœ˜Jšœ Ÿœ˜šœ ™ šŸœŸœŸœ™Jšœ?Ÿœ™Eš ŸœŸœŸœŸœŸœŸœŸ™EJšœ ‘œ Ÿœ™5———JšŸœŸœ˜—JšœŸœ˜4JšŸœ˜ —šŸœ˜JšŸœ ŸœŸœŸœ˜JšŸœ ŸœŸœŸœ˜šŸœŸœŸœ˜Jšœ?Ÿœ˜Eš ŸœŸœŸœŸœŸœŸœŸ˜EJšœ ‘œ Ÿœ˜3——šŸœŸœŸœ˜Jšœ?Ÿœ˜Fš ŸœŸœŸœŸœŸœŸœŸ˜FJšœ ‘œ Ÿœ˜3——šŸœŸ˜JšŸœF˜J————JšŸœ ŸœŸœŸœ˜Jš ŸœŸœŸœŸœ‘ œ˜DJšŸœŸœŸœ/˜RJšŸœŸœŸœ"˜:J˜—šΠbnœŸœ˜;JšœŸœ˜Jšœ ŸœŸœŸœ˜JšŸœ,˜.Jš‘D™DJšœŸœ-˜?š ŸœŸœŸœŸœ!ŸœŸœŸ˜HJšœŸœ.˜6Jšœ˜šŸœŸœ˜Jšœ/ŸœŸœ ˜SJšŸœ˜—Jšœ2˜2JšŸœŸœŸœ’˜/JšœŸœ˜,Jšœ-ŸœŸœ˜FJšŸœ˜—Jšœ(˜(JšœŸœ(˜>šŸœŸœŸœŸ˜0JšœT˜TJšŸœ˜—Jšœ˜šŸœ ŸœŸ˜Jšœ Ÿœ Ÿœ˜-šŸœŸœŸ˜&JšœŸœ Ÿœ˜.JšŸœŸœŸœŸœ˜Jšœ Ÿœ˜+———J˜š‘œŸœ˜6JšœA˜AJšŸœ%˜'šŸœŸœŸœ˜+JšŸœ'Ÿœ˜1—šŸœŸœŸœŸ˜/JšœŸœ˜#JšœPŸœ˜Y—šŸœ8ŸœŸœŸ˜LšŸœŸœŸœŸ˜.JšœŸœ#ŸœŸœ˜R——J˜—š œŸœŸœŸœ˜BšŸœŸ˜šœ*˜*Jšœ˜Jšœ˜Jšœ"˜"Jšœ˜——šŸœŸ˜šœ ˜ Jšœ˜Jšœ˜Jšœ˜——šœ*˜*J˜——š   œŸœ ŸœŸœŸœŸœ˜Lš ŸœŸœŸœŸœŸœŸœŸ˜5JšŸœ ŸœŸœŸœŸœ ŸœŸœŸœ˜:JšŸœ˜—JšŸœ Ÿœ ˜)—J˜Jš‘ œŸœŸœŸœ˜CJ˜š  œŸœ˜.JšŸœ˜JšœŸœ˜JšŸœ ŸœŸœ ŸœŸœ ŸœŸœŸœ˜>Jšœ˜Jšœ˜Jšœ˜JšŸœ ŸœŸœ ŸœŸœ ŸœŸœŸœ˜>JšŸœ"˜$JšœŸœ˜(šŸœŸœŸ˜JšŸœŸœ;˜C—Jšœ Ÿœ˜Jšœ Ÿœ˜ Jšœ Ÿœ˜J˜Jšœ Ÿœ#‘ œ˜RJšœŸœ#‘œ˜PJšœ!Ÿœ#‘œ˜OJšœŸœ#‘œ˜GJšœŸœ#‘œ˜LJšœŸœ#‘œ˜EJšœŸœ#‘œ˜JJ˜JšœŸœ#‘ œ˜QJšœŸœ#‘œ˜OJšœ Ÿœ#‘œ˜NJšœŸœ#‘œ˜GJšœŸœ#‘œ˜KJšœŸœ#‘œ˜EJšœŸœ#‘œ˜IJ˜Jšœ Ÿœ5˜WJšœŸœ4˜TJšœ Ÿœ6˜XJšœŸœ0˜LJšœŸœ2˜PJšœŸœ/˜JJšœŸœ1˜NJ˜JšœŸœ#‘ œ˜QJšœŸœ#‘œ˜NJšœŸœ#‘ œ˜RJšœŸœ#‘œ˜FJšœŸœ#‘œ˜JJšœŸœ#‘œ˜DJšœŸœ#‘œ˜HJ˜JšœŸœ#‘ œ˜PJšœŸœ#‘œ˜NJšœŸœ#‘ œ˜QJšœŸœ#‘œ˜IJšœŸœ#‘œ˜IJšœŸœ#‘œ˜GJšœŸœ#‘œ˜JJšœŸœ#‘œ˜EJšœŸœ#‘œ˜EJšœŸœ#‘œ˜HJ˜JšœŸœ#‘ œ˜QJšœŸœ#‘œ˜OJšœ Ÿœ#‘ œ˜SJšœŸœ#‘œ˜JJšœŸœ#‘œ˜KJšœŸœ#‘œ˜IJšœŸœ#‘œ˜KJšœŸœ#‘œ˜FJšœŸœ#‘œ˜GJšœŸœ#‘œ˜IJ˜JšœC˜CJšœA˜AJšœ Ÿœ6˜XJšœ:˜:Jšœ<˜Jšœ œ˜.—J˜š œŸœŸœ+˜KJšŸœŸœ ˜Jšœ<˜J˜JšŸœ˜J˜——…—H`V