DIRECTORY CD, CDIO, CDSymbolicObjects, CDExpr, PW, PWPLA, PWPLABasics, BoolOps, TerminalIO, Rope, IO, SymTab; PWPLAImpl: CEDAR PROGRAM IMPORTS BoolOps, CDExpr, CDIO, CDSymbolicObjects, IO, PW, PWPLABasics, Rope, TerminalIO EXPORTS PWPLA = BEGIN OPEN PWPLA; ReadParameters: PROC [fileName: ROPE] RETURNS [desc: PLADescription] = BEGIN bool, found: BOOL; int: INT; symTab: SymTab.Ref; ref: REF; desc _ NEW[PLADescriptionRec]; symTab _ CDExpr.ReadFile[fileName, CDIO.GetWorkingDirectory[]]; -- turn a xxx.mg file into a symtab desc.tileSet _ CDExpr.FetchRope[symTab, "TileSet"].val; IF desc.tileSet = NIL THEN ERROR PWPLABasics.Error[TileSet, "TileSet not specified"]; [found, bool] _ CDExpr.FetchBool[symTab, "Optimize"]; IF found THEN desc.optimize _ bool; [found, int] _ CDExpr.FetchInt[symTab, "Extras"]; IF found THEN desc.extraRows _ desc.extraAndColumns _ desc.extraOrColumns _ int; [found, int] _ CDExpr.FetchInt[symTab, "ExtraRows"]; IF found THEN desc.extraRows _ int; [found, int] _ CDExpr.FetchInt[symTab, "ExtraColumns"]; IF found THEN desc.extraAndColumns _ desc.extraOrColumns _ int; [found, int] _ CDExpr.FetchInt[symTab, "ExtraAndColumns"]; IF found THEN desc.extraAndColumns _ int; [found, int] _ CDExpr.FetchInt[symTab, "ExtraOrColumns"]; IF found THEN desc.extraOrColumns _ int; [found, int] _ CDExpr.FetchInt[symTab, "PrintRows"]; IF found THEN desc.printRows _ int; desc.dumpFile _ CDExpr.FetchRope[symTab, "TruthTableDumpFile"].val; ref _ CDExpr.FetchRef[symTab, "Inputs"].val; IF ref#NIL THEN desc.inputNames _ PWPLABasics.ListRefAnyToListRope[NARROW[ref, REF LIST OF REF]^]; ref _ CDExpr.FetchRef[symTab, "Outputs"].val; IF ref#NIL THEN desc.outputNames _ PWPLABasics.ListRefAnyToListRope[NARROW[ref, REF LIST OF REF]^] ; desc.truthTable _ PWPLABasics.FetchTT[symTab]; IF desc.truthTable # NIL THEN BEGIN PWPLABasics.EnsureSize[desc.inputNames, desc.truthTable.numInputs]; PWPLABasics.EnsureSize[desc.outputNames, desc.truthTable.numOutputs]; END ELSE desc.truthTable _ PWPLABasics.GetEQN[symTab, desc.inputNames, desc.outputNames]; IF desc.truthTable = NIL THEN ERROR; IF desc = NIL THEN ERROR; END; LoadTiles: PUBLIC PROC[desc: PLADescription] RETURNS [allTiles: AllTiles]= BEGIN whereTilesAre: CD.Design _ CDIO.ReadDesign[from: desc.tileSet, wDir: CDIO.GetWorkingDirectory[]]; OptionalTile: PROC [name1, name2, name3: ROPE _ NIL] RETURNS [CD.Object] = {RETURN [PWPLABasics.OptionalTile[whereTilesAre, name1, name2, name3]]}; RequiredTile: PROC [name1, name2, name3: ROPE _ NIL] RETURNS [CD.Object] = {RETURN [PWPLABasics.RequiredTile[whereTilesAre, name1, name2, name3]]}; RopeList: TYPE = LIST OF ROPE; IF whereTilesAre=NIL THEN ERROR PWPLABasics.Error[TileSet, "TileSet not found or empty"]; allTiles _ NEW[AllTilesRec _ [rowTab: NEW[ProgTileRec]]]; BEGIN OPEN allTiles; Aul _ RequiredTile["Aul"]; AUleft _ OptionalTile["AUleft", "Aleft"]; ADleft _ OptionalTile["ADleft", "Aleft"]; AHleft _ OptionalTile["AHleft"]; All _ RequiredTile["All"]; ALbot _ OptionalTile["ALbot", "Abot"]; ARbot _ OptionalTile["ARbot", "Abot"]; AVbot _ OptionalTile["AVbot"]; ALtop _ OptionalTile["ALtop", "Atop"]; ARtop _ OptionalTile["ARtop", "Atop"]; AVtop _ OptionalTile["AVtop"]; AUL0 _ RequiredTile["AUL0", "AL0", "A0"]; ADL0 _ RequiredTile["ADL0", "AL0", "A0"]; AUR0 _ RequiredTile["AUR0", "AR0", "A0"]; ADR0 _ RequiredTile["ADR0", "AR0", "A0"]; AUL1 _ RequiredTile["AUL1", "AL1", "A1"]; ADL1 _ RequiredTile["ADL1", "AL1", "A1"]; AUR1 _ RequiredTile["AUR1", "AR1", "A1"]; ADR1 _ RequiredTile["ADR1", "AR1", "A1"]; AULx _ RequiredTile["AUL-", "AL-", "A-"]; ADLx _ RequiredTile["ADL-", "AL-", "A-"]; AURx _ RequiredTile["AUR-", "AR-", "A-"]; ADRx _ RequiredTile["ADR-", "AR-", "A-"]; ALH _ OptionalTile["ALH", "AH"]; ARH _ OptionalTile["ARH", "AH"]; AUV _ OptionalTile["AUV", "AV"]; ADV _ OptionalTile["ADV", "AV"]; AHV _ OptionalTile["AHV"]; Btop _ OptionalTile["Btop"]; BU _ RequiredTile["BU", "B"]; BD _ RequiredTile["BD", "B"]; BH _ OptionalTile["BH"]; Bbot _ OptionalTile["Bbot"]; OLtop _ OptionalTile["OLtop", "Otop"]; ORtop _ OptionalTile["ORtop", "Otop"]; OVtop _ OptionalTile["OVtop"]; OLbot _ OptionalTile["OLbot", "Obot"]; ORbot _ OptionalTile["ORbot", "Obot"]; OVbot _ OptionalTile["OVbot"]; Olr _ OptionalTile["Olr"]; Our _ OptionalTile["Our"]; OUright _ OptionalTile["OUright", "Oright"]; ODright _ OptionalTile["ODright", "Oright"]; OHright _ OptionalTile["OHright"]; OUL0 _ RequiredTile["OUL0", "OU0"]; OUR0 _ RequiredTile["OUR0", "OU0"]; ODL0 _ RequiredTile["ODL0", "OD0"]; ODR0 _ RequiredTile["ODR0", "OD0"]; OUL1 _ RequiredTile["OUL1", "OU1"]; OUR1 _ RequiredTile["OUR1", "OU1"]; ODL1 _ RequiredTile["ODL1", "OD1"]; ODR1 _ RequiredTile["ODR1", "OD1"]; OLH _ OptionalTile["OLH", "OH"]; ORH _ OptionalTile["ORH", "OH"]; OUV _ OptionalTile["OUV", "OV"]; ODV _ OptionalTile["ODV", "OV"]; OHV _ OptionalTile["OHV"]; rowTab[TRUE][TRUE][TRUE][$One] _ AUL1; rowTab[TRUE][TRUE][TRUE][$Zero] _ AUL0; rowTab[TRUE][TRUE][TRUE][$NC] _ AULx; rowTab[TRUE][TRUE][FALSE][$One] _ AUR1; rowTab[TRUE][TRUE][FALSE][$Zero] _ AUR0; rowTab[TRUE][TRUE][FALSE][$NC] _ AURx; rowTab[TRUE][FALSE][TRUE][$One] _ ADL1; rowTab[TRUE][FALSE][TRUE][$Zero] _ ADL0; rowTab[TRUE][FALSE][TRUE][$NC] _ ADLx; rowTab[TRUE][FALSE][FALSE][$One] _ ADR1; rowTab[TRUE][FALSE][FALSE][$Zero] _ ADR0; rowTab[TRUE][FALSE][FALSE][$NC] _ ADRx; rowTab[FALSE][TRUE][TRUE][$One] _ OUL1; rowTab[FALSE][TRUE][TRUE][$Zero] _ OUL0; rowTab[FALSE][TRUE][TRUE][$NC] _ OUL0; rowTab[FALSE][TRUE][FALSE][$One] _ OUR1; rowTab[FALSE][TRUE][FALSE][$Zero] _ OUR0; rowTab[FALSE][TRUE][FALSE][$NC] _ OUR0; rowTab[FALSE][FALSE][TRUE][$One] _ ODL1; rowTab[FALSE][FALSE][TRUE][$Zero] _ ODL0; rowTab[FALSE][FALSE][TRUE][$NC] _ ODL0; rowTab[FALSE][FALSE][FALSE][$One] _ ODR1; rowTab[FALSE][FALSE][FALSE][$Zero] _ ODR0; rowTab[FALSE][FALSE][FALSE][$NC] _ ODR0; IF desc.haveHorizontalExtras AND ~PWPLABasics.AllPresent[LIST[ALH, ARH, BH, OLH, ORH]] THEN {PW.WriteF["Some of the extra horizontal tiles are missing.\n"]; desc.haveHorizontalExtras _ FALSE}; IF desc.haveVerticalAndExtras AND ~PWPLABasics.AllPresent[LIST[AUV, ADV]] THEN {PW.WriteF["Some of the extra vertical AND plane tiles are missing.\n"]; desc.haveVerticalAndExtras _ FALSE}; IF desc.haveVerticalOrExtras AND ~PWPLABasics.AllPresent[LIST[OUV, ODV]] THEN {PW.WriteF["Some of the extra vertical OR plane tiles are missing.\n"]; desc.haveVerticalOrExtras _ FALSE}; IF desc.haveHorizontalExtras AND desc.haveVerticalAndExtras AND AHV = NIL THEN PW.WriteF["Tile 'AHV' is missing.\n"]; IF desc.haveHorizontalExtras AND desc.haveVerticalOrExtras AND OHV = NIL THEN PW.WriteF["Tile 'OHV' is missing.\n"]; END; -- of the OPEN END; AssembleRows: PROC[desc: PLADescription, allTiles: AllTiles] RETURNS[pla: CD.Object] = BEGIN RenamePin: PROC[ob: CD.Object, old, new: ROPE] RETURNS [newOb: CD.Object] = BEGIN Rename: CDSymbolicObjects.InstEnumerator = { IF Rope.Equal[CDSymbolicObjects.GetName[inst], old] THEN CDSymbolicObjects.SetName[inst, new]}; newOb _ PW.Copy[ob]; -- just a copy [] _ CDSymbolicObjects.EnumerateSymbolicObs[newOb, Rename]; END; SpecialRow: PROC[left, andVert, andLeft, andRight, between, orVert, orLeft, orRight, right: CD.Object, namePins: BOOL _ FALSE] RETURNS [row: CD.Object] = BEGIN names: LIST OF ROPE; cell, newCell: CD.Object; tilesSinceExtra: INT; colList: LIST OF CD.Object; colList _ CONS[left, NIL]; tilesSinceExtra _ 0; names _ desc.inputNames; FOR i: INT IN [0 .. desc.truthTable.numInputs) DO IF tilesSinceExtra+1 >= desc.extraAndColumns AND desc.haveVerticalAndExtras AND PW.EVEN[i] THEN {colList _ CONS[andVert, colList]; -- extra column in AND plane tilesSinceExtra _ 0}; cell _ IF PW.EVEN[i] THEN andLeft ELSE andRight; IF namePins THEN { newCell _ RenamePin[cell, "In", names.first]; names _ names.rest} ELSE newCell _ cell; colList _ CONS[newCell, colList]; -- normal column tilesSinceExtra _ tilesSinceExtra + 1; ENDLOOP; colList _ CONS[between, colList]; tilesSinceExtra _ 0; names _ desc.outputNames; FOR i: INT IN [0 .. desc.truthTable.numOutputs) DO IF tilesSinceExtra+1 >= desc.extraOrColumns AND desc.haveVerticalOrExtras AND PW.EVEN[i] THEN {colList _ CONS[orVert, colList]; -- extra column in OR plane tilesSinceExtra _ 0}; cell _ IF PW.EVEN[i] THEN orLeft ELSE orRight; IF namePins THEN { newCell _ RenamePin[cell, "Out", names.first]; names _ names.rest} ELSE newCell _ cell; colList _ CONS[newCell, colList]; -- normal tilesSinceExtra _ tilesSinceExtra + 1; ENDLOOP; colList _ CONS[right, colList]; row _ PW.AbutListX[PW.Reverse[colList]]; END; NormalRow: PROC[rowNum: INT, left, andVert, between, orVert, right: CD.Object, rowTab: ProgTile] RETURNS[row: CD.Object] = BEGIN colList: LIST OF CD.Object; tilesSinceExtra: INT; colList _ CONS[left, NIL]; tilesSinceExtra _ 0; FOR i: INT IN [0 .. desc.truthTable.numInputs) DO IF tilesSinceExtra+1 >= desc.extraAndColumns AND desc.haveVerticalAndExtras AND PW.EVEN[i] THEN {colList _ CONS[andVert, colList]; -- extra column in AND plane tilesSinceExtra _ 0}; colList _ CONS[ -- normal cell rowTab[TRUE][PW.EVEN[rowNum]][PW.EVEN[i]][desc.truthTable.pterms[rowNum].bits[i]], colList]; tilesSinceExtra _ tilesSinceExtra + 1; ENDLOOP; colList _ CONS[between, colList]; tilesSinceExtra _ 0; FOR i: INT IN [0 .. desc.truthTable.numOutputs) DO IF tilesSinceExtra+1 >= desc.extraOrColumns AND desc.haveVerticalOrExtras AND PW.EVEN[i] THEN {colList _ CONS[orVert, colList]; -- extra column in OR plane tilesSinceExtra _ 0}; colList _ CONS[ -- normal cell rowTab[FALSE][PW.EVEN[rowNum]][PW.EVEN[i]][desc.truthTable.pterms[rowNum].bits[i + desc.truthTable.numInputs]], colList]; tilesSinceExtra _ tilesSinceExtra + 1; ENDLOOP; colList _ CONS[right, colList]; row _ PW.AbutListX[PW.Reverse[colList]]; END; noisy: BOOL; rowList: LIST OF CD.Object; rowsSinceExtra: INT _ 0; noisy _ (desc.truthTable.numPTerms > desc.printRows); IF noisy THEN PW.WriteF["Rows (product terms) placed: "]; BEGIN OPEN allTiles; rowList _ LIST [SpecialRow[Aul, AVtop, ALtop, ARtop, Btop, OVtop, OLtop, ORtop, Our, TRUE]]; FOR rowIndex: INT IN [0 .. desc.truthTable.numPTerms) DO IF rowsSinceExtra+1 >= desc.extraRows AND desc.haveHorizontalExtras AND PW.EVEN[rowIndex] THEN BEGIN rowList _ CONS[ SpecialRow[AHleft, AHV, ALH, ARH, BH, OHV, OLH, ORH, OHright], rowList]; rowsSinceExtra _ 0; END; rowList _ CONS[ IF PW.EVEN[rowIndex] THEN NormalRow[rowIndex, AUleft, AUV, BU, OUV, OUright, rowTab] ELSE NormalRow[rowIndex, ADleft, ADV, BD, ODV, ODright, rowTab], rowList]; IF noisy THEN PW.WriteF["%g", IO.int[rowIndex + 1]]; rowsSinceExtra _ rowsSinceExtra + 1; ENDLOOP; rowList _ CONS[ SpecialRow[All, AVbot, ALbot, ARbot, Bbot, OVbot, OLbot, ORbot, Olr], rowList]; END; -- OPEN allTiles pla _ PW.AbutListY[rowList]; IF noisy THEN PW.WriteF[" . . . that's all.\n"]; END; CreatePLAFromFile: PUBLIC PROC [fileName: ROPE] RETURNS [pla: CD.Object] = BEGIN desc: PLADescription _ ReadParameters[fileName]; allTiles: AllTiles _ LoadTiles[desc]; pla _ CreatePLA[desc, allTiles]; END; CreatePLA: PUBLIC PROC [desc: PLADescription, allTiles: AllTiles] RETURNS [pla: CD.Object] = BEGIN IF desc.optimize THEN BEGIN old, new: INT _ desc.truthTable.numPTerms; desc.truthTable _ BoolOps.TTOptimize[desc.truthTable]; new _ desc.truthTable.numPTerms; IF old>new THEN PW.WriteF["The optimizer reduced the number of products terms from %g to %g\n", IO.int[old], IO.int[new]] ELSE PW.WriteF["The optimizer did not help. \n"]; END; IF desc.dumpFile#NIL THEN PWPLABasics.DumpTruthTable[desc.truthTable, desc.dumpFile]; desc.haveHorizontalExtras _ desc.extraRows <= desc.truthTable.numPTerms; desc.haveVerticalAndExtras _ desc.extraAndColumns <= desc.truthTable.numInputs; desc.haveVerticalOrExtras _ desc.extraOrColumns <= desc.truthTable.numOutputs; pla _ AssembleRows[desc, allTiles]; END; MakePLAProc: PW.UserProc = BEGIN fileName: ROPE _ TerminalIO.RequestRope["File describing the PLA: "]; RETURN [CreatePLAFromFile[fileName]]; END; PW.Register[MakePLAProc, "Make PLA"]; END. ΔFile: PWPLAImpl.mesa Copyright c 1984 by Xerox Corporation. All rights reserved. Created by: Monier, March 14, 1985 8:57:18 pm PST Bertrand Serlet May 28, 1986 12:10:24 pm PDT -- Make a PLA. Borrows more than heavily from Bob Mayo's MakePLA. General plan: Read our input table and create a description record. Use that record to build a PLA. The PLA is built by producing rows from top to bottom, inserting extra rows as needed. Each row is built left to right, and may have extra columns added as needed. -- read the options from a file and build a PLADescription -- Input and Output names -- Truth Table: One must provide either the truth table, or the equations -- for now, just checking the technologies -- left side of AND plane -- top and bottom of AND plane -- core of AND plane -- area between planes -- top and bottom of OR plane -- right side of OR plane -- core of the OR plane -- up (U) rows of AND plane -- down (D) rows of AND plane -- up (U) rows of OR plane -- down (D) rows of OR plane -- extra horizontal tiles -- extra vertical AND plane tiles -- extra vertical OR plane tiles -- intersections between extras -- Cell assembly procedures -- left column -- AND plane -- Between planes -- OR plane -- right column -- left column -- AND plane -- Between planes -- OR plane -- right column -- create the PLA row by row, inserting extra ground rows as needed -- Start with the top row -- Now the rows, from top to bottom -- if conditions are right, we add an extra ground row -- now we add the normal row at the bottom -- Finally the bottom row -- Assemble the cells -- Gas on -- Mixture rich -- Carb heat off -- Instrument set and trimmed -- Take-off !!! -- register this generator with PW Κθ˜– "Cedar" stylešœ™Jšœ Οmœ1™