DragonMicroPLALister.mesa
Last edited by Twilliams, August 30, 1984 0:18:38 am PDT
Last edited by Curry, August 31, 1984 2:21:05 pm PDT
To Register the Huff and Puff commands, and load their needed files Do @DragonMicroPLA.cm
DIRECTORY
FS,
Rope,
ViewerIO,
Commander,
CompleteSum,
IO,
AMTypes,
AMBridge,
Ascii USING [CR],
Convert,
Process,
Dragon,
DragonMicroPLA;
DragonMicroPLALister: CEDAR PROGRAM
IMPORTS AMBridge, AMTypes, Commander, CompleteSum, Convert, DragonMicroPLA, FS, IO, Process, Rope, ViewerIO =
BEGIN
ROPE:TYPE = Rope.ROPE;
screen: IO.STREAM;
PLAReduce: Commander.CommandProc = {
DoPLAReduce[]
TRUSTED {Process.Detach[FORK DoPLAReduce];}
};
DoPLAReduce: PROC = {
OPEN CS: CompleteSum;
logFileName: IO.ROPE = "PLA/DragonMicroPLA.log";
log: IO.STREAM ← ViewerIO.CreateViewerStreams
[name: logFileName, backingFile: logFileName].out;
trace: IO.STREAM ← ViewerIO.CreateViewerStreams["Dragon MicroPLA Trace"].out;
composite: CS.TermList;
csSeq: CS.TermListSeq;
fpSeq: CS.TermListSeq;
log.PutRope[logFileName];
log.PutF["\n\nBuilding composite output term list - %g\n", IO.time[]];
composite ← GetTermList[trace];
CS.ListTermList[list: composite, log: log];
log.PutF["\n\nBuilding individual output term lists - %g\n", IO.time[]];
csSeq ← CS.ExpandTermList[composite, trace];
fpSeq ← NEW[CS.TermListSeqRec[composite.outBits]];
FOR i: CARDINAL IN [0..csSeq.size) DO
log.PutF["\n Output %3g specified by %3g terms",
IO.card[i], IO.card[csSeq[i].length]] ENDLOOP;
log.PutF["\n\nBuilding individual output complete sums - %g", IO.time[]];
FOR i: CARDINAL IN [0..csSeq.size) DO
MSG: PROC[msg: IO.ROPE] = {file.PutRope[msg]; log.PutRope[msg]};
fileName: IO.ROPEIO.PutFR["PLA/DragonMicroPLA-%03g.dump", IO.card[i]];
file: IO.STREAMFS.StreamOpen[fileName, $create];
file.PutRope[fileName];
MSG[IO.PutFR["\n\nDefinition Sum - Output: %g Length: %g Time: %g",
IO.card[i], IO.card[csSeq[i].length], IO.time[]]];
IF csSeq[i].length=0 THEN LOOP;
CS.ListTermList[list: csSeq[i], log: file];
CS.ConvertTermListToSum
[list: csSeq[i], addMerges: TRUE, addConsensus: TRUE, log: trace];
MSG[IO.PutFR["\nComplete Sum - Output: %g Length: %g Time: %g",
IO.card[i], IO.card[csSeq[i].length], IO.time[]]];
CS.ListTermList[list: csSeq[i], log: file]; file.Flush[];
fpSeq[i] ← CS.CSListToFPList[csList: csSeq[i], log: trace];
MSG[IO.PutFR["\nFundamental Sum - Output: %g Length: %g Time: %g",
IO.card[i], IO.card[fpSeq[i].length], IO.time[]]];
CS.ListTermList[list: fpSeq[i], log: file];
file.Close[];
ENDLOOP;
FOR i: CARDINAL IN [0..csSeq.size) DO
log.PutF["\nTerm List %g at %g", IO.card[i], IO.time[]];
CS.ListTermList[list: csSeq[i], log: log];
ENDLOOP;
log.Close;
trace.Close};
GetTermList: PROC [log: IO.STREAM] RETURNS[termList: CompleteSum.TermList] = BEGIN
inBitSize, outBitSize: CARDINAL;
plaRow: DragonMicroPLA.PlaRow ← DragonMicroPLA.PLA[0];
rope:  ROPE ← PhBStateToRope[plaRow.andRow.phBArgs, plaRow.andRow.sigPhBArgs];
rope ← rope.Cat[" | "]; rope ← rope.Cat[MicroWordToRope[plaRow.orRow.m]];
[inBitSize, outBitSize] ← CompleteSum.CountBits[rope];
termList ← NEW[CompleteSum.TermListRec ← [inBits: inBitSize, outBits: outBitSize ]];
log.PutF["\n In bit size: %g Out bit size: %g\n", IO.card[inBitSize], IO.card[outBitSize]];
FOR PlaRowPointer: INT IN [0..DragonMicroPLA.PLAMinterms) DO
FOR PlaRowPointer: INT IN [0..20) DO
term: CompleteSum.Term;
plaRow ← DragonMicroPLA.PLA[PlaRowPointer];
rope ← PhBStateToRope[plaRow.andRow.phBArgs, plaRow.andRow.sigPhBArgs];
rope ← rope.Cat[" | "]; rope ← rope.Cat[MicroWordToRope[plaRow.orRow.m]];
term ← CompleteSum.RopeToTerm[rope, termList];
CompleteSum.ACopy[term, termList];
IF log#IO.noWhereStream THEN
IF (termList.length MOD 100)=0 THEN log.PutRope["!"] ELSE
IF (termList.length MOD 10)=0 THEN log.PutRope["."];
ENDLOOP;
END;
PLAGen: Commander.CommandProc = BEGIN
TRUSTED {Process.Detach[FORK DoPLAGen];}
END;
DoPLAGen: PROC = BEGIN
Header: ROPENIL;
Outrope: ROPE;
MicrowordTV: AMTypes.TV;
[out: screen] ← ViewerIO.CreateViewerStreams["Dragon Microcode PLA"];
FOR fieldindex:INT IN [1..AMTypes.NComponents[CODE[DragonMicroPLA.PhBArgs]]] DO
fName: ROPE ← AMTypes.IndexToName[CODE[DragonMicroPLA.PhBArgs], fieldindex];
Header ← AddHeaderLabel[ Header, fName ];
ENDLOOP;
TRUSTED { MicrowordTV ← AMBridge.TVForReferent[NEW[DragonMicroPLA.MicroInst]] };
Header ← Header.Cat["| "];
FOR fieldindex:INT IN [1..AMTypes.NComponents[CODE[DragonMicroPLA.MicroInst]]] DO
fieldWidth: CARDINAL;
bitArray: PACKED ARRAY [0..MaxFieldWidth) OF BOOLEAN;
fTV: AMTypes.TV = AMTypes.IndexToTV[MicrowordTV, fieldindex];
fName: ROPE = AMTypes.IndexToName[CODE[DragonMicroPLA.MicroInst], fieldindex];
[fieldWidth, bitArray] ← FieldToBitArray[ fieldTV: fTV, fieldTVName: AMTypes.IndexToName[CODE[DragonMicroPLA.MicroInst], fieldindex]];
IF fieldWidth=1 THEN Header ← AddHeaderLabel[ Header, fName]
ELSE FOR bitindex: [0..MaxFieldWidth) IN [0..fieldWidth) DO
Header ← AddHeaderLabel[ Header, fName.Cat[ Rope.Cat[ ".bit", Convert.RopeFromCard[ from: bitindex, showRadix: FALSE]]]] ;
ENDLOOP;
ENDLOOP;
screen.PutF["Table for Dragon Microcode: \n%g\n",IO.rope[Header]];
Outrope ← GenAllOps[]; -- Read the PLA table and generate Ascii output.
END;
AddHeaderLabel: PROC [ header: ROPE, name: ROPENIL ] RETURNS [ Header: ROPE] = BEGIN
Header ← header.Cat[Rope.FromChar['"]];
Header ← Header.Cat[name];
Header ← Header.Cat[Rope.FromChar['"]];
Header ← Header.Cat[", "];
END;
GenAllOps: PROC RETURNS [ outRope: ROPENIL] = BEGIN
plaRow: DragonMicroPLA.PlaRow;
FOR PlaRowPointer: INT IN [0..DragonMicroPLA.PLAMinterms) DO
plaRow ← DragonMicroPLA.PLA[PlaRowPointer];
outRope ← GenARow[bArgs: plaRow.andRow.phBArgs, sigArgs: plaRow.andRow.sigPhBArgs, m: plaRow.orRow.m ];
screen.PutF["%g",IO.rope[outRope]];
outRope ← NIL;
ENDLOOP;
END; -- GenAllOps
GenARow: PROC [ bArgs: DragonMicroPLA.PhBArgs, sigArgs: DragonMicroPLA.SigPhBArgs, m: DragonMicroPLA.MicroInst ] RETURNS [ outRope: ROPENIL] = BEGIN
outRope ← outRope.Cat[PhBStateToRope[bArgs, sigArgs]];
outRope ← outRope.Cat[" | "];
outRope ← outRope.Cat[MicroWordToRope[m]];
END; -- GenARow
PhBStateToRope: PROC [ bArgs: DragonMicroPLA.PhBArgs, sigArgs: DragonMicroPLA.SigPhBArgs]
RETURNS [ row: ROPE] = {
phBStateTV: AMTypes.TV;
fieldWidth: CARDINAL;
bitArray: PACKED ARRAY [0..MaxFieldWidth) OF BOOLEAN;
TRUSTED { phBStateTV ← AMBridge.TVForReferent[NEW[DragonMicroPLA.PhBArgs ← bArgs]] };
FOR fieldindex:INT IN [1..AMTypes.NComponents[CODE[DragonMicroPLA.PhBArgs]]] DO
fTV: AMTypes.TypedVariable = AMTypes.IndexToTV[phBStateTV, fieldindex];
sig: BOOLFALSE;
fieldName: ROPE = AMTypes.IndexToName[CODE[DragonMicroPLA.PhBArgs], fieldindex];
-- This name is for example "op"
sigArgsTV: AMTypes.TV;
sigArgTV: AMTypes.TV;
sigArgType: AMTypes.Type;
ArgType: AMTypes.Type;
TRUSTED { sigArgsTV ← AMBridge.TVForReferent[NEW[DragonMicroPLA.SigPhBArgs ← sigArgs]] };
sigArgTV ← AMTypes.IndexToTV[ sigArgsTV, AMTypes.NameToIndex[ CODE[DragonMicroPLA.SigPhBArgs], fieldName ]];
sigArgType ← AMTypes.GroundStar[AMTypes.TVType[sigArgTV]];
ArgType ← AMTypes.GroundStar[AMTypes.TVType[fTV]];
SELECT AMTypes.TypeClass[sigArgType] FROM
record => {
SELECT TRUE FROM
( AMTypes.TypeClass[ArgType] = integer),
fieldName.Equal["op"] => {
Assume that the number of components in the sig record is the number of bits in the integer field.
bitsInInt: PACKED ARRAY [0..MaxFieldWidth) OF BOOLEAN;
numbits: CARDINAL = AMTypes.NComponents[sigArgType];
TRUSTED { bitsInInt ← LOOPHOLE[AMBridge.TVToInteger[fTV]]};
FOR bit: INT IN [0..numbits) DO
sigBitTV: AMTypes.TypedVariable = AMTypes.IndexToTV[sigArgTV, bit+1];
sig ← Rope.Equal[AMTypes.TVToName[sigBitTV], "TRUE"];
bitArray[MaxFieldWidth-1] ← bitsInInt[ MaxFieldWidth-numbits + bit ];
row ← row.Cat[BitArrayToRope[1, bitArray, sig]];
ENDLOOP;
};
( AMTypes.TypeClass[ArgType] = record) => {
FOR fieldInRecord:INT IN [1..AMTypes.NComponents[sigArgType]] DO
sigStateTV: AMTypes.TypedVariable = AMTypes.IndexToTV[sigArgTV, fieldInRecord];
sig ← Rope.Equal[AMTypes.TVToName[sigStateTV], "TRUE"];
[fieldWidth, bitArray] ← FieldToBitArray[ fieldTV: AMTypes.IndexToTV[fTV, fieldInRecord], fieldTVName: AMTypes.IndexToName[sigArgType, fieldInRecord]];
row ← row.Cat[BitArrayToRope[fieldWidth, bitArray, sig]];
row ← row.Cat[" "];
ENDLOOP;
};
ENDCASE => ERROR;
};
enumerated => { -- BOOLEAN is a subclass of enumerated
sig ← Rope.Equal[AMTypes.TVToName[sigArgTV], "TRUE"];
[fieldWidth, bitArray] ← FieldToBitArray[ fieldTV: fTV ];
row ← row.Cat[BitArrayToRope[fieldWidth, bitArray, sig]];
};
ENDCASE => ERROR;
row ← row.Cat[" "];
ENDLOOP;
};
MicroWordToRope: PROC [ Microword: DragonMicroPLA.MicroInst] RETURNS [ row: ROPE ] = {
MicrowordTV: AMTypes.TV;
fieldWidth: CARDINAL;
bitArray: PACKED ARRAY [0..MaxFieldWidth) OF BOOLEAN;
TRUSTED { MicrowordTV ← AMBridge.TVForReferent[NEW[DragonMicroPLA.MicroInst ← Microword]] };
FOR fieldindex:INT IN [1..AMTypes.NComponents[CODE[DragonMicroPLA.MicroInst]]] DO
fTV: AMTypes.TypedVariable = AMTypes.IndexToTV[MicrowordTV, fieldindex];
[fieldWidth, bitArray] ← FieldToBitArray[ fieldTV: fTV, fieldTVName: AMTypes.IndexToName[CODE[DragonMicroPLA.MicroInst], fieldindex]];
row ← row.Cat[BitArrayToRope[fieldWidth, bitArray, TRUE]];
row ← row.Cat[" "];
ENDLOOP;
row ← row.Cat[Rope.FromChar[Ascii.CR]];
};
MaxFieldWidth: CARDINAL = 16;
FieldToBitArray: PROC [ fieldTV: AMTypes.TypedVariable, fieldTVName: ROPENIL] RETURNS [ fieldWidth: CARDINAL ← 0, bitArray: PACKED ARRAY [0..MaxFieldWidth) OF BOOLEAN] = {
fType: AMTypes.Type = AMTypes.GroundStar[AMTypes.TVType[fieldTV]];
fClass: AMTypes.Class = AMTypes.TypeClass[fType];
SELECT fClass FROM
record => {
fieldWidthInRecord: CARDINAL;
bitArrayInRecord: PACKED ARRAY [0..MaxFieldWidth) OF BOOLEAN;
FOR fieldInRecord:INT DECREASING IN [1..AMTypes.NComponents[fType]] DO
fTV: AMTypes.TypedVariable = AMTypes.IndexToTV[fieldTV, fieldInRecord];
[fieldWidthInRecord, bitArrayInRecord] ← FieldToBitArray[ fTV ];
FOR bitOfFieldInRecord:INT IN [1..fieldWidthInRecord] DO
bitArray[ MaxFieldWidth-fieldWidth-bitOfFieldInRecord] ← bitArrayInRecord[ MaxFieldWidth-bitOfFieldInRecord];
ENDLOOP;
fieldWidth ← fieldWidth + fieldWidthInRecord;
IF fieldWidth > MaxFieldWidth THEN ERROR; -- Make MaxFieldWidth bigger
ENDLOOP;
};
integer => {
TRUSTED { bitArray ← LOOPHOLE[AMBridge.TVToInteger[fieldTV]]};
fieldWidth← SELECT TRUE FROM
Rope.Equal[ fieldTVName, "cycle" ] => 6, -- [0..64)
ENDCASE => 8; -- Default to 8 bit bytes.
};
enumerated => {
enumFieldValue: CARDINAL ← AMTypes.NameToIndex[fType, AMTypes.TVToName[fieldTV]] - 1 ;
fieldWidth ← LogBase2[AMTypes.NValues[fType]];
TRUSTED { bitArray ← LOOPHOLE[enumFieldValue]};
};
ENDCASE => ERROR;
};
BitArrayToRope: PROC [ fieldWidth: CARDINAL, field: PACKED ARRAY [0..MaxFieldWidth) OF BOOLEAN, sig: BOOL] RETURNS [ Rfield: ROPE ] = {
FOR bit:INT IN [0..fieldWidth) DO
Rfield ← Rfield.Cat[
IF sig THEN (
SELECT field[ MaxFieldWidth-fieldWidth + bit ] FROM
TRUE => "1",
ENDCASE => "0")
ELSE "x"
]
ENDLOOP;
};
LogBase2: PROC [ in: CARDINAL] RETURNS [ out: CARDINAL] = {
out ← SELECT in FROM
<= 1 => 0,
<= 2 => 1,
<= 4 => 2,
<= 8 => 3,
<= 16 => 4,
<= 32 => 5,
<= 64 => 6,
ENDCASE => ERROR -- need to expand this function more.
};
Commander.Register[key:"Puff", proc: PLAGen, doc: "Lists the Dragon Microcode PLA"];
Commander.Register[key:"Huff", proc: PLAReduce, doc: "Reduces the Dragon Microcode PLA"];
END.