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