<> <> <> <> <<>> 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[] <> }; 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.ROPE _ IO.PutFR["PLA/DragonMicroPLA-%03g.dump", IO.card[i]]; file: IO.STREAM _ FS.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[]; <> <> <> <> 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 <> 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: ROPE _ NIL; 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: ROPE _ NIL ] 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: ROPE _ NIL] = 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: ROPE _ NIL] = 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: BOOL _ FALSE; 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"] => { <> 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: ROPE _ NIL] 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.