PLAOpsImplC.mesa
Copyright © 1984 by Xerox Corporation. All rights reserved.
Last edited by Curry, April 4, 1986 2:38:28 pm PST
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: BOOLFALSE;
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 };
CopyPLASubFields: PUBLIC PROC[refPla: PLA, inRef, outRef: REF ]
RETURNS[newPla: PLA] = {
newTerm: Term;
refForm, newForm, oldForm: Format;
newPla ← NewPLA[refPla.data, outRef];
IF refPla.termList = NIL THEN RETURN[NIL];
newTerm ← NewTerm[newPla.termList.inBits, newPla.termList.outBits];
newTerm.in ← NIL; -- Throw away in sequence
refForm ← REFBit.Desc[refPla.out].fieldForm;
newForm ← REFBit.Desc[newPla.out].fieldForm;
oldForm ← NEW[FormatSeq[newForm.size]]; -- translation from new to old field position
FOR newField: CARDINAL IN [0..newForm.size) DO
FOR refField: CARDINAL IN [0..refForm.size) DO
IF
Rope.Equal[refForm[refField].name,  newForm[newField].name] AND
Rope.Equal[refForm[refField].nameInv, newForm[newField].nameInv]
THEN {oldForm[newField] ← refForm[refField]; EXIT}
REPEAT FINISHED => ERROR -- NOT found -- ENDLOOP ENDLOOP;
FOR i: CARDINAL IN [0..newTerm.out.wdSize) DO
newTerm.out[i] ← initOutQrtWz ENDLOOP;
FOR refTerm: Term ← refPla.termList.begin, refTerm.next WHILE refTerm#NIL DO
interesting: BOOLFALSE;
FOR field: CARDINAL IN [0..newForm.size) DO
FOR bit: CARDINAL IN [0..newForm[field].bitSize) DO
q: Qrt ← GetOutQrt[refTerm, oldForm[field].firstBit + bit];
SetOutQrt[q, newTerm, newForm[field].firstBit + bit];
interesting ← interesting OR q=one OR q=dontcare
ENDLOOP;
ENDLOOP;
IF ~interesting THEN LOOP;
newTerm.in ← refTerm.in; ACopy[newTerm, newPla.termList ];
ENDLOOP;
newTerm.in ← newTerm.out ← NIL;
newTerm ← NIL };
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;
[]𡤏indAMinimalCover[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.