<> <> <> <<>> DIRECTORY Basics, BasicTime, IO, PLAOps, REFBit, Rope; PLAOpsImplC: CEDAR PROGRAM IMPORTS Basics, BasicTime, IO, PLAOps, REFBit, Rope EXPORTS PLAOps = BEGIN OPEN PLAOps, REFBit; NewPLA: PUBLIC PROC[inRef, outRef: REF, name: IO.ROPE] RETURNS[pla: PLA] = { inName, outName: IO.ROPE; WITH inRef SELECT FROM name: IO.ROPE => {inName _ name}; refText: REF TEXT => {inName _ Rope.FromRefText[refText]}; ref: REF => { inName _ REFBit.Desc[ref].typeName; IF inName = NIL OR inName.Length[]=0 THEN ERROR}; ENDCASE; WITH outRef SELECT FROM name: IO.ROPE => {outName _ name}; refText: REF TEXT => {outName _ Rope.FromRefText[refText]}; ref: REF => { outName _ REFBit.Desc[ref].typeName; IF outName = NIL OR outName.Length[]=0 THEN ERROR}; ENDCASE; pla _ NEW[PLARec _ [ name: name, mask: REFBit.NEWFromName[inName], data: REFBit.NEWFromName[inName], out: REFBit.NEWFromName[outName], time: BasicTime.Now[], termList: NIL, term: NIL] ]; FOR bit: INT IN [0..REFBit.Size[pla.data]) DO -- Check for non-zero initial value IF REFBit.Get[pla.data, bit] THEN { Error[IO.PutFR["Non-zero initial value for pla input record: %g.%g", IO.rope[inName], IO.rope[REFBit.Desc[pla.data].bitForm[bit].name]]]} ENDLOOP; FOR bit: INT IN [0..REFBit.Size[pla.out]) DO -- Check for non-zero initial value IF REFBit.Get[pla.out, bit] THEN { Error[IO.PutFR["Non-zero initial value for pla output record: %g.%g", IO.rope[outName], IO.rope[REFBit.Desc[pla.out].bitForm[bit].name]]]} ENDLOOP; pla.termList _ NEW[TermListRec _ [ inBits: REFBit.Desc[pla.data].wds.size*16, outBits: REFBit.Desc[pla.out].wds.size*16] ]; pla.term _ NewTerm[inBitSize: pla.termList.inBits, outBitSize: pla.termList.outBits] }; Error: ERROR [msg: IO.ROPE] = CODE; InvOutBits: PUBLIC PROC[pla: PLA, first, size: CARDINAL _ 0 ] = { newTerm: Term _ NewTerm[pla.termList.inBits, pla.termList.outBits]; be: BoolExpr _ NEW[TermListRec _ [inBits: pla.termList.inBits, outBits: pla.termList.outBits]]; IF pla.termList = NIL THEN RETURN; newTerm.in _ NIL; -- Throw away in sequence IF size=0 THEN size _ REFBit.Desc[pla.out].bitForm.size-first; FOR i: CARDINAL IN [0..newTerm.out.wdSize) DO newTerm.out[i] _ initOutQrtWz ENDLOOP; FOR out: CARDINAL IN [first..first+size) DO outBit: CARDINAL _ REFBit.Desc[pla.out].bitForm[out].firstBit; SetOutQrt[one, newTerm, outBit]; FOR refTerm: Term _ pla.termList.begin, refTerm.next WHILE refTerm#NIL DO q: Qrt _ GetOutQrt[refTerm, outBit]; IF q#one THEN LOOP; SetOutQrt[zero, refTerm, outBit]; newTerm.in _ refTerm.in; ACopy[newTerm, be ] ENDLOOP; be _ Not[be]; FOR refTerm: Term _ be.begin, refTerm.next WHILE refTerm#NIL DO newTerm.in _ refTerm.in; ACopy[newTerm, pla.termList ] ENDLOOP; WHILE be.begin#NIL DO DeleteTerm[be.begin, be] ENDLOOP; SetOutQrt[zero, newTerm, outBit]; ENDLOOP}; ReconfigurePLA: PUBLIC PROC[refPla: PLA, newIn, newOut: REF ] RETURNS[newPla: PLA] = { newTerm: Term; outFormOld, outFormNew, outFormXlt: Format; inFormOld, inFormNew, inFormXlt: Format; IF newIn = NIL THEN newIn _ refPla.data; IF newOut = NIL THEN newOut _ refPla.out; newPla _ NewPLA[newIn, newOut, refPla.name.Cat["Xform"]]; IF refPla.termList = NIL THEN RETURN[newPla]; newTerm _ NewTerm[newPla.termList.inBits, newPla.termList.outBits]; inFormOld _ REFBit.Desc[refPla.data].fieldForm; inFormNew _ REFBit.Desc[newPla.data].fieldForm; inFormXlt _ NEW[FormatSeq[inFormNew.size]]; -- translation from new to old field pos outFormOld _ REFBit.Desc[refPla.out].fieldForm; outFormNew _ REFBit.Desc[newPla.out].fieldForm; outFormXlt _ NEW[FormatSeq[outFormNew.size]]; -- translation from new to old field pos FOR newField: CARDINAL IN [0..outFormNew.size) DO FOR oldField: CARDINAL IN [0..outFormOld.size) DO IF Rope.Equal[outFormOld[oldField].name, outFormNew[newField].name] AND Rope.Equal[outFormOld[oldField].nameInv, outFormNew[newField].nameInv] THEN {outFormXlt[newField] _ outFormOld[oldField]; EXIT} REPEAT FINISHED => RETURN[NIL] -- NOT found -- ENDLOOP ENDLOOP; FOR newField: CARDINAL IN [0..inFormNew.size) DO FOR oldField: CARDINAL IN [0..inFormOld.size) DO IF Rope.Equal[inFormOld[oldField].name, inFormNew[newField].name] AND Rope.Equal[inFormOld[oldField].nameInv, inFormNew[newField].nameInv] THEN {inFormXlt[newField] _ inFormOld[oldField]; EXIT} REPEAT FINISHED => RETURN[NIL] -- NOT found -- ENDLOOP ENDLOOP; FOR i: CARDINAL IN [0..newTerm.out.wdSize) DO newTerm.out[i] _ initOutQrtWz ENDLOOP; FOR i: CARDINAL IN [0..newTerm.in.wdSize) DO newTerm.in[i] _ initInQrtWdc ENDLOOP; FOR refTerm: Term _ refPla.termList.begin, refTerm.next WHILE refTerm#NIL DO interesting: BOOL _ FALSE; FOR newField: CARDINAL IN [0..outFormNew.size) DO FOR bit: CARDINAL IN [0..outFormNew[newField].bitSize) DO q: Qrt _ GetOutQrt[refTerm, outFormXlt[newField].firstBit + bit]; SetOutQrt[q, newTerm, outFormNew[newField].firstBit + bit]; interesting _ interesting OR q=one OR q=dontcare ENDLOOP ENDLOOP; IF ~interesting THEN LOOP; FOR newField: CARDINAL IN [0..inFormNew.size) DO FOR bit: CARDINAL IN [0..inFormNew[newField].bitSize) DO q: Qrt _ GetInQrt[refTerm, inFormXlt[newField].firstBit + bit]; SetInQrt[q, newTerm, inFormNew[newField].firstBit + bit] ENDLOOP ENDLOOP; ACopy[newTerm, newPla.termList ] ENDLOOP; newTerm.in _ newTerm.out _ NIL; newTerm _ NIL }; <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> < ERROR -- NOT found -- ENDLOOP ENDLOOP;>> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> GetOutputBE: PUBLIC PROC[pla: PLA, out: CARDINAL] RETURNS[be: BoolExpr] = { outTL: TermList _ CopyTermListForField[pla.termList, out, 1]; beTerm: Term _ NewTerm[inBitSize: pla.termList.inBits, outBitSize: 16]; be _ NEW[TermListRec _ [inBits: pla.termList.inBits, outBits: 16] ]; IF outTL.length=0 THEN RETURN[NIL]; beTerm.out[0].d _ beTerm.out[0].m _ 177777B; FOR term: Term _ outTL.begin, term.next WHILE term#NIL DO beTerm.in _ term.in; []_UpdateCompleteSumWithTerm[be, beTerm,TRUE,TRUE]; ENDLOOP; []_FindAMinimalCover[be, 120]}; GetBEForDataMask: PUBLIC PROC[pla: PLA] RETURNS[be: BoolExpr] = { dDesc: REFBitDesc _ REFBit.Desc[pla.data]; mDesc: REFBitDesc _ REFBit.Desc[pla.mask]; term: Term _ NewTerm[inBitSize: pla.termList.inBits, outBitSize: 16]; pla.validTerm _ FALSE; be _ NEW[TermListRec _ [inBits: pla.termList.inBits, outBits: 16] ]; REFBit.TVToDescWds[dDesc]; REFBit.TVToDescWds[mDesc]; FOR i: CARDINAL IN [0..term.in.wdSize) DO term.in[i].d _ Basics.BITAND[dDesc.wds[i], mDesc.wds[i]]; term.in[i].m _ mDesc.wds[i]; ENDLOOP; term.out[0].d _ term.out[0].m _ 177777B; AppendTerm[term, be ] }; SetOutForBE: PUBLIC PROC[pla: PLA, be: BoolExpr] = { oDesc: REFBitDesc _ REFBit.Desc[pla.out]; pla.validTerm _ FALSE; REFBit.TVToDescWds[oDesc]; FOR i: CARDINAL IN [0..oDesc.wds.size) DO IF oDesc.wds[i] # 0 THEN EXIT; REPEAT FINISHED => RETURN ENDLOOP; FOR t: Term _ be.begin, t.next WHILE t#NIL DO new: Term _ NewTerm[pla.termList.inBits, pla.termList.outBits]; FOR i: CARDINAL IN [0..new.in.wdSize) DO new.in[i] _ t.in[i] ENDLOOP; FOR i: CARDINAL IN [0..pla.term.out.wdSize) DO new.out[i].d _ oDesc.wds[i]; new.out[i].m _ 177777B ENDLOOP; AppendTerm[new, pla.termList] ENDLOOP}; GetOutForData: PUBLIC PROC[pla: PLA] = { dDesc: REFBitDesc _ REFBit.Desc[pla.data]; oDesc: REFBitDesc _ REFBit.Desc[pla.out]; REFBit.TVToDescWds[dDesc]; FOR i: CARDINAL IN [0..pla.term.in.wdSize) DO IF NOT pla.validTerm OR pla.term.in[i].d # dDesc.wds[i] THEN {pla.validTerm _ FALSE; pla.term.in[i].d _ dDesc.wds[i]}; IF NOT pla.validTerm OR pla.term.in[i].m # 177777B THEN {pla.validTerm _ FALSE; pla.term.in[i].m _ 177777B}; ENDLOOP; IF NOT pla.validTerm THEN { GetTermVal[pla.term, pla.termList]; pla.validTerm _ TRUE; FOR i: CARDINAL IN [0..pla.term.out.wdSize) DO oDesc.wds[i] _ pla.term.out[i].d ENDLOOP; REFBit.DescWdsToTV[oDesc]} }; END.