00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "propagate.hh"
00025 #include "prim2.hh"
00026 #include <assert.h>
00027 #include "ppbox.hh"
00028 #include "xtended.hh"
00029 #include "labels.hh"
00030 #include "Text.hh"
00031 #include "ppsig.hh"
00032 #include "names.hh"
00033
00034
00035
00036
00037
00039
00045
00046
00047
00049 siglist mix(const siglist& lsig, int nbus)
00050 {
00051 int nlines = lsig.size();
00052
00053 siglist dst(nbus);
00054
00055 for (int b=0; b<nbus; b++) {
00056 Tree t = (b<nlines) ? lsig[b] : sigInt(0);
00057 for (int i=b+nbus; i<nlines; i+=nbus) {
00058 t = sigAdd(t, lsig[i]);
00059 }
00060 dst[b] = t;
00061 }
00062 return dst;
00063 }
00064
00066 siglist split(const siglist& inputs, int nbus)
00067 {
00068 int nlines = inputs.size();
00069
00070 siglist outputs(nbus);
00071
00072 for (int b=0; b<nbus; b++) {
00073 outputs[b] = inputs[b % nlines];
00074 }
00075 return outputs;
00076 }
00077
00079 siglist makeSigProjList (Tree t, int n)
00080 {
00081 siglist l(n);
00082 for (int i = 0; i < n; i++) l[i] = sigDelay0(sigProj(i, t));
00083 return l;
00084 }
00085
00087 siglist makeMemSigProjList (Tree t, int n)
00088 {
00089 siglist l(n);
00090 for (int i = 0; i < n; i++) l[i] = sigDelay1(sigProj(i, t));
00091 return l;
00092 }
00093
00094
00096 siglist makeSigInputList (int n)
00097 {
00098 siglist l(n);
00099 for (int i = 0; i < n; i++) l[i] = sigInput(i);
00100 return l;
00101 }
00102
00103 inline siglist makeList(Tree t)
00104 {
00105 siglist l(1);
00106 l[0] = t;
00107 return l;
00108 }
00109
00110 siglist listRange(const siglist& l, int i, int j)
00111 {
00112 siglist r(j-i);
00113 for (int x = i; x < j; x++) r[x-i] = l[x];
00114 return r;
00115 }
00116
00117 siglist listConcat(const siglist& a, const siglist& b)
00118 {
00119 int n1 = a.size();
00120 int n2 = b.size();
00121 siglist r(n1+n2);
00122
00123 for (int x=0; x<n1; x++) r[x] = a[x];
00124 for (int x=0; x<n2; x++) r[x+n1] = b[x];
00125 return r;
00126 }
00127
00128 Tree listConvert(const siglist& a)
00129 {
00130 int n = a.size();
00131 Tree t=nil;
00132 while (n--) t = cons(a[n],t);
00133 return t;
00134 }
00135
00136
00137
00138
00139
00140
00141
00142
00143 siglist listLift(const siglist& l)
00144 {
00145 int n = l.size();
00146 siglist r(n);
00147
00148 for(int i = 0; i<n; i++) r[i] = lift(l[i]);
00149 return r;
00150 }
00151
00152 static int gDummyInput = 10000;
00153
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196 siglist propagate (Tree slotenv, Tree path, Tree box, const siglist& lsig)
00197 {
00198 int i;
00199 double r;
00200 prim0 p0;
00201 prim1 p1;
00202 prim2 p2;
00203 prim3 p3;
00204 prim4 p4;
00205 prim5 p5;
00206
00207 Tree t1, t2, ff, label, cur, min, max, step, type, name, file, slot, body;
00208
00209
00210 xtended* xt = (xtended*)getUserData(box);
00211
00212
00213
00214 if (xt) {
00215 assert(lsig.size() == xt->arity());
00216 return makeList(xt->computeSigOutput(lsig));
00217 }
00218
00219
00220
00221 else if (isBoxInt(box, &i)) {
00222 assert(lsig.size()==0);
00223 return makeList(sigInt(i));
00224 }
00225 else if (isBoxReal(box, &r)) {
00226 assert(lsig.size()==0);
00227 return makeList(sigReal(r));
00228 }
00229
00230 else if (isBoxFConst(box, type, name, file)) {
00231 assert(lsig.size()==0);
00232 return makeList(sigFConst(type, name, file));
00233 }
00234
00235 else if (isBoxFVar(box, type, name, file)) {
00236 assert(lsig.size()==0);
00237 return makeList(sigFVar(type, name, file));
00238 }
00239
00240
00241
00242 else if (isBoxCut(box)) {
00243 assert(lsig.size()==1);
00244 return siglist();
00245 }
00246
00247 else if (isBoxWire(box)) {
00248 assert(lsig.size()==1);
00249 return lsig;
00250 }
00251
00252
00253
00254 else if (isBoxSlot(box)) {
00255 Tree sig;
00256 assert(lsig.size()==0);
00257 if (!searchEnv(box,sig,slotenv)) {
00258
00259
00260
00261 sig = sigInput(++gDummyInput);
00262 }
00263 return makeList(sig);
00264 }
00265
00266 else if (isBoxSymbolic(box, slot, body)) {
00267 assert(lsig.size()>0);
00268 return propagate(pushEnv(slot,lsig[0],slotenv), path, body, listRange(lsig, 1, lsig.size()));
00269 }
00270
00271
00272
00273 else if (isBoxPrim0(box, &p0)) {
00274 assert(lsig.size()==0);
00275 return makeList( p0() );
00276 }
00277
00278 else if (isBoxPrim1(box, &p1)) {
00279 assert(lsig.size()==1);
00280 return makeList( p1(lsig[0]) );
00281 }
00282
00283 else if (isBoxPrim2(box, &p2)) {
00284
00285 assert(lsig.size()==2);
00286 return makeList( p2(lsig[0],lsig[1]) );
00287 }
00288
00289 else if (isBoxPrim3(box, &p3)) {
00290 assert(lsig.size()==3);
00291 return makeList( p3(lsig[0],lsig[1],lsig[2]) );
00292 }
00293
00294 else if (isBoxPrim4(box, &p4)) {
00295 assert(lsig.size()==4);
00296 return makeList( p4(lsig[0],lsig[1],lsig[2],lsig[3]) );
00297 }
00298
00299 else if (isBoxPrim5(box, &p5)) {
00300 assert(lsig.size()==5);
00301 return makeList( p5(lsig[0],lsig[1],lsig[2],lsig[3],lsig[4]) );
00302 }
00303
00304 else if (isBoxFFun(box, ff)) {
00305
00306 assert(int(lsig.size())==ffarity(ff));
00307 return makeList(sigFFun(ff, listConvert(lsig)));
00308 }
00309
00310
00311
00312 else if (isBoxButton(box, label)) {
00313 assert(lsig.size()==0);
00314 return makeList(sigButton(normalizePath(cons(label, path))));
00315 }
00316
00317 else if (isBoxCheckbox(box, label)) {
00318 assert(lsig.size()==0);
00319 return makeList(sigCheckbox(normalizePath(cons(label, path))));
00320 }
00321
00322 else if (isBoxVSlider(box, label, cur, min, max, step)) {
00323 assert(lsig.size()==0);
00324 return makeList(sigVSlider(normalizePath(cons(label, path)), cur, min, max, step));
00325 }
00326
00327 else if (isBoxHSlider(box, label, cur, min, max, step)) {
00328 assert(lsig.size()==0);
00329 return makeList(sigHSlider(normalizePath(cons(label, path)), cur, min, max, step));
00330 }
00331
00332 else if (isBoxNumEntry(box, label, cur, min, max, step)) {
00333 assert(lsig.size()==0);
00334 return makeList(sigNumEntry(normalizePath(cons(label, path)), cur, min, max, step));
00335 }
00336
00337 else if (isBoxVBargraph(box, label, min, max)) {
00338 assert(lsig.size()==1);
00339 return makeList(sigVBargraph(normalizePath(cons(label, path)), min, max, lsig[0]));
00340 }
00341
00342 else if (isBoxHBargraph(box, label, min, max)) {
00343 assert(lsig.size()==1);
00344 return makeList(sigHBargraph(normalizePath(cons(label, path)), min, max, lsig[0]));
00345 }
00346
00347
00348
00349 else if (isBoxVGroup(box, label, t1)) {
00350 return propagate(slotenv,cons(cons(tree(0),label), path), t1, lsig);
00351 }
00352
00353 else if (isBoxHGroup(box, label, t1)) {
00354 return propagate(slotenv, cons(cons(tree(1),label), path), t1, lsig);
00355 }
00356
00357 else if (isBoxTGroup(box, label, t1)) {
00358 return propagate(slotenv, cons(cons(tree(2),label), path), t1, lsig);
00359 }
00360
00361
00362
00363 else if (isBoxSeq(box, t1, t2)) {
00364 int in1, out1, in2, out2;
00365 getBoxType(t1, &in1, &out1);
00366 getBoxType(t2, &in2, &out2);
00367
00368 assert(out1==in2);
00369
00370 if (out1 == in2) {
00371 return propagate(slotenv, path, t2, propagate(slotenv, path,t1,lsig));
00372 } else if (out1 > in2) {
00373 siglist lr = propagate(slotenv, path, t1,lsig);
00374 return listConcat(propagate(slotenv, path, t2, listRange(lr, 0, in2)), listRange(lr, in2, out1));
00375 } else {
00376 return propagate(slotenv, path, t2, listConcat( propagate(slotenv, path, t1, listRange(lsig,0,in1)), listRange(lsig,in1,in1+in2-out1) ) );
00377 }
00378 }
00379
00380 else if (isBoxPar(box, t1, t2)) {
00381 int in1, out1, in2, out2;
00382 getBoxType(t1, &in1, &out1);
00383 getBoxType(t2, &in2, &out2);
00384
00385 return listConcat( propagate(slotenv, path, t1, listRange(lsig, 0, in1)),
00386 propagate(slotenv, path, t2, listRange(lsig, in1, in1+in2)) );
00387 }
00388
00389 else if (isBoxSplit(box, t1, t2)) {
00390 int in1, out1, in2, out2;
00391 getBoxType(t1, &in1, &out1);
00392 getBoxType(t2, &in2, &out2);
00393
00394 siglist l1 = propagate(slotenv, path, t1, lsig);
00395 siglist l2 = split(l1, in2);
00396 return propagate(slotenv, path, t2, l2);
00397 }
00398
00399 else if (isBoxMerge(box, t1, t2)) {
00400 int in1, out1, in2, out2;
00401 getBoxType(t1, &in1, &out1);
00402 getBoxType(t2, &in2, &out2);
00403
00404 siglist l1 = propagate(slotenv, path, t1, lsig);
00405 siglist l2 = mix(l1, in2);
00406 return propagate(slotenv, path, t2, l2);
00407 }
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421 else if (isBoxRec(box, t1, t2)) {
00422
00423 int in1, out1, in2, out2;
00424 getBoxType(t1, &in1, &out1);
00425 getBoxType(t2, &in2, &out2);
00426
00427 Tree slotenv2 = lift(slotenv);
00428
00429 siglist l0 = makeMemSigProjList(ref(1), in2);
00430 siglist l1 = propagate(slotenv2, path, t2, l0);
00431 siglist l2 = propagate(slotenv2, path, t1, listConcat(l1,listLift(lsig)));
00432 Tree g = rec(listConvert(l2));
00433 return makeSigProjList(g, out1);
00434 }
00435
00436 cout << "ERROR in file " << __FILE__ << ':' << __LINE__ << ", unrecognised box expression : " << boxpp(box) << endl;
00437 exit(1);
00438 return siglist();
00439 }
00440
00441
00442 Tree boxPropagateSig (Tree path, Tree box, const siglist& lsig)
00443 {
00444 return listConvert(propagate(nil, path, box, lsig));
00445 }
00446