<> <> <> <> <> <> <> DIRECTORY Commander, CommandTool, FS, IFUPLA, IO, PLAOps, REFBit, Rope; IFUPLAImpl: CEDAR PROGRAM IMPORTS Commander, CommandTool, FS, IO, PLAOps, REFBit, Rope EXPORTS IFUPLA = BEGIN PLAs: TYPE = IFUPLA.PLAs; PLA: TYPE = PLAOps.PLA; ReadIFUPLAs: Commander.CommandProc = {FOR pla: PLAs IN PLAs DO IFUPLARead[pla, cmd.out] ENDLOOP}; ReadIFUPLA: Commander.CommandProc = { list: LIST OF IO.ROPE _ CommandTool.ParseToList[cmd].list; CheckForOtherReferences: PROC[pla: PLAs] = { FOR other: PLAs IN PLAs DO Ck: PROC [p1, p2: PLAs] = { IF REFBit.Size[plas[p1].data] # REFBit.Size[plas[plaDescriptions[p2].input].data] THEN ERROR}; IF pla = plaDescriptions[other].input AND plas[other]#NIL THEN {Ck[pla, other]; plas[other].data _ plas[pla].data}; IF other = plaDescriptions[pla].input AND plas[other]#NIL THEN {Ck[other, pla]; plas[pla].data _ plas[other].data} ENDLOOP}; PLAOps.FlushPLACache[]; IF list=NIL THEN FOR pla: PLAs IN PLAs DO plas[pla] _ NIL; IFUPLARead[pla, cmd.out]; CheckForOtherReferences[pla] ENDLOOP ELSE { root: IO.ROPE _ list.first.Substr[0, list.first.Index[0, "."]]; FOR pla: PLAs IN PLAs DO IF NOT root.Equal[plaDescriptions[pla].fileName, FALSE] THEN LOOP; plas[pla] _ NIL; IFUPLARead[pla, cmd.out]; CheckForOtherReferences[pla]; EXIT ENDLOOP} }; ReadAndAnalyzeIFUPLAs: Commander.CommandProc = { name: IO.ROPE _ "IFUPLAStats.txt"; out: IO.STREAM _ FS.StreamOpen[name, $create]; out.PutF["%g, - %g\n", IO.rope[name], IO.time[]]; FOR pla: PLAs IN PLAs DO name: IO.ROPE _ plaDescriptions[pla].fileName.Substr[6]; IFUPLARead[pla, cmd.out]; ShowPLA[out, name, plas[pla]]; ENDLOOP; out.Close[]; cmd.out.PutF[" Statistics file: %g\n", IO.rope[name]]}; FlushAll: PROC = { PLAOps.FlushPLACache[]; FOR pla: PLAs IN PLAs DO plas[pla] _ NIL ENDLOOP}; IFUPLARead: PROC [ plaType: PLAs, log: IO.STREAM _ IO.noWhereStream]={ fileName: IO.ROPE _ IO.PutFR["%g.ttt", IO.rope[plaDescriptions[plaType].fileName]]; IF plas[plaType]=NIL THEN plas[plaType] _ PLAOps.ReadPLAFile[fileName, log, TRUE]; IF plaDescriptions[plaType].input # plaType THEN -- use another PLA's input IF REFBit.Size[plas[plaType].data] = REFBit.Size[plas[plaDescriptions[plaType].input].data] THEN plas[plaType].data _ plas[plaDescriptions[plaType].input].data ELSE ERROR; plaSizes[plaType][input] _ REFBit.Size[plas[plaType].data]; plaSizes[plaType][output] _ REFBit.Size[plas[plaType].out]}; ShowPLA: PROC[out: IO.STREAM, name: IO.ROPE, pla: PLA, fields, outs: INT _ 0] = { terms: INT _ pla.termList.length; ins: INT _ REFBit.Desc[pla.data].bitForm.size; IF fields=0 THEN fields _ REFBit.Desc[pla.out].fieldForm.size; IF outs=0 THEN outs _ REFBit.Desc[pla.out].bitForm.size; out.PutF["%16g Ins:%2g Terms:%3g Outs:%2g/%3g", IO.rope[name], IO.int[ins], IO.int[terms], IO.int[fields], IO.int[outs] ]; out.PutF[" PhSz:%3g MxI/T:%2g MxT/O:%2g\n", IO.int[PhSize[outs, terms]], IO.int[MaxInsPerTerm[pla]], IO.int[MaxTermsPerOut[pla]]]}; PhSize: PROC[outs, terms: INT] RETURNS[max: INT _ 0] = {RETURN[outs + MAX[outs*2, terms]]}; MaxInsPerTerm: PROC[pla: PLA] RETURNS[max: INT _ 0] = { bitFormat: PLAOps.Format _ REFBit.Desc[pla.data].bitForm; FOR term: PLAOps.Term _ pla.termList.begin, term.next WHILE term#NIL DO thisTermMax: INT _ 0; FOR in: INT IN [0..bitFormat.size) DO IF PLAOps.GetInQrt[term, bitFormat[in].firstBit]#dontcare THEN thisTermMax _ thisTermMax+1 ENDLOOP; max _ MAX[max, thisTermMax] ENDLOOP}; MaxTermsPerOut: PROC[pla: PLA] RETURNS[max: INT _ 0] = { bitFormat: PLAOps.Format _ REFBit.Desc[pla.out].bitForm; FOR out: INT IN [0..bitFormat.size) DO thisOutMax: INT _ 0; FOR term: PLAOps.Term _ pla.termList.begin, term.next WHILE term#NIL DO IF PLAOps.GetOutQrt[term, bitFormat[out].firstBit]=one THEN thisOutMax _ thisOutMax+1 ENDLOOP; max _ MAX[max, thisOutMax] ENDLOOP}; IFUPLAEval: PUBLIC PROC [ plaType: PLAs ] = {PLAOps.GetOutForData[plas[plaType]]}; plas: PUBLIC ARRAY PLAs OF PLA; PlaDescription: TYPE = RECORD [ fileName: IO.ROPE, input: IFUPLA.PLAs ]; plaDescriptions: PUBLIC ARRAY IFUPLA.PLAs OF PlaDescription _ [ fetchControl: ["IFUPLAFetchControl", fetchControl], fetchRdDecode: ["IFUPLAFetchRdDecode", fetchRdDecode], fetchWtDecode: ["IFUPLAFetchWtDecode", fetchWtDecode], instrDecode: ["IFUPLAInstrDecode", instrDecode], instrDecode0: ["IFUPLAInstrDecode0", instrDecode0], instrDecode1: ["IFUPLAInstrDecode1", instrDecode0], instrDecode2: ["IFUPLAInstrDecode2", instrDecode0], instrDecode3: ["IFUPLAInstrDecode3", instrDecode0], instrDecode4: ["IFUPLAInstrDecode4", instrDecode0], instrDecode5: ["IFUPLAInstrDecode5", instrDecode0], instrDecode6: ["IFUPLAInstrDecode6", instrDecode0], interlock: ["IFUPLAInterlock", interlock], mainPipeControl: ["IFUPLAMainPipeControl", mainPipeControl], stackAControl: ["IFUPLAStackAControl", stackAControl], stackBControl: ["IFUPLAStackBControl", stackBControl], stackDecode: ["IFUPLAStackDecode", stackDecode], ltDrPadIO: ["IFUPLAPassLtDrPadIO", ltDrPadIO], rtDrPadIO: ["IFUPLAPassRtDrPadIO", rtDrPadIO] ]; plaSizes: PUBLIC ARRAY IFUPLA.PLAs OF ARRAY IFUPLA.Sense OF NAT _ ALL[ALL[0]]; Commander.Register[key:"IFUPLA", proc: ReadIFUPLAs, doc: "Reads in the IFU PLA's - results are cached"]; Commander.Register[key:"IFUPLARead", proc: ReadIFUPLA, doc: "Reads in an IFU PLA given file name. (flushes previous cached read)"]; Commander.Register[key:"IFUPLAStats", proc: ReadAndAnalyzeIFUPLAs, doc: "Build statistics file for the IFU PLA's"]; END.