DIRECTORY CD, CDExpr, CDExtras, CDIO, CDPinObjects, PW, PWBasics, PWConditional, PWPLA, PWPLABasics, BoolOps, TerminalIO, AMTypes, Rope, IO, SymTab; PWPLAImpl: CEDAR PROGRAM IMPORTS BoolOps, CDExpr, CDIO, CDPinObjects, PW, PWBasics, PWConditional, 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]; -- 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[design: CD.Design, desc: PLADescription] RETURNS [allTiles: AllTiles]= BEGIN CheckProc: PROC [whereTilesAre: CD.Design] RETURNS [BOOL] = {RETURN [design.technology = whereTilesAre.technology]}; OptionalTile: PROC [name1, name2, name3: ROPE _ NIL] RETURNS [PW.ObjName] = {RETURN [PWPLABasics.OptionalTile[whereTilesAre, design, tilesPrefix, tilesFetched, name1, name2, name3]]}; RequiredTile: PROC [name1, name2, name3: ROPE _ NIL] RETURNS [PW.ObjName] = {RETURN [PWPLABasics.RequiredTile[whereTilesAre, design, tilesPrefix, tilesFetched, name1, name2, name3]]}; whereTilesAre: CD.Design _ NIL; RopeList: TYPE = LIST OF ROPE; tilesPrefix: ROPE _ NIL; -- to avoid conflict between several sets of tiles tilesFetched: REF RopeList _ NEW[RopeList _ NIL]; PWBasics.Output["Reading the tiles from ", desc.tileSet, "\n"]; whereTilesAre _ CDIO.ReadDesign[desc.tileSet, CheckProc]; -- if technos differ, no read tilesPrefix _ Rope.Cat["~", whereTilesAre.name, "."]; 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 {PWBasics.Output["Some of the extra horizontal tiles are missing.\n"]; desc.haveHorizontalExtras _ FALSE}; IF desc.haveVerticalAndExtras AND ~PWPLABasics.AllPresent[LIST[AUV, ADV]] THEN {PWBasics.Output["Some of the extra vertical AND plane tiles are missing.\n"]; desc.haveVerticalAndExtras _ FALSE}; IF desc.haveVerticalOrExtras AND ~PWPLABasics.AllPresent[LIST[OUV, ODV]] THEN {PWBasics.Output["Some of the extra vertical OR plane tiles are missing.\n"]; desc.haveVerticalOrExtras _ FALSE}; IF desc.haveHorizontalExtras AND desc.haveVerticalAndExtras AND AHV = NIL THEN PWBasics.Output["Tile 'AHV' is missing.\n"]; IF desc.haveHorizontalExtras AND desc.haveVerticalOrExtras AND OHV = NIL THEN PWBasics.Output["Tile 'OHV' is missing.\n"]; END; -- of the OPEN END; AssembleRows: PUBLIC PROC[design: CD.Design, desc: PLADescription, allTiles: AllTiles] RETURNS[pla: PW.ObjName] = BEGIN RenamePin: PROC[cell: PW.ObjName, old, new: ROPE] RETURNS[newCell: PW.ObjName] = BEGIN Rename: CDPinObjects.AppEnumerator = { IF Rope.Equal[CDPinObjects.GetName[app], old] THEN CDPinObjects.SetName[app, new]}; newOb, ob: CD.ObPtr; ob _ PWBasics.ObjFromName[design, cell]; newOb _ PWConditional.Inst[design, ob, NIL]; -- just a copy [] _ CDPinObjects.EnumeratePins[newOb, Rename]; newCell _ PWBasics.NameFromObj[newOb]; END; SpecialRow: PROC[left, andVert, andLeft, andRight, between, orVert, orLeft, orRight, right: PW.ObjName, namePins: BOOL _ FALSE] RETURNS[row: PW.ObjName] = BEGIN names: LIST OF ROPE; cell, newCell: PW.ObjName; tilesSinceExtra: INT; colList: LIST OF PW.ObjName; 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[PWPLABasics.ReverseList[colList]]; END; NormalRow: PROC[rowNum: INT, left, andVert, between, orVert, right: PW.ObjName, rowTab: ProgTile] RETURNS[row: PW.ObjName] = BEGIN colList: LIST OF PW.ObjName; 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[PWPLABasics.ReverseList[colList]]; END; noisy: BOOL; rowList: LIST OF PW.ObjName; rowsSinceExtra: INT _ 0; noisy _ (desc.truthTable.numPTerms > desc.printRows); IF noisy THEN TerminalIO.WriteRope["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 TerminalIO.WriteInt[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 TerminalIO.WriteRope[" . . . that's all.\n"]; END; CreatePLAFromFile: PUBLIC PROC [design: CD.Design, fileName: ROPE] RETURNS [pla: PW.ObjName] = BEGIN desc: PLADescription _ ReadParameters[fileName]; allTiles: AllTiles _ LoadTiles[design, desc]; pla _ CreatePLA[design, desc, allTiles]; END; CreatePLA: PUBLIC PROC [design: CD.Design, desc: PLADescription, allTiles: AllTiles] RETURNS [pla: PW.ObjName] = 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 BEGIN TerminalIO.WriteRope["The optimizer reduced the number of products terms from"]; TerminalIO.WriteInt[old]; TerminalIO.WriteRope[" to "]; TerminalIO.WriteInt[new]; TerminalIO.WriteLn[]; END ELSE TerminalIO.WriteRope["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[design, desc, allTiles]; END; MakePLAProc: PW.UserProc = BEGIN fileName: ROPE _ TerminalIO.RequestRope["File describing the PLA: "]; RETURN[CreatePLAFromFile[design, 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 -- 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 ΚR˜– "Cedar" stylešœ™Jšœ Οmœ1™