<> <> <> << PWMergedPLAImpl.mesa>> <> <> <> <<>> <> <<>> < InstrDecode.ttt >> DIRECTORY Basics, CD, CDExpr, IO, PLAOps, PW, PWPLAStack, REFBit, Rope, SymTab, TerminalIO, ViewerIO, ViewerOps; PWPLAStackImpl: CEDAR PROGRAM IMPORTS Basics, CDExpr, PLAOps, PW, REFBit, Rope, TerminalIO, ViewerIO, ViewerOps EXPORTS PWPLAStack = BEGIN OPEN PWPLAStack; <<>> CreatePLAFromDesc: PUBLIC PROC [desc: PLADescription] RETURNS [plaCell: CD.Object] = { BuildConnDescArraysAndReducePLA[desc]; LoadTiles[desc]; DefineRows[desc]; plaCell _ AssembleRows[desc]}; PWPLAStackProc: PUBLIC PW.UserProc = { fileName: ROPE _ TerminalIO.RequestRope["PLA specification file: "]; desc: PLADescription _ ReadParameters[fileName]; desc.design _ design; RETURN[CreatePLAFromDesc[desc]]}; <> 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.pla _ PLAOps.ReadPLAFile[desc.tttFile ! PLAOps.InvalidTermRope => RESUME ]; desc.pla.iForm _ REFBit.Desc[desc.pla.data].bitForm; desc.pla.oForm _ REFBit.Desc[desc.pla.out].bitForm; desc.inputNames _ ListDoubleIns[REFBit.BitNameList[desc.pla.data]]; desc.outputNames _ REFBit.BitNameList[desc.pla.out]; ref _ CDExpr.FetchRef[desc.symTab, "Signals"].val; IF ref # NIL THEN { IF NOT ISTYPE[ref, LIST OF REF] THEN ERROR; desc.signalOrder _ ToRopeList[NARROW[ref]]} ELSE desc.signalOrder _ ListConcat[desc.inputNames, desc.outputNames]; <> ref _ CDExpr.FetchRef[desc.symTab, "Params"].val; IF ref = NIL OR NOT ISTYPE[ref, PLAParams] THEN ERROR; desc.param _ NARROW[ref]; IF desc.param.tileSet = NIL OR NOT ISTYPE[desc.param.tileSet, ROPE] THEN ERROR}; BuildConnDescArraysAndReducePLA: PROC [desc: PLADescription ] = { index: INT _ -1; maskTerm: PLAOps.Term _ PLAOps.CopyTerm[desc.pla.termList.begin]; actualOutNames: LIST OF ROPE; PW.Output["Working on connection list . . . "]; <> desc.connSeq _ NEW[ConnSeqRec[ListLength[desc.signalOrder]]]; FOR i: CARDINAL IN [0..maskTerm.out.wdSize) DO maskTerm.out[i] _ PLAOps.initOutQrtWz ENDLOOP; FOR list: LIST OF ROPE _ desc.signalOrder, list.rest WHILE list#NIL DO pos: INT _ ListItemIndex[desc.inputNames, 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.outputNames, list.first]; IF pos=-1 THEN ERROR; -- Signal name not found; actualOutNames _ CONS[list.first, actualOutNames]; PLAOps.SetOutQrt[one, maskTerm, desc.pla.oForm[pos].firstBit]; desc.connSeq[index] _ [index: pos, isOutput: TRUE, isLeftSide: FALSE]; ENDLOOP; <> actualOutNames _ ReverseList[actualOutNames]; desc.smlToBigOut _ NEW[XsFormSeqRec[ListLength[actualOutNames]]]; FOR i: CARDINAL IN [0..desc.smlToBigOut.size) DO desc.smlToBigOut[i] _ ListItemIndex[desc.outputNames,ListIndexItem[actualOutNames,i]] ENDLOOP; <> desc.outputNames _ actualOutNames; FOR term: PLAOps.Term _ desc.pla.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; PW.Output["done\n"]; <> IF desc.param.doCompleteSum THEN { viewerName: ROPE _ "PWPLAStack Complete Sum Log"; log: IO.STREAM _ ViewerIO.CreateViewerStreams[viewerName].out; [ ] _ PLAOps.ConvertTermListToCompleteSum[ list: desc.pla.termList, addMerges: desc.param.csAddMerges, addConsensus: desc.param.csAddConsensus, log: log ]; log.Close[]; ViewerOps.DestroyViewer[ViewerOps.FindViewer[viewerName]]}; <> IF desc.param.doMinimization THEN { viewerName: ROPE _ "PWPLAStack Minimization Log"; log: IO.STREAM _ ViewerIO.CreateViewerStreams[viewerName].out; [ ] _ PLAOps.FindAMinimalCover[ list: desc.pla.termList, time: desc.param.timeOutMinutes, log: log ]; log.Close[]; ViewerOps.DestroyViewer[ViewerOps.FindViewer[viewerName]]}; desc.nextTerm _ desc.pla.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]} }; LoadTiles: PROC [desc: PLADescription ] = { OPEN desc; tileDefDesign _ PW.OpenDesign[param.tileSet]; IF tileDefDesign=NIL THEN ERROR PW.Error[MissingDesign, "TileSet design not found or empty"]; PW.Output["Setting up tiles\n"]; glueTiles _ NEW[GlueTilesRec]; andTiles _ NEW[NormalTilesRec]; orTiles _ NEW[NormalTilesRec]; glueTiles [header][leftSide] _ PW.Get[source: tileDefDesign, name: "HLeftSide" ]; glueTiles [header][between] _ PW.Get[source: tileDefDesign, name: "HBetween" ]; glueTiles [header][rightSide] _ PW.Get[source: tileDefDesign, name: "HOrEx" ]; andTiles [header][nc] _ PW.Get[source: tileDefDesign, name: "HAnd" ]; andTiles [header][extra] _ PW.Get[source: tileDefDesign, name: "HAndEx" ]; orTiles [header][nc] _ PW.Get[source: tileDefDesign, name: "HOr" ]; orTiles [header][extra] _ PW.Get[source: tileDefDesign, name: "HOrEx" ]; glueTiles [conn][leftSide] _ PW.Get[source: tileDefDesign, name: "CLeftSide" ]; glueTiles [conn][between] _ PW.Get[source: tileDefDesign, name: "CBetween" ]; glueTiles [conn][rightSide] _ PW.Get[source: tileDefDesign, name: "CRightSide" ]; andTiles [conn][left] _ PW.Get[source: tileDefDesign, name: "CAndLt" ]; andTiles [conn][right] _ PW.Get[source: tileDefDesign, name: "CAndRt" ]; andTiles [conn][nc] _ PW.Get[source: tileDefDesign, name: "CAndNC" ]; andTiles [conn][extra] _ PW.Get[source: tileDefDesign, name: "CAndEx" ]; orTiles [conn][left] _ PW.Get[source: tileDefDesign, name: "COr" ]; orTiles [conn][nc] _ PW.Get[source: tileDefDesign, name: "COrNC" ]; orTiles [conn][extra] _ PW.Get[source: tileDefDesign, name: "COrEx" ]; glueTiles [dataUp][leftSide] _ PW.Get[source: tileDefDesign, name: "DLeftSide" ]; glueTiles [dataUp][between] _ PW.Get[source: tileDefDesign, name: "DBetween" ]; glueTiles [dataUp][rightSide] _ PW.Get[source: tileDefDesign, name: "DRightSide" ]; andTiles [dataUp][left] _ PW.Get[source: tileDefDesign, name: "DAndLt" ]; andTiles [dataUp][right] _ PW.Get[source: tileDefDesign, name: "DAndRt" ]; andTiles [dataUp][nc] _ PW.Get[source: tileDefDesign, name: "DAndNC" ]; andTiles [dataUp][extra] _ PW.Get[source: tileDefDesign, name: "DAndEx" ]; orTiles [dataUp][left] _ PW.Get[source: tileDefDesign, name: "DOr" ]; orTiles [dataUp][nc] _ PW.Get[source: tileDefDesign, name: "DOrNC" ]; orTiles [dataUp][extra] _ PW.Get[source: 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] ]; }; DefineRows: PROC [desc: PLADescription] = { index: INT _ 0; termUp: BOOL _ TRUE; nofIns: INT _ ListLength[desc.inputNames]; nofOuts: INT _ ListLength[desc.outputNames]; cRowsLeft: INT _ nofIns + nofOuts; dRowsLeft: INT _ desc.pla.termList.length; hRowsLeft: INT _ 2 + (dRowsLeft + cRowsLeft -1) / desc.param.rowsPerHeader; CheckHead: PROC RETURNS[ loop: BOOL ] = { IF index+1 # desc.nofRows AND index MOD (desc.param.rowsPerHeader+1) # 0 THEN RETURN[FALSE]; desc.rows[index] _ NextRow[desc, header]; hRowsLeft _ hRowsLeft - 1; index _ index + 1; RETURN[TRUE]}; PW.Output["Assign row types\n"]; desc.nofAndCols _ nofIns/2 + (nofIns/2 -1) / desc.param.insPerExtra; desc.nofOrCols _ nofOuts + (nofOuts -1) / desc.param.outsPerExtra; desc.nofRows _ dRowsLeft + cRowsLeft + hRowsLeft; desc.rows _ NEW[RowsRec[desc.nofRows]]; WHILE index < desc.nofRows DO CperD, DperC: INT; IF CheckHead[] THEN LOOP; CperD _ MAX[1, (cRowsLeft + dRowsLeft/2)/dRowsLeft]; DperC _ MAX[1, (dRowsLeft + cRowsLeft/2)/cRowsLeft]; WHILE CperD > 0 DO IF CheckHead[] THEN LOOP; desc.rows[index] _ NextRow[desc, conn]; index _ index + 1; cRowsLeft _ cRowsLeft - 1; CperD _ CperD - 1; ENDLOOP; termUp _ TRUE; WHILE DperC > 0 DO IF CheckHead[] THEN LOOP; 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 }; NextRow: PROC [desc: PLADescription, type: RowType] RETURNS[row: RowRef] = { andIndex, orIndex, index: INT _ 0; data: PLAOps.Term; conn: Connection; SELECT type FROM dataUp, dataDn => data _ NextDataTerm[desc]; conn => conn _ NextConnection[desc]; ENDCASE; row _ NEW[RowRec _ [type: type]]; row.and _ NEW[ColSeqRec[desc.nofAndCols]]; row.or _ NEW[ColSeqRec[desc.nofOrCols]]; FOR index IN[0..desc.nofAndCols) DO IF (index+1) MOD (desc.param.insPerExtra+1) = 0 THEN row.and[index] _ extra ELSE { SELECT type FROM dataUp, dataDn => SELECT PLAOps.GetInQrt [data, desc.pla.iForm[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; FOR index IN[0..desc.nofOrCols) DO IF (index+1) MOD (desc.param.outsPerExtra+1) = 0 THEN row.or[index] _ extra ELSE { SELECT type FROM dataUp, dataDn => SELECT PLAOps.GetOutQrt [data, desc.pla.oForm[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; desc.nextTerm _ desc.nextTerm.next}; NextConnection: PROC [desc: PLADescription] RETURNS[conn: Connection] = { conn _ desc.connSeq[desc.nextConn]; desc.nextConn _ desc.nextConn+1}; TestRow: INT _ -1; AssembleRows: PROC[desc: PLADescription] RETURNS[pla: CD.Object] = { rowList: PW.ListOb _ NIL; PW.Output["Assemble row cells\n"]; FOR rowIndex: INT IN [0..desc.nofRows) DO objects: PW.ListOb _ NIL; row: RowRef _ desc.rows[rowIndex]; IF TestRow=rowIndex THEN {TestRow_TestRow}; objects _ CONS[desc.glueTiles[row.type][leftSide], objects]; FOR index: INT IN [0..row.and.size) DO objects _ CONS[desc.andTiles[row.type][row.and[index]], objects] ENDLOOP; objects _ CONS[desc.glueTiles[row.type][between], objects]; FOR index: INT IN [0..row.or.size) DO objects _ CONS[desc.orTiles[row.type][row.or[index]], objects] ENDLOOP; objects _ CONS[desc.glueTiles[row.type][rightSide], objects]; rowList _ CONS[PW.AbutListX[desc.design, PW.Reverse[objects]], rowList] ENDLOOP; PW.Output["Assemble PLA\n"]; pla _ PW.AbutListY[desc.design, rowList] }; 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] 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}; ListDoubleIns: PUBLIC PROC [list: LIST OF ROPE] RETURNS[new: LIST OF ROPE] = { FOR i: INT DECREASING IN [0..ListLength[list]) DO new _ CONS[ ListIndexItem[list, i].Cat["'"], new]; new _ CONS[ ListIndexItem[list, i], new] ENDLOOP}; <<>> <> <> <> <> <> <> <> <> <> <> <> <> PW.Register [userProc: PWPLAStackProc, name: "PWPLAStack" ]; END.