<> <> <> <<-- Make a Control Part, i.e. a set of PLAs sharing the input lines.>> <<>> DIRECTORY CD, CDExpr, CDExtras, Convert, PW, PWBasics, PWCP, PWPLA, PWPLABasics, BoolOps, TerminalIO, Rope, AMTypes, IO, SymTab; PWCPImpl: CEDAR PROGRAM IMPORTS BoolOps, CDExpr, Convert, PW, PWBasics, PWPLA, PWPLABasics, Rope, TerminalIO EXPORTS PWCP = BEGIN OPEN PWCP; ReadParameters: PROC [fileName: ROPE] RETURNS [desc: CPDescription] = <<-- read the options from a file and build a CPDescription>> BEGIN bool, found: BOOL; int: INT; ref: REF; symTab: SymTab.Ref; desc _ NEW[CPDescriptionRec]; 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; <<>> <<-- The large Truth Table>> desc.truthTable _ PWPLABasics.FetchTT[symTab]; IF desc.truthTable = NIL THEN ERROR; <<>> <<-- Input and Output names>> ref _ CDExpr.FetchRef[symTab, "Inputs"].val; IF ref#NIL THEN desc.inputNames _ PWPLABasics.ListRefAnyToListRope[NARROW[ref, REF LIST OF REF]^]; PWPLABasics.EnsureSize[desc.inputNames, desc.truthTable.numInputs]; ref _ CDExpr.FetchRef[symTab, "Outputs"].val; IF ref#NIL THEN desc.outputs _ PWPLABasics.ListRefAnyToListOfListRope[NARROW[ref, REF LIST OF REF]^] ; END; SeparateTT: PROC [desc: CPDescription] RETURNS [truthTables: LIST OF BoolOps.TruthTable _ NIL] = BEGIN ct: INT _ 0; listOutput: LIST OF LIST OF ROPE _ desc.outputs; posFirstOutput: INT _ desc.truthTable.numInputs; tt: BoolOps.TruthTable; WHILE listOutput#NIL DO [tt, posFirstOutput] _ MakeSmallTT[desc.truthTable, posFirstOutput, listOutput.first]; IF desc.optimize THEN tt _ BoolOps.TTOptimize[tt]; IF desc.dumpFile#NIL THEN PWPLABasics.DumpTruthTable[tt, Rope.Concat[desc.dumpFile, Convert.RopeFromInt[ct]]]; ct _ ct+1; truthTables _ CONS[tt, truthTables]; listOutput _ listOutput.rest; ENDLOOP; <<-- beware of the order of truthTables>> END; MakeSmallTT: PROC [bigTT: BoolOps.TruthTable, posFirstOutput: INT, listOutput: LIST OF ROPE] RETURNS [tt: BoolOps.TruthTable _ NIL, posFirstOutputAfter: INT] = BEGIN nbPTerm, ctPTerm: INT _ 0; copy: BOOL; p: REF BoolOps.PTerm; nbOutput: INT _ PWPLABasics.Length[listOutput]; <<-- Count how many minterms are needed to size the tt>> FOR j: INT IN [0..bigTT.numPTerms) DO copy _ FALSE; FOR i: INT IN [posFirstOutput..posFirstOutput+nbOutput) DO IF bigTT.pterms[j][i] = $One THEN copy _ TRUE; ENDLOOP; IF copy THEN nbPTerm _ nbPTerm+1; ENDLOOP; <<-- Make a truth table of the right size>> tt _ NEW[BoolOps.TruthTableRec[nbPTerm]]; tt.numInputs _ bigTT.numInputs; tt.numOutputs _ nbOutput; tt.numPTerms _ nbPTerm; <<-- And fill it up with the appropriate minterms>> FOR j: INT IN [0..bigTT.numPTerms) DO copy _ FALSE; <<-- Is this minterm interesting?>> FOR i: INT IN [posFirstOutput..posFirstOutput+nbOutput) DO IF bigTT.pterms[j][i] = $One THEN copy _ TRUE; ENDLOOP; IF ~copy THEN LOOP; <<-- Yes, so make a new minterm and copy it>> p _ NEW[BoolOps.PTerm[tt.numInputs + tt.numOutputs]]; <<-- Copy the AND-plane part>> FOR ins: INT IN [0..bigTT.numInputs) DO p[ins] _ bigTT.pterms[j][ins]; ENDLOOP; <<-- Copy the portion in the OR-plane>> FOR ins: INT IN [0..nbOutput) DO p[tt.numInputs + ins] _ bigTT.pterms[j][posFirstOutput+ins]; ENDLOOP; <<-- Insert in tt>> tt.pterms[ctPTerm] _ p; ctPTerm _ ctPTerm+1; ENDLOOP; <<>> <> posFirstOutputAfter _ posFirstOutput+nbOutput; END; CPdescToPLAdesc: PROC [desc: CPDescription] RETURNS [plaDesc: PWPLA.PLADescription] = BEGIN plaDesc _ NEW[PWPLA.PLADescriptionRec]; plaDesc.truthTableFile _ desc.truthTableFile; plaDesc.tileSet _ desc.tileSet; plaDesc.optimize _ desc.optimize; plaDesc.haveHorizontalExtras _ desc.haveHorizontalExtras; plaDesc.haveVerticalAndExtras _ desc.haveVerticalAndExtras; plaDesc.haveVerticalOrExtras _ desc.haveVerticalOrExtras; plaDesc.extraRows _ desc.extraRows; plaDesc.extraAndColumns _ desc.extraAndColumns; plaDesc.extraOrColumns _ desc.extraOrColumns; plaDesc.printRows _ desc.printRows; plaDesc.dumpFile _ desc.dumpFile; plaDesc.inputNames _ desc.inputNames; END; AssembleCP: PROC [design: CD.Design, desc: CPDescription, allTiles: PWPLA.AllTiles] RETURNS [cp: PW.ObjName] = BEGIN pla: PW.ObjName; listPLAs: LIST OF PW.ObjName _ NIL; listTT: LIST OF BoolOps.TruthTable _ desc.truthTables; listOutput: LIST OF LIST OF ROPE _ desc.outputs; <<-- Create a description for the generic small PLA>> plaDesc: PWPLA.PLADescription _ CPdescToPLAdesc[desc]; <<-- Put in the different fields for each small PLA>> WHILE listOutput#NIL DO plaDesc.truthTable _ listTT.first; plaDesc.outputNames _ listOutput.first; pla _ PWPLA.AssembleRows[design, plaDesc, allTiles]; PW.MakeObjNonStretchable[pla]; listPLAs _ CONS[PW.AbutX[pla, "glue"], listPLAs]; listOutput _ listOutput.rest; listTT _ listTT.rest; ENDLOOP; cp _ PW.AbutListY[PWPLABasics.ReverseList[listPLAs]]; END; CreateCPFromFile: PUBLIC PROC [design: CD.Design, fileName: ROPE] RETURNS [cp: PW.ObjName] = BEGIN desc: CPDescription; allTiles: PWPLA.AllTiles; PWBasics.Output["Parsing input file\n"]; desc _ ReadParameters[fileName]; PWBasics.Output["Loading cp tile set\n"]; allTiles _ PWPLA.LoadTiles[design, CPdescToPLAdesc[desc]]; cp _ CreateCP[design, desc, allTiles]; END; CreateCP: PUBLIC PROC [design: CD.Design, desc: CPDescription, allTiles: PWPLA.AllTiles] RETURNS [cp: PW.ObjName] = BEGIN <<-- Gas on>> PWBasics.Output["Slicing truth table\n"]; desc.truthTables _ SeparateTT[desc]; <<-- Mixture rich>> desc.haveHorizontalExtras _ desc.extraRows <= desc.truthTable.numPTerms; desc.haveVerticalAndExtras _ desc.extraAndColumns <= desc.truthTable.numInputs; desc.haveVerticalOrExtras _ desc.extraOrColumns <= desc.truthTable.numOutputs; <<-- Carb heat off>> PWBasics.Output["Assembling PLAs\n"]; cp _ AssembleCP[design, desc, allTiles]; END; MakeCPProc: PW.UserProc = BEGIN <<-- Instrument set and trimmed>> fileName: ROPE _ TerminalIO.RequestRope["File describing the Control Part: "]; <<-- Take-off !!!>> RETURN[CreateCPFromFile[design, fileName]]; END; <<-- register this generator with PW>> PW.Register[MakeCPProc, "Make Control Part"]; END.