File: PWCPImpl.mesa   
Copyright © 1984 by Xerox Corporation. All rights reserved.
Created by: Monier, March 1, 1985 2:11:04 pm PST
-- 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;
IF ct=0 THEN ERROR; -- disconnected output: see later
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.