1// Scicos 2// 3// Copyright (C) INRIA - METALAU Project <scicos@inria.fr> 4// 5// This program is free software; you can redistribute it and/or modify 6// it under the terms of the GNU General Public License as published by 7// the Free Software Foundation; either version 2 of the License, or 8// (at your option) any later version. 9// 10// This program is distributed in the hope that it will be useful, 11// but WITHOUT ANY WARRANTY; without even the implied warranty of 12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13// GNU General Public License for more details. 14// 15// You should have received a copy of the GNU General Public License 16// along with this program; if not, write to the Free Software 17// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18// 19// See the file ../license.txt 20// 21 22function cpr=c_pass2(bllst,connectmat,clkconnect,cor,corinv,flag) 23 // cor ; correspondence table with initial block ordering 24 // 25 // bllst: list with nblk elts where nblk denotes number of blocks. 26 // Each element must be a list with 16 elements: 27 // 1- a list containing function name and function type 28 // 2- vector of number of inputs 29 // 3- vector of number of outputs 30 // 4- vector of number of clock inputs 31 // 5- vector of number of clock outputs 32 // 6- vector (column) of continuous initial condition 33 // 7- vector (column) of discrete initial condition 34 // 8- vector (column) of real parameters 35 // 9- vector (column) of integer parameters 36 // 10- string: 'l' for synchro (ifthenelse,eselect) or 'm' 37 // (memo) or 'x' for blocks that need to be called during 38 // integration even in the absence of state (only if with workspace) 39 // 11- vector of size <number of clock outputs> including 40 // preprogrammed event firing times (<0 if no firing) 41 // 12- boolean vector (column): 1:nin entry for dependence on u, 42 // last on t 43 // 13- block label 44 // 14- number of zero crossings 45 // 15- number of modes 46 // 16- empty list (equation for modelica blocks) 47 // 48 // connectmat: nx4 matrix. Each row contains, in order, the block 49 // number and the port number of an outgoing scicopath, 50 // and the block number and the port number of the target 51 // ingoing scicopath. 52 // 53 // clkconnect: same as connectmat but for clock scicopaths. 54 // 55 // define some constants 56 if argn(2) <6 then flag="verbose",end 57 show_trace=%f 58 if show_trace then mprintf("c_pass1:\t%f\n", timer()),end 59 60 show_pause=%f; 61 show_comment=%f; 62 63 if bllst==list() then 64 messagebox(_("No block can be activated"),"modal","error") 65 cpr=list() 66 ok=%f; 67 return 68 end 69 70 //correction of clkconnect.. Must be done before 71 clkconnect(find(clkconnect(:,2)==0),2)=1; 72 73 74 75 76 if exists("%scicos_solver")==0 then %scicos_solver=0,end 77 78 clkptr=1,cliptr=1,typ_l=[], 79 nblk=size(bllst) 80 81 //take care of the heritage 82 [bllst,inplnk,outlnk,clkptr,cliptr,inpptr,outptr,dep_u,dep_uptr,dep_t,.. 83 typ_l,typ_r,typ_m,tblock,typ_cons,typ_zx,ok]=mini_extract_info(bllst,.. 84 connectmat,clkconnect) 85 if show_trace then mprintf("c_pass20:\t%f\n", timer()),end 86 if ~ok then 87 cpr=list() 88 return 89 end 90 [outoin,outoinptr]=conn_mat(inpptr,outptr,inplnk,outlnk) 91 92 [critev]=critical_events(connectmat,clkconnect,dep_t,typ_r,.. 93 typ_l,typ_zx,outoin,outoinptr,clkptr) 94 [clkconnect,exe_cons]=pak_ersi(connectmat,clkconnect,typ_r,.. 95 typ_l,outoin,outoinptr,tblock,typ_cons,clkptr) 96 97 98 [ordclk,ordptr,cord,typ_l,clkconnect,connectmat,bllst,dep_t,dep_u,.. 99 dep_uptr,corinv,clkptr,cliptr,critev,ok]=paksazi2(typ_l,clkconnect,.. 100 connectmat,bllst,dep_t,dep_u,dep_uptr,corinv,clkptr,cliptr,critev) 101 102 if ~ok then 103 cpr=list() 104 return 105 end 106 107 if show_pause then 108 mprintf("fin de paksazi") 109 pause 110 end 111 112 if show_trace then mprintf("c_pass31:\t%f\n", timer()),end 113 114 //extract various info from bllst 115 [lnksz,lnktyp,inplnk,outlnk,clkptr,cliptr,inpptr,outptr,xptr,zptr,.. 116 ozptr,typ_mod,rpptr,ipptr,opptr,xc0,xcd0,xd0,oxd0,rpar,.. 117 ipar,opar,typ_z,typ_x,typ_m,funs,funtyp,initexe,labels,uids,.. 118 bexe,boptr,blnk,blptr,ok]=extract_info(bllst,connectmat,clkconnect,typ_l); 119 typ_z0=typ_z; 120 121 122 123 if ~ok then 124 messagebox(_("Problem in port size or type."),"modal","error"); 125 cpr=list() 126 return, 127 end 128 129 if show_trace then mprintf("c_pass41:\t%f\n", timer()),end 130 131 //form a matrix which gives destinations of each block 132 [outoin,outoinptr]=conn_mat(inpptr,outptr,inplnk,outlnk) 133 [evoutoin,evoutoinptr]=synch_clkconnect(typ_l,clkconnect) 134 // 135 if show_trace then mprintf("c_pass50:\t%f\n", timer()),end 136 137 [execlk_cons]=discard(clkptr,cliptr,clkconnect,exe_cons) 138 139 clkconnect=[];exe_cons=[] 140 141 if show_trace then mprintf("c_pass501:\t%f\n", timer()),end 142 143 // Set execution scheduling tables 144 [ordclk,iord,oord,zord,typ_z,ok]=scheduler(inpptr,outptr,clkptr,execlk_cons,.. 145 outoin,outoinptr,evoutoin,evoutoinptr,typ_z,typ_x,typ_l,bexe,boptr,blnk,blptr,.. 146 ordclk,ordptr,cord,dep_t,dep_u,dep_uptr); 147 148 if ~ok then 149 cpr=list() 150 return, 151 end 152 153 if show_trace then mprintf("c_pass51:\t%f\n", timer()),end 154 //form scicos arguments 155 156 nb=size(typ_z,"*"); 157 zcptr=ones(nb+1,1); 158 modptr=ones(nb+1,1); 159 160 for i=1:nb 161 zcptr(i+1)=zcptr(i)+typ_z(i) 162 modptr(i+1)=modptr(i)+sign(typ_z(i))*typ_mod(i); 163 end 164 165 ztyp=sign(typ_z0) //completement inutile pour simulation 166 // utiliser pour la generation de code 167 168 if xptr($)==1 & zcptr($)>1 then 169 mess=msprintf(_("No continuous-time state. Thresholds are ignored; this \nmay be OK if you don''t generate external events with them.\nIf you want to reactivate the thresholds, then you need\n\nto include a block with continuous-time state in your diagram.\n You can for example include DUMMY CLSS block (linear palette).")) 170 messagebox(mess,"modal","error"); 171 end 172 173 subscr=[] 174 ncblk=0;nxblk=0;ndblk=0;ndcblk=0; 175 sim=scicos_sim(funs=funs,xptr=xptr,zptr=zptr,ozptr=ozptr,.. 176 zcptr=zcptr,inpptr=inpptr,outptr=outptr,.. 177 inplnk=inplnk,outlnk=outlnk,rpar=rpar,rpptr=rpptr,.. 178 ipar=ipar,ipptr=ipptr,opar=opar,opptr=opptr,.. 179 clkptr=clkptr,ordptr=ordptr,execlk=ordclk,.. 180 ordclk=ordclk,cord=cord,oord=oord,zord=zord,.. 181 critev=critev(:),nb=nb,ztyp=ztyp,nblk=nblk,.. 182 ndcblk=ndcblk,subscr=subscr,funtyp=funtyp,.. 183 iord=iord,labels=labels,uids=uids,modptr=modptr); 184 185 //initialize agenda 186 [tevts,evtspt,pointi]=init_agenda(initexe,clkptr) 187 if show_trace then mprintf("c_pass61:\t%f\n", timer()),end 188 189 //mod= zeros(modptr($)-1,1) 190 191 outtb=list(); 192 outtb=buildouttb(lnksz,lnktyp); 193 194 iz0=zeros(nb,1); 195 196 if max(funtyp)>10000 &%scicos_solver==0 then 197 warning(_("Diagram contains implicit blocks, compiling for implicit Solver.")) 198 %scicos_solver=100 199 end 200 if or(%scicos_solver==[100, 101, 102]) then xc0=[xc0;xcd0],end 201 state=scicos_state() 202 state.x=xc0 203 state.z=xd0 204 state.oz=oxd0 205 state.iz=iz0 206 state.tevts=tevts 207 state.evtspt=evtspt 208 state.pointi=pointi 209 state.outtb=outtb 210 // state.mod=mod 211 212 cpr=scicos_cpr(state=state,sim=sim,cor=cor,corinv=corinv); 213 214 if show_trace then mprintf("c_pass71:\t%f\n", timer()),end 215 216endfunction 217 218 219//donne les sources d'activation du sch�ma 220function [vec_clk]=get_clocks(clkconnect,clkptr) 221 vec_clk=[] 222 if (find(clkconnect(:,1)==0) ~=[]) then 223 //activation continue 224 vec_clk=[vec_clk;0 0]; 225 end 226 for blk=1:size(clkptr,1)-1 227 if ~typ_l(blk) then 228 for port=1:clkptr(blk+1)-clkptr(blk) 229 vec_clk=[vec_clk; blk port]; 230 end 231 end 232 end 233endfunction 234 235 236 237//insere le vecteur primary dans vec_clk apr�s la ligne comptenant le bloc i 238function vec_clk0=set_primary_clk(vec_clk,primary,i) 239 240 if vec_clk~=[] then 241 n_vc0=find(vec_clk==i) 242 n_vc0=n_vc0($) 243 vec_clk0=vec_clk(1:n_vc0) 244 vec_clk1=vec_clk(n_vc0+1:size(vec_clk,1)) 245 for k=1:size(primary,1) 246 if find(primary(k)==vec_clk0)==[] then 247 vec_clk0($+1)=primary(k) 248 end 249 end 250 for k=1:size(vec_clk1,1) 251 if find(vec_clk1(k)==vec_clk0)==[] then 252 vec_clk0($+1)=vec_clk1(k) 253 end 254 end 255 else 256 vec_clk0=primary 257 end 258 259endfunction 260 261//insere la sous-matrice primary dans vec_clk apr�s la ligne k 262function vec_clk0=set_primary_clkport(vec_clk,primary,i) 263 264 if vec_clk~=[] then 265 vec_clk0=vec_clk(1:i,:) 266 vec_clk1=vec_clk(i+1:size(vec_clk,1),:) 267 for k=1:size(primary,1) 268 f=find(primary(k,1)==vec_clk0(:,1)) 269 if f==[] then 270 vec_clk0=[vec_clk0;primary(k,:)] 271 end 272 end 273 n_vc1=size(vec_clk1,1) 274 if n_vc1>0 then 275 for k=1:n_vc1 276 f=find(vec_clk1(k,1)==vec_clk0(:,1)) 277 if f==[] then 278 vec_clk0=[vec_clk0;vec_clk1(k,:)] 279 end 280 end 281 end 282 else 283 vec_clk0=primary 284 end 285 286endfunction 287 288//insere la sous-matrice ordoclk0 dans ordclk apr�s le block k 289function [ordptr,ordclk,blocs_traites]=set_ordclk(ordclk,.. 290 ordoclk0,k,j,ordptr,blocs_traites) 291 if ordoclk0~=[] then 292 if ordclk==[] then 293 ordclk=[ordclk;ordoclk0]; 294 ordptr($+1)=ordptr($)+size(ordoclk0,1); 295 blocs_traites=[blocs_traites;k] //k 296 else 297 m=max(find(blocs_traites==k)) 298 if j>1 & m~=[] then 299 ordclk=[ordclk(1:ordptr(m+1)-1,:);ordoclk0;ordclk(ordptr(m+1):$,:)] 300 ordptr=[ordptr(1:m+1);ordptr(m+1:$)+size(ordoclk0,1)] 301 blocs_traites=[blocs_traites(1:m);k;blocs_traites(m+1:$)] 302 else 303 ind=find(blocs_traites <k) 304 m=max(ind) 305 if m==size(blocs_traites,1) then 306 ordclk=[ordclk;ordoclk0] 307 ordptr($+1)=ordptr($)+size(ordoclk0,1); 308 blocs_traites=[blocs_traites;k] 309 else 310 if m~=[] then 311 ordclk=[ordclk(1:ordptr(m+1)-1,:);ordoclk0;ordclk(ordptr(m+1):$,:)] 312 ordptr=[ordptr(1:m+1);ordptr(m+1:$)+size(ordoclk0,1)] 313 blocs_traites=[blocs_traites(1:m);k;blocs_traites(m+1:$)] 314 else 315 ordclk=[ordoclk0;ordclk] 316 ordptr=[1;ordptr+size(ordoclk0,1)] 317 blocs_traites=[k;blocs_traites] 318 end 319 end 320 end 321 end 322 else 323 if j>1 & find((blocs_traites==k))~=[] then 324 m=max(find(blocs_traites==k)) 325 ordptr=[ordptr(1:m+1);ordptr(m+1:$)+size(ordoclk0,1)] 326 blocs_traites=[blocs_traites(1:m);k;blocs_traites(m+1:$)] 327 else 328 ind=find(blocs_traites <k) 329 m=max(ind) 330 if m==size(blocs_traites,1) then 331 ordptr($+1)=ordptr($)+size(ordoclk0,1); 332 blocs_traites=[blocs_traites;k] 333 else 334 if m~=[] then 335 ordptr=[ordptr(1:m+1);ordptr(m+1:$)+size(ordoclk0,1)] 336 blocs_traites=[blocs_traites(1:m);k;blocs_traites(m+1:$)] 337 else 338 ordptr=[1;ordptr+size(ordoclk0,1)] 339 blocs_traites=[k;blocs_traites] 340 end 341 end 342 end 343 end 344endfunction 345 346 347//donne les blocs activant blk 348function [parents]=get_parents(parents,blk) 349 f=find(clkconnect(:,3)==blk) 350 n_f=size(f,2) 351 if n_f>0 then 352 for i=1:n_f 353 clki1=clkconnect(f(i),1) 354 clki2=clkconnect(f(i),2) 355 g=find(clki1==parents(:,1)) 356 if g==[] | (g~=[] & parents(g,2)~=clki2) then 357 parents=[parents;clki1,clki2] 358 end 359 end 360 end 361endfunction 362 363 364function [blks,blksptr]=depend_on(connectmat,dep_u,dep_uptr) 365 // returns the blocks on which depend directly a block 366 blks=[];blksptr=1 367 for i=1:size(dep_uptr,"*")-1 368 indport=find(dep_u(dep_uptr(i):dep_uptr(i+1)-1)); 369 f=[] 370 for j=indport 371 f=[f,find(connectmat(:,3)==i&connectmat(:,4)==j)] 372 end 373 blkis=unique(connectmat(f,1)) 374 blks=[blks;blkis] 375 blksptr=[blksptr;blksptr($)+size(blkis,"*")] 376 end 377endfunction 378 379function [eblks,eblksptr]=update_event_depend_on(eblks,eblksptr,clkconnect,cliptr,bls) 380 // updates the blocks activating a block 381 nb1=size(cliptr,"*") 382 eblksptr($:nb1)=eblksptr($) 383 for i=bls 384 f=find(clkconnect(:,3)==i) 385 blkis=unique(clkconnect(f,1)) 386 dblkis=size(blkis,"*")-(eblksptr(i+1)-eblksptr(i)) 387 Ibef=eblksptr(1):eblksptr(i)-1; 388 Iaft=eblksptr(i+1):eblksptr($)-1; 389 eblks=[eblks(Ibef);blkis;eblks(Iaft)] 390 eblksptr(i+1:$)=eblksptr(i+1:$)+dblkis 391 end 392endfunction 393 394 395function [fblks,fblksptr]=update_event_activates(fblks,fblksptr,clkconnect,clkptr,bls) 396 // returns the blocks activated by a block (assumed typ_l) 397 nb1=size(cliptr,"*") 398 fblksptr($:nb1)=fblksptr($) 399 for i=bls 400 f=find(clkconnect(:,1)==i) 401 blkis=unique(clkconnect(f,3)) 402 dblkis=size(blkis,"*")-(fblksptr(i+1)-fblksptr(i)) 403 Ibef=fblksptr(1):fblksptr(i)-1; 404 Iaft=fblksptr(i+1):fblksptr($)-1; 405 fblks=[fblks(Ibef);blkis;fblks(Iaft)] 406 fblksptr(i+1:$)=fblksptr(i+1:$)+dblkis 407 end 408endfunction 409 410 411function [eblks,eblksptr]=event_depend_on(clkconnect,cliptr) 412 // returns the blocks activating a block 413 eblks=[];eblksptr=1 414 for i=1:size(cliptr,"*")-1 415 f=find(clkconnect(:,3)==i) 416 blkis=unique(clkconnect(f,1)) 417 eblks=[eblks;blkis] 418 eblksptr=[eblksptr;eblksptr($)+size(blkis,"*")] 419 end 420endfunction 421 422 423function [fblks,fblksptr]=event_activates(clkconnect,clkptr) 424 // returns the blocks activated by a block of type typ_l 425 fblks=[];fblksptr=1 426 for i=1:size(typ_l,"*") 427 if typ_l(i) then 428 f=find(clkconnect(:,1)==i) 429 blkis=unique(clkconnect(f,3)) 430 fblks=[fblks;blkis] 431 else 432 blkis=[] 433 end 434 fblksptr=[fblksptr;fblksptr($)+size(blkis,"*")] 435 end 436endfunction 437 438 439function uni=merge_mat(m1,m2) 440 // for m1 and m2 with two columns containing >=0 values 441 if isempty(m1) & isempty(m2) then 442 uni=[]; 443 return; 444 end 445 uni=[m1;m2] 446 n=max(uni(:,2))+1; 447 [j,ind]=unique(uni(:,1)*n+uni(:,2)) 448 uni=uni(-gsort(-ind),:) 449endfunction 450 451function [typ_l,clkconnect,connectmat,vbllst,dep_t,dep_u,dep_uptr,.. 452 corinv,clkptr,cliptr,critev]=duplicate_block(bl,typ_l,clkconnect,.. 453 connectmat,vbllst,dep_t,dep_u,dep_uptr,corinv,clkptr,cliptr,critev) 454 455 nblock=size(typ_l,1)+1 456 g=find(clkconnect(:,1)==bl) 457 if g<> [] then 458 xx=clkconnect(g,:) 459 xx(:,1)=nblock 460 clkconnect=[clkconnect;xx] 461 end 462 463 g=find(connectmat(:,3)==bl) 464 xx=connectmat(g,:) 465 xx(:,3)=nblock*ones(size(xx,1),1) 466 connectmat=[connectmat;xx] 467 468 typ_l($+1)=%t 469 critev=[critev;critev(clkptr(bl):clkptr(bl+1)-1)] 470 vbllst(nblock)=vbllst(bl) 471 dep_t(nblock)=dep_t(bl) 472 dep_u=[dep_u;dep_u(dep_uptr(bl))] 473 dep_uptr($+1)=dep_uptr($)+1 474 475 corinv(nblock)=corinv(bl) 476 clkptr(nblock+1)=clkptr(nblock)+clkptr(bl+1)-clkptr(bl) 477 cliptr(nblock+1)=cliptr(nblock)+cliptr(bl+1)-cliptr(bl) 478 479endfunction 480 481function [childs]=get_allchilds(primary,fblks,fblksptr,typ_l) 482 483 oldtaille=0 484 childs=primary(:)' 485 taille=size(childs,"*") 486 487 while oldtaille<>taille 488 oldtaille=taille 489 for i=childs(typ_l(childs)) 490 bb=fblks(fblksptr(i):fblksptr(i+1)-1) 491 childs=union(childs,bb) 492 end 493 taille=size(childs,"*") 494 end 495endfunction 496 497 498function ok=is_alg_event_loop(typ_l,clkconnect) 499 clkconnect(find(clkconnect(:,1)==0),:)=[] 500 lclkconnect=clkconnect(typ_l(clkconnect(:,1))&typ_l(clkconnect(:,3)),[1,3]) 501 n=size(typ_l,"*") 502 oldvec=zeros(n,1) 503 vec(lclkconnect(:,1))=1 504 i=0 505 ok=%f 506 while i<=n 507 i=i+1 508 oldvec=vec // not optimal to use large v 509 if isempty(vec(lclkconnect(:,1))) then 510 vec(lclkconnect(:,2))=1 511 else 512 vec(lclkconnect(:,2))=vec(lclkconnect(:,1))+1 513 end 514 if and(vec==oldvec) then 515 ok=%t 516 return 517 end 518 end 519endfunction 520 521function [ordclk,ordptr,cord,typ_l,clkconnect,connectmat,bllst,dep_t,dep_u,dep_uptr,corinv,clkptr,cliptr,critev,ok]=paksazi2(typ_l,clkconnect,connectmat,bllst,dep_t,dep_u,dep_uptr,corinv,clkptr,cliptr,critev) 522 523 ordclk=[];ordptr=1;cord=[]; 524 lordclk=list() 525 526 vbllst=1:length(bllst) 527 528 zz=get_clocks(clkconnect,clkptr) 529 //testing event algebraic loops 530 ok=is_alg_event_loop(typ_l,clkconnect) 531 if ~ok then 532 disp(msprintf("%s: alg_event_loop failed", "c_pass2")); 533 messagebox(_("Algebraic loop on events."),"modal","error"); 534 return 535 end 536 537 538 ok=%t 539 [fblks,fblksptr]=event_activates(clkconnect,clkptr) 540 [blks,blksptr]=depend_on(connectmat,dep_u,dep_uptr) 541 [eblks,eblksptr]=event_depend_on(clkconnect,cliptr) 542 543 544 for i=1:size(zz,1) 545 546 nblock=size(typ_l,1); // number of blocks in diagram 547 548 todo=zz(i,:) 549 while todo<>[] 550 551 blk=todo(1,1);port=todo(1,2); 552 if blk==0 |find(definedfields(lordclk)==clkptr(blk)+port-1)==[] then 553 554 f=find(clkconnect(:,1)==blk&clkconnect(:,2)==port); 555 if f<>[] then 556 primary0=clkconnect(f,3);prt0=clkconnect(f,4) 557 else 558 primary0=[] 559 end 560 561 if show_comment then mprintf("Processing blk " + string(blk) + " port "+... 562 + string(port) + "\n"),end 563 564 if primary0<>[] then // delete redundant links 565 [jj,k]=unique(primary0*(1+max(prt0))+prt0) 566 index=setdiff(1:size(primary0,1),k) 567 clkconnect(f(index),:)=[] // does not affect e(f)blks 568 569 primary=unique(primary0) 570 571 [balg,vec]=ini_ordo3(primary) 572 if balg then 573 disp(msprintf("%s: ini_ordo (3) failed", "c_pass2")); 574 messagebox(_("Algebraic loop."),"modal","error"), 575 ok=%f 576 return 577 end 578 579 pvec=vec(primary)+.5*typ_l(primary) // same order typ_l to the right 580 [mi,In]=gsort(-pvec) 581 primary=primary(In) 582 lp=find(typ_l(primary)) 583 lprimary=primary(lp) 584 585 bouclalg=%f 586 lp_backw=lp($:-1:1) 587 for i=lp_backw 588 for J=primary(i+1:$)' 589 if intersect(get_allchilds(primary(i)),get_allchilds(J))<>[] then 590 bouclalg=%t 591 break 592 end 593 end 594 if bouclalg then break,end 595 end 596 597 if show_comment&bouclalg then mprintf("found intersect \n"),end 598 599 if ~bouclalg then 600 [bouclalg,Vec,typ_l,clkconnect,connectmat,bllst,dep_t,dep_u,.. 601 dep_uptr,corinv,clkptr,cliptr,critev]=ini_ordo2(primary,.. 602 clkconnect,connectmat,bllst,typ_l,dep_t,dep_u,dep_uptr,.. 603 corinv,clkptr,cliptr,critev) 604 if bouclalg then 605 if show_comment then mprintf("found non convergence\n"),pause,end 606 i=lp(1) // first typ_l 607 if i==[] then 608 disp(msprintf("%s: ini_ordo (2) failed", "c_pass2")); 609 messagebox(_("Algebraic loop."),"modal","error") 610 ok=%f 611 return 612 end 613 J=primary(i+1:$) 614 end 615 end 616 617 if bouclalg then 618 modif=%f 619 bl=primary(i) 620 621 nout=clkptr(bl+1)-clkptr(bl) 622 //duplicate bl if it receives other links 623 f=find(clkconnect(:,1)==blk&clkconnect(:,2)==port&clkconnect(:,3)==bl) 624 h=find(clkconnect(:,3)==bl) // this is always one 625 if size(f,2)<>size(h,2) then 626 nblock=nblock+1 627 clkconnect(f,3)=nblock 628 if show_comment then 629 mprintf("duplicating pivot"+string(bl)+" to obtain "+string(nblock) + "\n"), 630 end 631 [typ_l,clkconnect,connectmat,vbllst,dep_t,dep_u,dep_uptr,.. 632 corinv,clkptr,cliptr,critev]=duplicate_block(bl,typ_l,clkconnect,.. 633 connectmat,vbllst,dep_t,dep_u,dep_uptr,corinv,clkptr,cliptr,critev) 634 vec(nblock)=vec(bl) 635 //update pointer 636 blks_bl=blks(blksptr(bl):blksptr(bl+1)-1) 637 blks=[blks;blks_bl] 638 blksptr($+1)=blksptr($)+size(blks_bl,"*") 639 // 640 bls=[bl,nblock,fblks(fblksptr(bl):fblksptr(bl+1)-1)'] 641 [eblks,eblksptr]=.. 642 update_event_depend_on(eblks,eblksptr,clkconnect,cliptr,bls) 643 bl=nblock // use new block as pivot 644 lprimary(i)=bl 645 end 646 647 for bli=J(:)' 648 modif=%t 649 f=find(clkconnect(:,1)==blk&clkconnect(:,2)==port&clkconnect(:,3)==bli) 650 clkconnect(f,1)=bl 651 clkconnect(f,2)=1 652 xx= clkconnect(f,:) 653 for jj=2:nout 654 if show_comment then 655 mprintf("No block duplication but link between "+string(blk)+.. 656 " and "+string(bli)+" replaced with links from "+.. 657 string(bl)+" to "+string(bli) + "\n"), 658 end 659 xx(:,2)=jj; 660 clkconnect=[clkconnect;xx] 661 end 662 end 663 664 [eblks,eblksptr]=update_event_depend_on(eblks,eblksptr,clkconnect,cliptr,J(:)') 665 bls=[blk,bl];bls(find(bls==0))=[];bls=bls(typ_l(bls)); //exclude non typ_l and 0 666 [fblks,fblksptr]=update_event_activates(fblks,fblksptr,clkconnect,clkptr,bls) 667 668 // can (must) be done outside the for loop 669 // [fblks2,fblksptr2]=event_activates(clkconnect,clkptr) 670 // [eblks2,eblksptr2]=event_depend_on(clkconnect,cliptr) 671 //but then it must be updated 672 // if norm(eblksptr-eblksptr2)>0 then mprintf('roro2');pause,end 673 // if norm(fblksptr-fblksptr2)>0 then mprintf('soso2');pause,end 674 // if norm(eblks-eblks2)>0 then mprintf('roro');pause,end 675 // if norm(fblks-fblks2)>0 then mprintf('soso');pause,end 676 677 678 if ~modif then messagebox(_("Algebraic loop."),"modal","error"),ok=%f,return,end 679 else 680 primary0=primary0(k); 681 prt0=prt0(k) 682 [primary0,prt0]=aggregate(primary0,prt0) 683 [mi,In]=gsort(-Vec(primary0)) 684 if blk<>0 then 685 lordclk(clkptr(blk)+port-1)=[primary0(In),prt0(In)] 686 687 if show_comment then 688 mprintf("for blk port "+string(blk)+" "+string(port)+.. 689 " ordclk is :\n"), disp(lordclk(clkptr(blk)+port-1)), 690 end 691 else 692 cord=[primary0(In),prt0(In)] 693 end 694 695 todo(1,:)=[] 696 L=[]; 697 for Bi=lprimary' 698 C=[1:clkptr(Bi+1)-clkptr(Bi)]' 699 L=[L;Bi*ones(C),C] 700 end 701 todo=merge_mat(todo,L) 702 end 703 else 704 if blk<>0 then 705 J=clkptr(blk)+port-1 706 lordclk(J)=[] 707 if show_comment then 708 mprintf("for blk port "+string(blk)+" "+string(port)+.. 709 " ordclk is"), mprintf(lordclk(J) + "\n"), 710 end 711 else 712 cord=[] 713 end 714 715 todo(1,:)=[] 716 end 717 else 718 todo(1,:)=[] 719 end 720 end 721 end 722 723 for J=1:clkptr($)-1 724 ordclk=[ordclk;lordclk(J)] 725 ordptr=[ordptr;ordptr($)+size(lordclk(J),1)] 726 end 727 728 bllst=list(bllst(vbllst)) 729 730endfunction 731 732function [primary0,port0]=aggregate(primary0,port0) 733 primary=discardprimary([primary0,port0]) // must rewrite 734 primary0=primary(:,1);port0=primary(:,2) 735endfunction 736 737 738function [parents]=get_parents2(parents,blk,port) 739 k=size(parents,1)+1; 740 f=find(clkconnect(:,3)==blk) 741 n_f=size(f,2) 742 if n_f>0 then 743 for i=1:n_f 744 if clkconnect(f(i),4)==port then 745 clki1=clkconnect(f(i),1) 746 clki2=clkconnect(f(i),2) 747 g=find(clki1==parents(:,1)) 748 if g==[] | (g~=[] & parents(g,2)~=clki2) then 749 parents(k,1)=clki1 750 parents(k,2)=clki2 751 k=k+1 752 end 753 end 754 end 755 end 756endfunction 757 758//suppression des liens inutiles 759function [clkconnect,amaj]=find_del_inutile(clkconnect,vec_plus,typ_l) 760 amaj=[] 761 for i=1:size(vec_plus,1) 762 blk=vec_plus(i,1) 763 port=vec_plus(i,2) 764 parents=get_parents2([],blk,port) 765 j=1 766 done=%f 767 n_p=size(parents,1) 768 while j<=n_p & ~done 769 par1=parents(j,1) 770 if par1~=0 & typ_l(par1) then 771 n_out=clkptr(par1+1)-clkptr(par1) 772 f=find(par1==parents(:,1)) 773 if size(f,2)==n_out then 774 if show_comment then 775 mprintf("find_del_inutile:") 776 mprintf("link between blocks "+string(par1)+" and "+string(blk)+.. 777 " are deleted\n") 778 pause 779 end 780 [clkconnect]=del_inutile(clkconnect,par1,n_out,blk,port) 781 done=%t 782 amaj=[amaj;par1;blk] 783 end 784 end 785 j=j+1 786 end 787 end 788endfunction 789 790function [clkconnect]=del_inutile(clkconnect,blk0,n_out,blk,port) 791 f=find(clkconnect(:,1)==blk0) 792 del=[] 793 for i=1:size(f,2) 794 if clkconnect(f(i),3)==blk & clkconnect(f(i),4)==port then 795 del=[del;f(i)] 796 end 797 end 798 clkconnect(del,:)=[] 799 p=get_parents([],blk0) 800 n_p=size(p,1) 801 for i=1:n_p 802 clkconnect($+1,:)=[p(i,1),p(i,2),blk,port] 803 end 804endfunction 805 806 807function blk0=get_father(blk1,vectmp) 808 gg=find(clkconnect(:,3)==blk1) // parents of blk1 809 del=find(clkconnect(gg,1)==0) 810 gg(del)=[] // remove continuous-time source 811 // it is inactive 812 hh=find(vectmp(clkconnect(gg,1))>0) // keep active ones 813 blk0=unique(clkconnect(gg(hh),1)) // active parent(s) 814 blk0=blk0(typ_l(blk0)) // can be a vector 815endfunction 816 817function [bouclalg,vec,typ_l,clkconnect,connectmat,bllst,dep_t,dep_u,.. 818 dep_uptr,corinv,clkptr,cliptr,critev]=ini_ordo2(primary,.. 819 clkconnect,connectmat,bllst,typ_l,dep_t,dep_u,dep_uptr,corinv,clkptr,.. 820 cliptr,critev) 821 822 n_p=size(primary,1) 823 824 nblock=size(typ_l,1); 825 //initialisation de vec 826 //on initialise vec � -1 827 vec=-ones(nblock,1) 828 vec(primary(:,1))=1 829 830 bouclalg=%f 831 fromfixe=%f 832 oldvec2=[] 833 counter2=0 834 835 [wprim,wprimptr,g0prim,g0primptr,gprim,gprimptr]=prim_calc(primary) 836 837 while ~fromfixe 838 vec=update_vec3(vec,wprim,wprimptr,g0prim,g0primptr,gprim,gprimptr) 839 // 840 if and(vec==oldvec2) then 841 fromfixe=%t 842 else 843 oldvec2=vec 844 end 845 counter2=counter2+1 846 if (counter2>n_p+1) then 847 bouclalg=%t 848 // mprintf('Algebraic Loop detection.') 849 break 850 end 851 end 852endfunction 853 854function [bouclalg,vec]=ini_ordo3(primary) 855 856 n_p=size(primary,1) 857 858 nblock=size(typ_l,1); 859 //initialisation de vec 860 //on initialise vec � -1 861 vec=-ones(nblock,1) 862 vec(primary(:,1))=0 863 864 bouclalg=%f 865 fromfixe=%f 866 oldvec2=[] 867 counter2=0 868 869 [wprim,wprimptr,g0prim,g0primptr,gprim,gprimptr]=prim_calc(primary) 870 871 while ~fromfixe 872 vec=update_vec4(vec,wprim,wprimptr,g0prim,g0primptr,gprim,gprimptr) 873 874 if and(vec==oldvec2) then 875 fromfixe=%t 876 else 877 oldvec2=vec 878 end 879 counter2=counter2+1 880 if (counter2>n_p+1) then 881 bouclalg=%t 882 // mprintf('Algebraic Loop detection.') 883 break 884 end 885 end 886endfunction 887 888 889function vec=update_vec3(vec,wprim,wprimptr,g0prim,g0primptr,gprim,gprimptr) 890 for i=1:size(wprimptr,"*")-1 891 w=wprim(wprimptr(i):wprimptr(i+1)-1) 892 g0=g0prim(g0primptr(i):g0primptr(i+1)-1) 893 g=gprim(gprimptr(i):gprimptr(i+1)-1) 894 // detecting algebraic loops within a single cluster 895 //mprintf([px,py,size(blks,'*')]) 896 vec(w)=max(vec(w)) 897 if (g0 ~= []) then 898 vec(w(1))=max(vec(w(1)),max(vec(g0))+1) 899 end 900 //g=g(find(vec(g)>-1)) //not optimal test max(vec(g)) 901 if g~=[] then 902 vec(w)=vec(w)-1 903 vec(w)=max(vec(w),max(vec(g)))+1 904 end 905 end 906endfunction 907 908function vec=update_vec4(vec,wprim,wprimptr,g0prim,g0primptr,gprim,gprimptr) 909 for i=1:size(wprimptr,"*")-1 910 w=wprim(wprimptr(i):wprimptr(i+1)-1) 911 g0=g0prim(g0primptr(i):g0primptr(i+1)-1) 912 if g0<>[] then vec(w(1))=max(vec(w(1)),max(vec(g0))), end 913 vec(w(2:$))=vec(w(1))+1 914 end 915endfunction 916 917function [wprim,wprimptr,g0prim,g0primptr,gprim,gprimptr]=prim_calc(primary) 918 wprim=[];wprimptr=1 919 gprim=[];gprimptr=1 920 g0prim=[];g0primptr=1 921 922 923 for i=1:size(primary,"*") 924 w0=primary(i) 925 if typ_l(w0) then 926 w=get_allchilds(w0,fblks,fblksptr,typ_l) 927 j=find(w==w0) 928 w([1,j])=w([j,1]) // put w0 on top 929 else 930 w=w0; 931 end 932 wprim=[wprim;w(:)] 933 wprimptr($+1)=wprimptr($)+size(w,"*") 934 935 px=blksptr(w(1));py=blksptr(w(1)+1)-1 936 //mprintf([px,py,size(blks,'*')]) 937 g0prim=[g0prim;blks(px:py)] 938 g0primptr($+1)=g0primptr($)+size(px:py,2) 939 940 g=[] 941 for i1=2:size(w,"*") // 1 is done already 942 px=blksptr(w(i1));py=blksptr(w(i1)+1)-1 943 g=[g;blks(px:py)] 944 end 945 gprim=[gprim;g] 946 gprimptr($+1)=gprimptr($)+size(g,"*") 947 end 948endfunction 949 950function primary=discardprimary(primary) 951 // discard 952 mma=max(primary(:,2))+1 953 con=mma*primary(:,1)+primary(:,2) 954 [junk,ind]=gsort(-con);con=-junk 955 primary=primary(ind,:) 956 // discard duplicate calls to the same block port 957 if size(con,"*")>=2 then 958 primary(find(con(2:$)-con(1:$-1)==0),:)=[] 959 end 960 // group calls to different ports of the same block. 961 primary=[primary(:,1),2^(primary(:,2)-ones(primary(:,2)))] 962 primary=int(primary) 963 con=primary(:,1) 964 clkconnectjj=[] 965 if size(con,"*")>=2 then 966 iini=[find(con(2:$)-con(1:$-1)<>0),size(primary,1)] 967 else 968 iini=1 969 end 970 for ii=iini 971 clkconnectjj=[clkconnectjj;[primary(ii,1),.. 972 mysum(primary(find(primary(:,1)==primary(ii,1)),2))]] 973 end 974 primary=clkconnectjj 975endfunction 976 977 978 979 980function [ordclk,iord,oord,zord,typ_z,ok]=scheduler(inpptr,outptr,clkptr,execlk_cons,.. 981 outoin,outoinptr,evoutoin,evoutoinptr,typ_z,typ_x,typ_l,bexe,boptr,.. 982 blnk,blptr,ordclk,ordptr,cord,dep_t,dep_u,dep_uptr); 983 984 nblk=size(typ_x,1) 985 //compute iord 986 if execlk_cons<>[] then 987 vec=-ones(1,nblk) 988 no_tu_dep=execlk_cons(:,1) 989 wec=zeros(1,nblk) 990 wec(no_tu_dep')=execlk_cons(:,2)' 991 vec(no_tu_dep)=0*no_tu_dep' 992 [r,ok]=newc_tree2(vec,outoin,outoinptr,dep_u,dep_uptr) 993 994 iord=[r,wec(r)'] 995 else 996 iord=[] 997 end 998 // 999 if ~ok then 1000 disp(msprintf("%s: scheduling failed", "c_pass2")); 1001 messagebox(_("Algebraic loop."),"modal","error"); 1002 iord=[],oord=[],zord=[],critev=[] 1003 return, 1004 end 1005 1006 n=size(cord,1) 1007 vec=-ones(1,nblk); 1008 vec(cord(:,1))=0; 1009 typp=zeros(typ_l);typp(typ_l)=1 1010 1011 ext_cord1=cord; 1012 j=1 1013 while %t 1014 ii=ext_cord1(j,1) 1015 if typ_l(ii) 1016 for i=[clkptr(ii):clkptr(ii+1)-1] 1017 ext_cord1=[ext_cord1;ordclk([ordptr(i):ordptr(i+1)-1],:)]; 1018 end 1019 end 1020 j=j+1 1021 if j>size(ext_cord1,1) then break;end 1022 end 1023 // code to replace faulty unique which reorders 1024 yy=ext_cord1(:,1)' 1025 [xx,kkn]=unique(yy); 1026 ext_cord=yy(-gsort(-kkn)) 1027 //ext_cord=unique(ext_cord1(:,1)'); 1028 //for i=ext_cord 1029 // if typ_l(i) then typ_z(i)=clkptr(i+1)-clkptr(i)-1;end 1030 //end // adding zero crossing surfaces to cont. time synchros 1031 1032 //a supprimer 1033 1034 [ext_cord_old,ok]=newc_tree3(vec,dep_u,dep_uptr,typp); 1035 1036 if or(gsort(ext_cord_old)<>gsort(ext_cord)) then pause,end 1037 // 1038 //pour mettre a zero les typ_z qui ne sont pas dans ext_cord 1039 //noter que typ_z contient les tailles des nzcross (peut etre >1) 1040 typ_z(ext_cord)=-typ_z(ext_cord) 1041 typ_z=-min(typ_z,0) 1042 1043 if ~ok then mprintf("serious bug, report.");pause;end 1044 // ext_cord=ext_cord(n+1:$); 1045 1046 typ_z_save=typ_z 1047 1048 fin=0 1049 while ~fin 1050 fin=1 1051 for i=ext_cord($:-1:1) 1052 for ii=[outoin(outoinptr(i):outoinptr(i+1)-1,1)',.. 1053 evoutoin(evoutoinptr(i):evoutoinptr(i+1)-1,1)'] 1054 //ii est un block affecte par changement de sortie du 1055 //i-eme block de oord 1056 if typ_z(ii) then 1057 if typ_z(i)==0 then typ_z(i)=1;fin=0;end 1058 end 1059 if typ_x(ii) then 1060 if ~typ_x(i) then typ_x(i)=%t;fin=0;end 1061 end 1062 if typ_z(i)&typ_x(i) then break,end 1063 end 1064 end 1065 end 1066 //supprimer les blocks a supprimer 1067 ind=find(typ_z(cord(:,1))); 1068 zord=cord(ind,:) 1069 ind=find(typ_x(cord(:,1))); 1070 oord=cord(ind,:) 1071 typ_z=typ_z_save 1072 //critev: vecteur indiquant si evenement est important pour tcrit 1073 //Donc les blocks indiques sont des blocks susceptibles de produire 1074 //des discontinuites quand l'evenement se produit 1075 if isempty(ext_cord1) then 1076 if isempty(ordclk) then 1077 maX=1; 1078 else 1079 maX=max(ordclk(:,2))+1; 1080 end 1081 cordX = []; 1082 else 1083 maX=max([ext_cord1(:,2);ordclk(:,2)])+1; 1084 cordX=ext_cord1(:,1)*maX+ext_cord1(:,2); 1085 end 1086 1087 // 1: important; 0:non 1088 //n=clkptr(nblk+1)-1 //nb d'evenement 1089 n=size(ordptr,"*")-1 //nb d'evenement 1090 1091 //a priori tous les evenements sont non-importants 1092 //critev=zeros(n,1) 1093 for i=1:n 1094 for hh=ordptr(i):ordptr(i+1)-1 1095 jj= ordclk(hh,1) //block excite par evenement i 1096 //Following line is not correct because of ever active synchros 1097 if or(jj*maX+ordclk(hh,2)==cordX) then 1098 ordclk(hh,2)=-ordclk(hh,2) 1099 end 1100 end 1101 end 1102endfunction 1103 1104function [ord,ok]=tree3(vec,dep_ut,typ_l) 1105 //compute blocks execution tree 1106 ok=%t 1107 nb=size(vec,"*") 1108 for j=1:nb+2 1109 fini=%t 1110 for i=1:nb 1111 if vec(i)==j-1&typ_l(i)<>-1 then 1112 if j==nb+2 then 1113 disp(msprintf("%s: tree (3) failed", "c_pass2")); 1114 messagebox(_("Algebraic loop."),"modal","error");ok=%f;ord=[];return; 1115 end 1116 if typ_l(i)==1 then 1117 fini=%f; 1118 kk=bexe(boptr(i):boptr(i+1)-1)'; 1119 else 1120 kk=[]; 1121 for ii=blnk(blptr(i):blptr(i+1)-1)' 1122 if vec(ii)>-1 & (dep_ut(ii,1) | (typ_l(ii)==1)) then 1123 fini=%f; 1124 kk=[kk ii]; 1125 end 1126 end 1127 end 1128 vec(kk)=j*ones(kk) ; //mprintf(vec) 1129 end 1130 end 1131 if fini then break;end 1132 end 1133 [k,ord]=gsort(-vec); 1134 ord(find(k==1))=[]; 1135endfunction 1136 1137function [clkconnectj_cons]=discard(clkptr,cliptr,clkconnect,exe_cons) 1138 1139 if exe_cons<>[] then 1140 clkconnectj=exe_cons 1141 mma=max(clkconnectj(:,2))+1 1142 con=mma*(clkconnectj(:,1))+clkconnectj(:,2) 1143 [junk,ind]=gsort(-con);con=-junk 1144 clkconnectj=clkconnectj(ind,:) 1145 // discard duplicate calls to the same block port 1146 if size(con,"*")>=2 then 1147 clkconnectj(find(con(2:$)-con(1:$-1)==0),:)=[] 1148 end 1149 // group calls to different ports of the same block. 1150 clkconnectj=[clkconnectj(:,1),2^(clkconnectj(:,2)-ones(clkconnectj(:,2)))] 1151 clkconnectj=int(clkconnectj) 1152 con=clkconnectj(:,1) 1153 clkconnectj_cons=[] 1154 if size(con,"*")>=2 then 1155 iini=[find(con(2:$)-con(1:$-1)<>0),size(clkconnectj,1)] 1156 else 1157 iini=1 1158 end 1159 for ii=iini 1160 clkconnectj_cons=[clkconnectj_cons;[clkconnectj(ii,1),.. 1161 mysum(clkconnectj(find(clkconnectj(:,1)==clkconnectj(ii,1)),2))]] 1162 end 1163 else 1164 clkconnectj_cons=[] 1165 end 1166endfunction 1167 1168function a=mysum(b) 1169 if b<>[] then a=sum(b), else a=[], end 1170endfunction 1171 1172function [lnksz,lnktyp,inplnk,outlnk,clkptr,cliptr,inpptr,outptr,xptr,zptr,.. 1173 ozptr,typ_mod,rpptr,ipptr,opptr,xc0,xcd0,xd0,oxd0,rpar,.. 1174 ipar,opar,typ_z,typ_x,typ_m,funs,funtyp,initexe,labels,uids,.. 1175 bexe,boptr,blnk,blptr,ok]=extract_info(bllst,connectmat,clkconnect,typ_l) 1176 1177 ok=%t 1178 nbl=length(bllst) 1179 clkptr=zeros(nbl+1,1);clkptr(1)=1 1180 cliptr=clkptr;inpptr=cliptr;outptr=inpptr; 1181 xptr=1;zptr=1;ozptr=1; 1182 rpptr=clkptr;ipptr=clkptr;opptr=clkptr; 1183 // 1184 xc0=[];xcd0=[];xd0=[]; 1185 oxd0=list() 1186 rpar=[];ipar=[]; 1187 opar=list(); 1188 1189 fff=ones(nbl,1)==1 1190 typ_z=zeros(nbl,1);typ_x=fff;typ_m=fff;typ_mod=zeros(nbl,1); 1191 1192 initexe=[]; 1193 funs=list(); 1194 funtyp=zeros(typ_z) 1195 labels=[] 1196 uids=[] 1197 [ok,bllst]=adjust_inout(bllst,connectmat) 1198 if ok then 1199 [ok,bllst]=adjust_typ(bllst,connectmat) 1200 end 1201 1202 // placed here to make sure nzcross and nmode correctly updated 1203 if ~ok then 1204 lnksz=[],lnktyp=[],inplnk=[],outlnk=[],clkptr=[],cliptr=[],inpptr=[],outptr=[],.. 1205 xptr=[],zptr=[],ozptr=[],rpptr=[],ipptr=[],opptr=[],xc0=[],.. 1206 xcd0=[],xd0=[],oxd0=list(),rpar=[],ipar=[],opar=list(),.. 1207 typ_z=[],typ_x=[],typ_m=[],funs=[],funtyp=[],initexe=[],.. 1208 labels=[],uids=[],bexe=[],boptr=[],blnk=[],blptr=[] 1209 return; 1210 end 1211 for i=1:nbl 1212 ll=bllst(i) 1213 1214 if type(ll.sim)==15 then 1215 funs(i)=ll.sim(1) 1216 funtyp(i,1)=ll.sim(2) 1217 else 1218 funs(i)=ll.sim; 1219 funtyp(i,1)=0; 1220 end 1221 if funtyp(i,1)>999&funtyp(i,1)<10000 then 1222 if ~c_link(funs(i)) then 1223 msg = _("A C or Fortran block is used but not linked.\nYou can save your compiled diagram and load it.\nThis will automatically link the C or Fortran function.") 1224 messagebox(msprintf(msg), "modal", "error") 1225 end 1226 end 1227 inpnum=ll.in;outnum=ll.out;cinpnum=ll.evtin;coutnum=ll.evtout; 1228 // 1229 inpptr(i+1)=inpptr(i)+size(inpnum,"*") 1230 outptr(i+1)=outptr(i)+size(outnum,"*") 1231 cliptr(i+1)=cliptr(i)+size(cinpnum,"*") 1232 clkptr(i+1)=clkptr(i)+size(coutnum,"*") 1233 // 1234 X0=ll.state(:) 1235 if funtyp(i,1)<10000 then 1236 xcd0=[xcd0;0*X0] 1237 xc0=[xc0;X0] 1238 xptr(i+1)=xptr(i)+size(ll.state,"*") 1239 else 1240 xcd0=[xcd0;X0($/2+1:$)] 1241 xc0=[xc0;X0(1:$/2)] 1242 xptr(i+1)=xptr(i)+size(ll.state,"*")/2 1243 end 1244 1245 //dstate 1246 if (funtyp(i,1)==3 | funtyp(i,1)==5 | funtyp(i,1)==10005) then //sciblocks 1247 if ll.dstate==[] then xd0k=[]; else xd0k=var2vec(ll.dstate);end 1248 else 1249 xd0k=ll.dstate(:) 1250 end 1251 xd0=[xd0;xd0k] 1252 zptr(i+1)=zptr(i)+size(xd0k,"*") 1253 1254 //odstate 1255 if type(ll.odstate)==15 then 1256 if ((funtyp(i,1)==5) | (funtyp(i,1)==10005)) then //sciblocks : don't extract 1257 if size(ll.odstate)>0 then 1258 oxd0($+1)=ll.odstate 1259 ozptr(i+1)=ozptr(i)+1; 1260 else 1261 ozptr(i+1)=ozptr(i); 1262 end 1263 elseif ((funtyp(i,1)==4) | (funtyp(i,1)==10004) |... 1264 (funtyp(i,1)==2004) | (funtyp(i,1)==12004)) //C blocks : extract 1265 ozsz = size(ll.odstate); 1266 if ozsz>0 then 1267 for j=1:ozsz, oxd0($+1)=ll.odstate(j), end; 1268 ozptr(i+1)=ozptr(i)+ozsz; 1269 else 1270 ozptr(i+1)=ozptr(i); 1271 end 1272 else 1273 ozptr(i+1)=ozptr(i); 1274 end 1275 else 1276 //add an error message here please ! 1277 ozptr(i+1)=ozptr(i); 1278 end 1279 1280 //mod 1281 typ_mod(i)=ll.nmode; 1282 if typ_mod(i)<0 then 1283 messagebox(msprintf(_("Number of modes in block #%d cannot be determined."),i),"modal","error") 1284 ok=%f 1285 end 1286 1287 //real paramaters 1288 rpark=ll.rpar(:) 1289 rpar=[rpar;rpark] 1290 rpptr(i+1)=rpptr(i)+size(rpark,"*") 1291 1292 //integer parameters 1293 if type(ll.ipar)==1 then 1294 ipar=[ipar;ll.ipar(:)] 1295 ipptr(i+1)=ipptr(i)+size(ll.ipar,"*") 1296 else 1297 ipptr(i+1)=ipptr(i) 1298 end 1299 1300 //object parameters 1301 if type(ll.opar)==15 then 1302 if ((funtyp(i,1)==5) | (funtyp(i,1)==10005)) then //sciblocks : don't extract 1303 if size(ll.opar)>0 then 1304 opar($+1)=ll.opar 1305 opptr(i+1)=opptr(i)+1; 1306 else 1307 opptr(i+1)=opptr(i); 1308 end 1309 elseif ((funtyp(i,1)==4) | (funtyp(i,1)==10004) |... 1310 (funtyp(i,1)==2004) | (funtyp(i,1)==12004)) then //C blocks : extract 1311 oparsz = size(ll.opar); 1312 if oparsz>0 then 1313 for j=1:oparsz, opar($+1)=ll.opar(j), end; 1314 opptr(i+1)=opptr(i)+oparsz; 1315 else 1316 opptr(i+1)=opptr(i); 1317 end 1318 else 1319 opptr(i+1)=opptr(i); 1320 end 1321 else 1322 //add an error message here please ! 1323 opptr(i+1)=opptr(i); 1324 end 1325 1326 // typ_z(i)=ll.blocktype=='z' 1327 typ_z(i)=ll.nzcross 1328 if typ_z(i)<0 then 1329 messagebox(msprintf(_("Number of zero crossings in block #%d cannot be determined."),i),"modal","error") 1330 ok=%f 1331 end 1332 typ_x(i)=ll.state<>[]|ll.blocktype=="x" // some blocks like delay 1333 // need to be in oord even 1334 // without state 1335 1336 typ_m(i)=ll.blocktype=="m" 1337 // 1338 if ll.evtout<>[] then 1339 ll11=ll.firing 1340 prt=find(ll11>=zeros(ll11)) 1341 nprt=prod(size(prt)) 1342 initexe=[initexe;[i*ones(nprt,1),matrix(prt,nprt,1),matrix(ll11(prt),nprt,1)]]; 1343 end 1344 1345 if type(ll.label)==10 then 1346 labels=[labels;ll.label(1)] 1347 else 1348 labels=[labels;" "] 1349 end 1350 1351 if type(ll.uid)==10 then 1352 uids=[uids;ll.uid(1)] 1353 else 1354 uids=[uids;" "] 1355 end 1356 end 1357 1358 clkconnect=clkconnect(find(clkconnect(:,1)<>0),:); 1359 1360 if isempty(clkconnect) then 1361 con=-1; 1362 else 1363 con=clkptr(clkconnect(:,1))+clkconnect(:,2)-1; 1364 end 1365 [junk,ind]=gsort(-con);con=-junk; 1366 clkconnect=clkconnect(ind,:); 1367 // 1368 bclkconnect=clkconnect(:,[1 3]); 1369 boptr=1; 1370 bexe=[]; 1371 for i=1:nbl 1372 r=bclkconnect(find(bclkconnect(:,1)==i),2); 1373 bexe=[bexe;r]; 1374 boptr=[boptr;boptr($)+size(r,1)]; 1375 end 1376 // 1377 1378 blptr=1; 1379 blnk=[]; 1380 1381 for i=1:nbl 1382 r=connectmat(find(connectmat(:,1)==i),3:4); 1383 blnk=[blnk;r]; 1384 blptr=[blptr;blptr($)+size(r,1)]; 1385 end 1386 // 1387 1388 nlnk=size(connectmat,1) 1389 inplnk=zeros(inpptr($)-1,1);outlnk=zeros(outptr($)-1,1);ptlnk=1; 1390 lnksz=[];lnktyp=[]; 1391 for jj=1:nlnk 1392 ko=outlnk(outptr(connectmat(jj,1))+connectmat(jj,2)-1) 1393 ki=inplnk(inpptr(connectmat(jj,3))+connectmat(jj,4)-1) 1394 if ko<>0 & ki<>0 then 1395 if ko>ki then 1396 outlnk(outlnk>ko)=outlnk(outlnk>ko)-1 1397 outlnk(outlnk==ko)=ki 1398 inplnk(inplnk>ko)=inplnk(inplnk>ko)-1 1399 inplnk(inplnk==ko)=ki 1400 ptlnk=-1+ptlnk 1401 lnksz(ko,1)=[]; 1402 lnksz(ko,2)=[]; 1403 lnktyp(ko) =[]; 1404 elseif ki>ko 1405 outlnk(outlnk>ki)=outlnk(outlnk>ki)-1 1406 outlnk(outlnk==ki)=ko 1407 inplnk(inplnk>ki)=inplnk(inplnk>ki)-1 1408 inplnk(inplnk==ki)=ko 1409 ptlnk=-1+ptlnk 1410 lnksz(ki,1)=[]; 1411 lnksz(ki,2)=[]; 1412 lnktyp(ki) =[]; 1413 end 1414 elseif ko<>0 then 1415 inplnk(inpptr(connectmat(jj,3))+connectmat(jj,4)-1)=ko 1416 elseif ki<>0 then 1417 outlnk(outptr(connectmat(jj,1))+connectmat(jj,2)-1)=ki 1418 else 1419 outlnk(outptr(connectmat(jj,1))+connectmat(jj,2)-1)=ptlnk 1420 inplnk(inpptr(connectmat(jj,3))+connectmat(jj,4)-1)=ptlnk 1421 lnksz(ptlnk,1)=bllst(connectmat(jj,1)).out(connectmat(jj,2)); 1422 lnksz(ptlnk,2)=bllst(connectmat(jj,1)).out2(connectmat(jj,2)); 1423 lnktyp(ptlnk)=bllst(connectmat(jj,1)).outtyp(connectmat(jj,2)); 1424 ptlnk=1+ptlnk 1425 end 1426 end 1427 1428 //store unconnected outputs, if any, at the end of outtb 1429 unco=find(outlnk==0); 1430 for j=unco 1431 m=max(find(outptr<=j)) 1432 n=j-outptr(m)+1 1433 nm=bllst(m).out(n) 1434 if nm<1 then 1435 under_connection(corinv(m),n,nm,-1,0,0,1),ok=%f,return, 1436 end 1437 nm2=bllst(m).out2(n) 1438 if nm2<1 then 1439 under_connection(corinv(m),n,nm2,-1,0,0,1),ok=%f,return, 1440 end 1441 lnksz($+1,1)=bllst(m).out(n); 1442 lnksz($,2)=bllst(m).out2(n); 1443 lnktyp($+1)=bllst(m).outtyp(n); 1444 outlnk(j)=max(outlnk)+1 1445 end 1446 1447 //store unconnected inputs, if any, at the end of outtb 1448 unco=find(inplnk==0); 1449 for j=unco 1450 m=max(find(inpptr<=j)) 1451 n=j-inpptr(m)+1 1452 nm=bllst(m).in(n) 1453 if nm<1 then 1454 under_connection(corinv(m),n,nm,-2,0,0,1),ok=%f,return, 1455 end 1456 nm2=bllst(m).in2(n) 1457 if nm2<1 then 1458 under_connection(corinv(m),n,nm2,-2,0,0,1),ok=%f,return, 1459 end 1460 lnksz($+1,1)=bllst(m).in(n); 1461 lnksz($,2)=bllst(m).in2(n); 1462 lnktyp($+1)=bllst(m).intyp(n); 1463 inplnk(j)=max([inplnk;max(outlnk)])+1 1464 end 1465 1466endfunction 1467 1468function [outoin,outoinptr]=conn_mat(inpptr,outptr,inplnk,outlnk) 1469 outoin=[];outoinptr=1 1470 nblk=size(inpptr,1)-1 1471 for i=1:nblk 1472 k=outptr(i):outptr(i+1)-1 1473 ii=[] 1474 for j=outlnk(k)' 1475 ii=[ii,find(inplnk==j)] 1476 end 1477 outoini=[];jj=0 1478 for j=ii 1479 m=max(find(inpptr<=j)) 1480 n=j-inpptr(m)+1 1481 outoini=[outoini;[m,n]] 1482 jj=jj+1 1483 end 1484 outoinptr=[outoinptr;outoinptr($)+jj] 1485 outoin=[outoin;outoini] 1486 end 1487endfunction 1488 1489function [ord,ok]=tree2(vec,outoin,outoinptr,dep_ut) 1490 //compute blocks execution tree 1491 ok=%t; 1492 1493 nb=size(vec,"*"); 1494 for j=1:nb+2 1495 fini=%t 1496 for i=1:nb 1497 if vec(i)==j-1 then 1498 if j==nb+2 then 1499 disp(msprintf("%s: tree (2) failed", "c_pass2")); 1500 messagebox(_("Algebraic loop."),"modal","error");ok=%f;ord=[];return; 1501 end 1502 for k=outoinptr(i):outoinptr(i+1)-1 1503 ii=outoin(k,1); 1504 //indport=find(dep_u(dep_uptr(ii):dep_uptr(ii+1)-1)==1); 1505 //if (indport ~=[] &vec(ii)>-1) then 1506 if (dep_ut(ii) &vec(ii)>-1) then 1507 fini=%f; 1508 vec(ii)=j; 1509 end 1510 end 1511 end 1512 end 1513 if fini then break;end 1514 end 1515 1516 [k,ord]=gsort(-vec); 1517 ord(find(k==1))=[]; 1518 ord=ord(:) 1519endfunction 1520 1521 1522//adjust_inout : it resolves positive, negative and null size 1523// of in/out port dimensions of connected block. 1524// If it's not done in a first pass, the second 1525// pass try to resolve negative or null port 1526// dimensions by asking user to informed dimensions 1527// with underconnection function. 1528// It is a fixed point algorithm. 1529// 1530//in parameters : bllst : list of blocks 1531// 1532// connectmat : matrix of connection 1533// connectmat(lnk,1) : source block 1534// connectmat(lnk,2) : source port 1535// connectmat(lnk,3) : target block 1536// connectmat(lnk,4) : target port 1537// 1538//out parameters : ok : a boolean flag to known if adjust_inout have 1539// succeeded to resolve the in/out port size 1540// - ok = %t : all size have been resolved in bllst 1541// - ok = %f : problem in size adjustement 1542// 1543// bllst : modified list of blocks 1544// 1545//18/05/06, Alan : improvement in order to take into 1546// account two dimensional port size. 1547// 1548//28/12/06, Alan : type for source port and target port must 1549// be the same. 1550// 1551//29/12/06, Fady : type for source and target can be different 1552// in one condition that they are double and complex. 1553// the result on the link will be complex. 1554// 1555//04/01/07, Fady : Can test the case of negatives equals target's dimensions. 1556// 1557//19/01/07, Alan : - Return correct information for user in editor 1558// with preceding test of Fady in the first pass 1559// - Second pass reviewed : under_connection returns two dimensions now 1560// 1561//10/05/07, Alan : - if-then-else event-select case 1562 1563function [ok,bllst]=adjust_inout(bllst,connectmat) 1564 1565 //Adjust in2/out2, inttyp/outtyp 1566 //in accordance to in/out in bllst 1567 [ko,bllst]=adjust_in2out2(bllst); 1568 if ~ko then ok=%f,return, end //if adjust_in2out2 failed then exit 1569 //adjust_inout with flag ok=%f 1570 1571 nlnk=size(connectmat,1) //nlnk is the number of link 1572 1573 //loop on number of block (pass 1 and pass 2) 1574 for hhjj=1:length(bllst)+1 1575 //%%%%% pass 1 %%%%%// 1576 for hh=1:length(bllst)+1 //second loop on number of block 1577 ok=%t 1578 for jj=1:nlnk //loop on number of link 1579 1580 //intyp/outtyp are the type of the 1581 //target port and the source port of the observed link 1582 outtyp = bllst(connectmat(jj,1)).outtyp(connectmat(jj,2)) 1583 intyp = bllst(connectmat(jj,3)).intyp(connectmat(jj,4)) 1584 //nnin/nnout are the size (two dimensions) of the 1585 //target port and the source port of the observed link 1586 //before adjust 1587 nnout(1,1)=bllst(connectmat(jj,1)).out(connectmat(jj,2)) 1588 nnout(1,2)=bllst(connectmat(jj,1)).out2(connectmat(jj,2)) 1589 nnin(1,1)=bllst(connectmat(jj,3)).in(connectmat(jj,4)) 1590 nnin(1,2)=bllst(connectmat(jj,3)).in2(connectmat(jj,4)) 1591 1592 //This Part is done in adjust_typ 1593 1594 //check intyp/outtyp 1595 // if intyp<>outtyp then 1596 // if (intyp==1 & outtyp==2) then 1597 // bllst(connectmat(jj,3)).intyp(connectmat(jj,4))=2; 1598 // elseif (intyp==2 & outtyp==1) then 1599 // bllst(connectmat(jj,1)).outtyp(connectmat(jj,2))=2; 1600 // else 1601 // if bllst(connectmat(jj,3)).sim(2)<0 //if-then-else/eselect case 1602 // bllst(connectmat(jj,3)).intyp(connectmat(jj,4))=... 1603 // bllst(connectmat(jj,1)).outtyp(connectmat(jj,2)) 1604 // else 1605 // bad_connection(corinv(connectmat(jj,1)),connectmat(jj,2),.. 1606 // nnout,outtyp,.. 1607 // corinv(connectmat(jj,3)),connectmat(jj,4),.. 1608 // nnin,intyp,1) 1609 // ok=%f; 1610 // return 1611 // end 1612 // end 1613 // end 1614 1615 //loop on the two dimensions of source/target port 1616 for ndim=1:2 1617 //check test source/target sizes 1618 //in case of negatif equal target dimensions 1619 //nin/nout are the size (two dimensions) of the 1620 //target port and the source port of the observed link 1621 nout(1,1)=bllst(connectmat(jj,1)).out(connectmat(jj,2)) 1622 nout(1,2)=bllst(connectmat(jj,1)).out2(connectmat(jj,2)) 1623 nin(1,1)=bllst(connectmat(jj,3)).in(connectmat(jj,4)) 1624 nin(1,2)=bllst(connectmat(jj,3)).in2(connectmat(jj,4)) 1625 1626 //first case : dimension of source and 1627 // target ports are explicitly informed 1628 // informed with positive size 1629 if(nout(1,ndim)>0&nin(1,ndim)>0) then 1630 //if dimension of source and target port doesn't match 1631 //then call bad_connection, set flag ok to false and exit 1632 if nin(1,ndim)<>nout(1,ndim) then 1633 bad_connection(corinv(connectmat(jj,1)),connectmat(jj,2),.. 1634 nnout,outtyp,.. 1635 corinv(connectmat(jj,3)),connectmat(jj,4),.. 1636 nnin,intyp) 1637 ok=%f;return 1638 end 1639 1640 //second case : dimension of source port is 1641 // positive and dimension of 1642 // target port is negative 1643 elseif(nout(1,ndim)>0&nin(1,ndim)<0) then 1644 //find vector of input ports of target block with 1645 //first/second dimension equal to size nin(1,ndim) 1646 //and assign it to nout(1,ndim) 1647 ww=find(bllst(connectmat(jj,3)).in==nin(1,ndim)) 1648 bllst(connectmat(jj,3)).in(ww)=nout(1,ndim) 1649 ww=find(bllst(connectmat(jj,3)).in2==nin(1,ndim)) 1650 bllst(connectmat(jj,3)).in2(ww)=nout(1,ndim) 1651 1652 //find vector of output ports of target block with 1653 //first/second dimension equal to size nin(1,ndim) 1654 //and assign it to nout(1,ndim) 1655 ww=find(bllst(connectmat(jj,3)).out==nin(1,ndim)) 1656 bllst(connectmat(jj,3)).out(ww)=nout(1,ndim) 1657 ww=find(bllst(connectmat(jj,3)).out2==nin(1,ndim)) 1658 bllst(connectmat(jj,3)).out2(ww)=nout(1,ndim) 1659 1660 //find vector of output ports of target block with 1661 //ndim dimension equal to zero and sum the ndim 1662 //dimension of all input ports of target block 1663 //to be the new dimension of the ndim dimension 1664 //of the output ports of the target block 1665 if ndim==1 then 1666 ww=find(bllst(connectmat(jj,3)).out==0) 1667 if (ww<>[]&min(bllst(connectmat(jj,3)).in(:))>0) then 1668 bllst(connectmat(jj,3)).out(ww)=sum(bllst(connectmat(jj,3)).in(:)) 1669 end 1670 elseif ndim==2 then 1671 ww=find(bllst(connectmat(jj,3)).out2==0) 1672 if (ww<>[]&min(bllst(connectmat(jj,3)).in2(:))>0) then 1673 bllst(connectmat(jj,3)).out2(ww)=sum(bllst(connectmat(jj,3)).in2(:)) 1674 end 1675 end 1676 1677 //if nzcross of the target block match with 1678 //the negative dimension nin(1,ndim) then 1679 //adjust it to nout(1,ndim) 1680 if bllst(connectmat(jj,3)).nzcross==nin(1,ndim) then 1681 bllst(connectmat(jj,3)).nzcross=nout(1,ndim) 1682 end 1683 //if nmode of the target block match with 1684 //the negative dimension nin(1,ndim) then 1685 //adjust it to nout(1,ndim) 1686 if bllst(connectmat(jj,3)).nmode==nin(1,ndim) then 1687 bllst(connectmat(jj,3)).nmode=nout(1,ndim) 1688 end 1689 1690 //third case : dimension of source port is 1691 // negative and dimension of 1692 // target port is positive 1693 elseif(nout(1,ndim)<0&nin(1,ndim)>0) then 1694 //find vector of output ports of source block with 1695 //first/second dimension equal to size nout(1,ndim) 1696 //and assign it to nin(1,ndim) 1697 ww=find(bllst(connectmat(jj,1)).out==nout(1,ndim)) 1698 bllst(connectmat(jj,1)).out(ww)=nin(1,ndim) 1699 ww=find(bllst(connectmat(jj,1)).out2==nout(1,ndim)) 1700 bllst(connectmat(jj,1)).out2(ww)=nin(1,ndim) 1701 1702 //find vector of input ports of source block with 1703 //first/second dimension equal to size nout(1,ndim) 1704 //and assign it to nin(1,ndim) 1705 ww=find(bllst(connectmat(jj,1)).in==nout(1,ndim)) 1706 bllst(connectmat(jj,1)).in(ww)=nin(1,ndim) 1707 ww=find(bllst(connectmat(jj,1)).in2==nout(1,ndim)) 1708 bllst(connectmat(jj,1)).in2(ww)=nin(1,ndim) 1709 1710 //find vector of input ports of source block with 1711 //ndim dimension equal to zero and sum the ndim 1712 //dimension of all output ports of source block 1713 //to be the new dimension of the ndim dimension 1714 //of the input ports of the source block 1715 if ndim==1 then 1716 ww=find(bllst(connectmat(jj,1)).in==0) 1717 if (ww<>[]&min(bllst(connectmat(jj,1)).out(:))>0) then 1718 bllst(connectmat(jj,1)).in(ww)=sum(bllst(connectmat(jj,1)).out(:)) 1719 end 1720 elseif ndim==2 then 1721 ww=find(bllst(connectmat(jj,1)).in2==0) 1722 if (ww<>[]&min(bllst(connectmat(jj,1)).out2(:))>0) then 1723 bllst(connectmat(jj,1)).in2(ww)=sum(bllst(connectmat(jj,1)).out2(:)) 1724 end 1725 end 1726 1727 //if nzcross of the source block match with 1728 //the negative dimension nout(1,ndim) then 1729 //adjust it to nin(1,ndim) 1730 if bllst(connectmat(jj,1)).nzcross==nout(1,ndim) then 1731 bllst(connectmat(jj,1)).nzcross=nin(1,ndim) 1732 end 1733 //if nmode of the source block match with 1734 //the negative dimension nout(1,ndim) then 1735 //adjust it to nin(1,ndim) 1736 if bllst(connectmat(jj,1)).nmode==nout(1,ndim) then 1737 bllst(connectmat(jj,1)).nmode=nin(1,ndim) 1738 end 1739 1740 //fourth case : a dimension of source port is 1741 // null 1742 elseif(nout(1,ndim)==0) then 1743 //set ww to be the vector of size of the ndim 1744 //dimension of input port of the source block 1745 if ndim==1 then 1746 ww=bllst(connectmat(jj,1)).in(:) 1747 elseif ndim==2 then 1748 ww=bllst(connectmat(jj,1)).in2(:) 1749 end 1750 1751 //test if all size of the ndim dimension of input 1752 //port of the source block is positive 1753 if min(ww)>0 then 1754 //test if the dimension of the target port 1755 //is positive 1756 if nin(1,ndim)>0 then 1757 1758 //if the sum of the size of the ndim dimension of the input 1759 //port of the source block is equal to the size of the ndim dimension 1760 //of the target port, then the size of the ndim dimension of the source 1761 //port is equal to nin(1,ndim) 1762 if sum(ww)==nin(1,ndim) then 1763 if ndim==1 then 1764 bllst(connectmat(jj,1)).out(connectmat(jj,2))=nin(1,ndim) 1765 elseif ndim==2 then 1766 bllst(connectmat(jj,1)).out2(connectmat(jj,2))=nin(1,ndim) 1767 end 1768 //else call bad_connection, set flag ok to false and exit 1769 else 1770 bad_connection(corinv(connectmat(jj,1)),0,0,1,-1,0,0,1) 1771 ok=%f;return 1772 end 1773 1774 //if the ndim dimension of the target port is negative 1775 //then the size of the ndim dimension of the source port 1776 //is equal to the sum of the size of the ndim dimension 1777 //of input ports of source block, and flag ok is set to false 1778 else 1779 if ndim==1 then 1780 bllst(connectmat(jj,1)).out(connectmat(jj,2))=sum(ww) 1781 elseif ndim==2 then 1782 bllst(connectmat(jj,1)).out2(connectmat(jj,2))=sum(ww) 1783 end 1784 ok=%f 1785 end 1786 1787 else 1788 //set nww to be the vector of all negative size of input ports 1789 //of the source block 1790 nww=ww(find(ww<0)) 1791 1792 //if all negative size have same size and if size of the 1793 //ndim dimension of the target port is positive then assign 1794 //size of the ndim dimension of the source port to nin(1,ndim) 1795 if norm(nww-nww(1),1)==0 & nin(1,ndim)>0 then 1796 if ndim==1 then 1797 bllst(connectmat(jj,1)).out(connectmat(jj,2))=nin(1,ndim) 1798 elseif ndim==2 then 1799 bllst(connectmat(jj,1)).out2(connectmat(jj,2))=nin(1,ndim) 1800 end 1801 1802 //compute a size to be the difference between the size 1803 //of the ndim dimension of the target block and sum of positive 1804 //size of input ports of the source block divided by the number 1805 //of input ports of source block with same negative size 1806 k=(nin(1,ndim)-sum(ww(find(ww>0))))/size(nww,"*") 1807 1808 //if this size is a positive integer then assign it 1809 //to the size of the ndim dimension of input ports of the 1810 //source block which have negative size 1811 if k==int(k)&k>0 then 1812 if ndim==1 then 1813 bllst(connectmat(jj,1)).in(find(ww<0))=k 1814 elseif ndim==2 then 1815 bllst(connectmat(jj,1)).in2(find(ww<0))=k 1816 end 1817 //else call bad_connection, set flag ok to false and exit 1818 else 1819 bad_connection(corinv(connectmat(jj,1)),0,0,1,-1,0,0,1) 1820 ok=%f;return 1821 end 1822 1823 //set flag ok to false 1824 else 1825 ok=%f 1826 end 1827 1828 end 1829 1830 //fifth case : a dimension of target port is 1831 // null 1832 elseif(nin(1,ndim)==0) then 1833 //set ww to be the vector of size of the ndim 1834 //dimension of output port of the target block 1835 if ndim==1 then 1836 ww=bllst(connectmat(jj,3)).out(:) 1837 elseif ndim==2 then 1838 ww=bllst(connectmat(jj,3)).out2(:) 1839 end 1840 1841 //test if all size of the ndim dimension of output 1842 //port of the target block is positive 1843 if min(ww)>0 then 1844 //test if the dimension of the source port 1845 //is positive 1846 if nout(1,ndim)>0 then 1847 1848 //if the sum of the size of the ndim dimension of the output 1849 //port of the target block is equal to the size of the ndim dimension 1850 //of the source port, then the size of the ndim dimension of the target 1851 //port is equal to nout(1,ndim) 1852 if sum(ww)==nout(1,ndim) then 1853 if ndim==1 then 1854 bllst(connectmat(jj,3)).in(connectmat(jj,4))=nout(1,ndim) 1855 elseif ndim==2 then 1856 bllst(connectmat(jj,3)).in2(connectmat(jj,4))=nout(1,ndim) 1857 end 1858 //else call bad_connection, set flag ok to false and exit 1859 else 1860 bad_connection(corinv(connectmat(jj,3)),0,0,1,-1,0,0,1) 1861 ok=%f;return 1862 end 1863 1864 //if the ndim dimension of the source port is negative 1865 //then the size of the ndim dimension of the target port 1866 //is equal to the sum of the size of the ndim dimension 1867 //of output ports of target block, and flag ok is set to false 1868 else 1869 if ndim==1 then 1870 bllst(connectmat(jj,3)).in(connectmat(jj,4))=sum(ww) 1871 elseif ndim==2 then 1872 bllst(connectmat(jj,3)).in2(connectmat(jj,4))=sum(ww) 1873 end 1874 ok=%f 1875 end 1876 1877 else 1878 //set nww to be the vector of all negative size of output ports 1879 //of the target block 1880 nww=ww(find(ww<0)) 1881 1882 //if all negative size have same size and if size of the 1883 //ndim dimension of the source port is positive then assign 1884 //size of the ndim dimension of the target port to nout(1,ndim) 1885 if norm(nww-nww(1),1)==0 & nout(1,ndim)>0 then 1886 if ndim==1 then 1887 bllst(connectmat(jj,3)).in(connectmat(jj,4))=nout(1,ndim) 1888 elseif ndim==2 then 1889 bllst(connectmat(jj,3)).in2(connectmat(jj,4))=nout(1,ndim) 1890 end 1891 1892 //compute a size to be the difference between the size 1893 //of the ndim dimension of the source block and sum of positive 1894 //size of output ports of the target block divided by the number 1895 //of output ports of target block with same negative size 1896 k=(nout(1,ndim)-sum(ww(find(ww>0))))/size(nww,"*") 1897 1898 //if this size is a positive integer then assign it 1899 //to the size of the ndim dimension of output ports of the 1900 //target block which have negative size 1901 if k==int(k)&k>0 then 1902 if ndim==1 then 1903 bllst(connectmat(jj,3)).out(find(ww<0))=k 1904 elseif ndim==2 then 1905 bllst(connectmat(jj,3)).out2(find(ww<0))=k 1906 end 1907 //else call bad_connection, set flag ok to false and exit 1908 else 1909 bad_connection(corinv(connectmat(jj,3)),0,0,1,-1,0,0,1) 1910 ok=%f;return 1911 end 1912 1913 //set flag ok to false 1914 else 1915 ok=%f 1916 end 1917 1918 end 1919 1920 //sixth (& last) case : dimension of both source 1921 // and target port are negatives 1922 else 1923 ok=%f //set flag ok to false 1924 end 1925 end 1926 end 1927 if ok then return, end //if ok is set true then exit adjust_inout 1928 end 1929 //if failed then display message 1930 msg = _("Not enough information to find port sizes.\nI try to find the problem.") 1931 messagebox(msprintf(msg),"modal","info"); 1932 1933 //%%%%% pass 2 %%%%%// 1934 //Alan 19/01/07 : Warning : Behavior have changed, To Be more Tested 1935 findflag=%f //set findflag to false 1936 1937 for jj=1:nlnk //loop on number of block 1938 //nin/nout are the size (two dimensions) of the 1939 //target port and the source port of the observed link 1940 nout(1,1)=bllst(connectmat(jj,1)).out(connectmat(jj,2)) 1941 nout(1,2)=bllst(connectmat(jj,1)).out2(connectmat(jj,2)) 1942 nin(1,1)=bllst(connectmat(jj,3)).in(connectmat(jj,4)) 1943 nin(1,2)=bllst(connectmat(jj,3)).in2(connectmat(jj,4)) 1944 1945 //loop on the two dimensions of source/target port 1946 //only case : target and source ports are both 1947 // negatives or null 1948 if nout(1,1)<=0&nin(1,1)<=0 | nout(1,2)<=0&nin(1,2)<=0 then 1949 findflag=%t; 1950 // 1951 ninnout=under_connection(corinv(connectmat(jj,1)),connectmat(jj,2),nout(1,ndim),.. 1952 corinv(connectmat(jj,3)),connectmat(jj,4),nin(1,ndim),1) 1953 // 1954 if size(ninnout,2) <> 2 then ok=%f;return;end 1955 if ninnout==[] then ok=%f;return;end 1956 if ninnout(1,1)<=0 | ninnout(1,2)<=0 then ok=%f;return;end 1957 // 1958 ww=find(bllst(connectmat(jj,1)).out==nout(1,1)) 1959 bllst(connectmat(jj,1)).out(ww)=ninnout(1,1) 1960 ww=find(bllst(connectmat(jj,1)).out2==nout(1,1)) 1961 bllst(connectmat(jj,1)).out2(ww)=ninnout(1,1) 1962 1963 ww=find(bllst(connectmat(jj,1)).out==nout(1,2)) 1964 bllst(connectmat(jj,1)).out(ww)=ninnout(1,2) 1965 ww=find(bllst(connectmat(jj,1)).out2==nout(1,2)) 1966 bllst(connectmat(jj,1)).out2(ww)=ninnout(1,2) 1967 // 1968 1969 if bllst(connectmat(jj,1)).nzcross==nout(1,1) then 1970 bllst(connectmat(jj,1)).nzcross=ninnout(1,1) 1971 end 1972 if bllst(connectmat(jj,1)).nzcross==nout(1,2) then 1973 bllst(connectmat(jj,1)).nzcross=ninnout(1,2) 1974 end 1975 // 1976 if bllst(connectmat(jj,1)).nmode==nout(1,1) then 1977 bllst(connectmat(jj,1)).nmode=ninnout(1,1) 1978 end 1979 if bllst(connectmat(jj,1)).nmode==nout(1,2) then 1980 bllst(connectmat(jj,1)).nmode=ninnout(1,2) 1981 end 1982 // 1983 ww=find(bllst(connectmat(jj,1)).in==nout(1,1)) 1984 bllst(connectmat(jj,1)).in(ww)=ninnout(1,1) 1985 ww=find(bllst(connectmat(jj,1)).in2==nout(1,1)) 1986 bllst(connectmat(jj,1)).in2(ww)=ninnout(1,1) 1987 1988 ww=find(bllst(connectmat(jj,1)).in==nout(1,2)) 1989 bllst(connectmat(jj,1)).in(ww)=ninnout(1,2) 1990 ww=find(bllst(connectmat(jj,1)).in2==nout(1,2)) 1991 bllst(connectmat(jj,1)).in2(ww)=ninnout(1,2) 1992 // 1993 ww=find(bllst(connectmat(jj,1)).in==0) 1994 if (ww<>[]&min(bllst(connectmat(jj,1)).out(:))>0) then 1995 bllst(connectmat(jj,1)).in(ww)=sum(bllst(connectmat(jj,1)).out) 1996 end 1997 1998 ww=find(bllst(connectmat(jj,1)).in2==0) 1999 if (ww<>[]&min(bllst(connectmat(jj,1)).out2(:))>0) then 2000 bllst(connectmat(jj,1)).in2(ww)=sum(bllst(connectmat(jj,1)).out2) 2001 end 2002 // 2003 ww=find(bllst(connectmat(jj,3)).in==nin(1,1)) 2004 bllst(connectmat(jj,3)).in(ww)=ninnout(1,1) 2005 ww=find(bllst(connectmat(jj,3)).in2==nin(1,1)) 2006 bllst(connectmat(jj,3)).in2(ww)=ninnout(1,1) 2007 2008 ww=find(bllst(connectmat(jj,3)).in==nin(1,2)) 2009 bllst(connectmat(jj,3)).in(ww)=ninnout(1,2) 2010 ww=find(bllst(connectmat(jj,3)).in2==nin(1,2)) 2011 bllst(connectmat(jj,3)).in2(ww)=ninnout(1,2) 2012 // 2013 if bllst(connectmat(jj,3)).nzcross==nin(1,1) then 2014 bllst(connectmat(jj,3)).nzcross=ninnout(1,1) 2015 end 2016 if bllst(connectmat(jj,3)).nzcross==nin(1,2) then 2017 bllst(connectmat(jj,3)).nzcross=ninnout(1,2) 2018 end 2019 if bllst(connectmat(jj,3)).nmode==nin(1,1) then 2020 bllst(connectmat(jj,3)).nmode=ninnout(1,1) 2021 end 2022 if bllst(connectmat(jj,3)).nmode==nin(1,2) then 2023 bllst(connectmat(jj,3)).nmode=ninnout(1,2) 2024 end 2025 // 2026 ww=find(bllst(connectmat(jj,3)).out==nin(1,1)) 2027 bllst(connectmat(jj,3)).out(ww)=ninnout(1,1) 2028 ww=find(bllst(connectmat(jj,3)).out2==nin(1,1)) 2029 bllst(connectmat(jj,3)).out2(ww)=ninnout(1,1) 2030 2031 ww=find(bllst(connectmat(jj,3)).out==nin(1,2)) 2032 bllst(connectmat(jj,3)).out(ww)=ninnout(1,2) 2033 ww=find(bllst(connectmat(jj,3)).out2==nin(1,2)) 2034 bllst(connectmat(jj,3)).out2(ww)=ninnout(1,2) 2035 // 2036 ww=find(bllst(connectmat(jj,3)).out==0) 2037 if (ww<>[]&min(bllst(connectmat(jj,3)).in(:))>0) then 2038 bllst(connectmat(jj,3)).out(ww)=sum(bllst(connectmat(jj,3)).in(:)) 2039 end 2040 ww=find(bllst(connectmat(jj,3)).out2==0) 2041 if (ww<>[]&min(bllst(connectmat(jj,3)).in2(:))>0) then 2042 bllst(connectmat(jj,3)).out2(ww)=sum(bllst(connectmat(jj,3)).in2(:)) 2043 end 2044 end 2045 end 2046 2047 //if failed then display message 2048 if ~findflag then 2049 msg = _("I cannot find a link with undetermined size.\nMy guess is that you have a block with unconnected \nundetermined output ports.") 2050 messagebox(msprintf(msg), "modal", "error") 2051 ok = %f 2052 return 2053 end 2054 end 2055endfunction 2056 2057function id = getBlockIds(path) 2058 // Return a block id path from a block index path 2059 // 2060 // path: the path in the index form 2061 // id: th path in the uid form 2062 2063 scs_m; // check scs_m access 2064 id=[]; 2065 2066 k = path(:); 2067 for i = k 2068 b = scs_m.objs(i); 2069 if typeof(b) == "Block" & length(scs_m.objs(i).model.uid) >= 1 then 2070 id($ + 1) = scs_m.objs(i).model.uid; 2071 end 2072 if typeof(b.model.rpar) == "diagram" then 2073 scs_m = b.model.rpar; 2074 end 2075 end 2076endfunction 2077 2078//19/01/07, Alan : under_connection show bad link and returns two dimensions now 2079function ninnout=under_connection(path_out,prt_out,nout,path_in,prt_in,nin,flagg) 2080 // alert for badly connected blocks 2081 // path_out : Path of the "from block" in scs_m 2082 // path_in : Path of the "to block" in scs_m 2083 //! 2084 2085 if path_in==-1 then 2086 msg = "<html><body>"; 2087 msg = msg + gettext("One of this block output has negative size.<br />Please check."); 2088 msg = msg + "</body></html>"; 2089 hilite_path(path_out, msg); 2090 ninnout=0 2091 return 2092 end 2093 2094 if path_in==-2 then 2095 msg = "<html><body>"; 2096 msg = msg + gettext("Block input has negative size:"); 2097 msg = msg + "<ul>"; 2098 msg = msg + "<li>" + msprintf(gettext("Input port %s size is: %s"), string(prt_out), sci2exp(nout)) + "</li>"; 2099 msg = msg + "</ul>"; 2100 msg = msg + "</body></html>"; 2101 hilite_path(path_out, msg); 2102 ninnout=0 2103 return 2104 end 2105 2106 // different use case (Unable to report on a non opened diagram) 2107 if isdef("Code_gene_run") then 2108 messagebox([gettext("Unable to report an error into a SuperBlock"); gettext("Please compile the diagram to report the error.")], "Compilation error", "error", "modal"); 2109 ninnout=0 2110 return 2111 end 2112 2113 msg = "<html><body>"; 2114 if flagg==1 then 2115 msg = msg + gettext("<em>Please update the diagram to avoid this warning.</em><br />Block output port has a non-determined size:"); 2116 msg = msg + "<ul>"; 2117 msg = msg + "<li>" + msprintf(gettext("Output port %s size is: %s"), string(prt_out), sci2exp(nout)) + "</li>"; 2118 msg = msg + "<li>" + msprintf(gettext("Input port %s size is: %s"), string(prt_in), sci2exp(nin)) + "</li>"; 2119 else 2120 msg = msg + gettext("<em>Please update the diagram to avoid this warning.</em><br />Block output port has a non-determined type:"); 2121 msg = msg + "<ul>"; 2122 msg = msg + "<li>" + msprintf(gettext("Output port %s type."), string(prt_out)) + "</li>"; 2123 msg = msg + "<li>" + msprintf(gettext("Input port %s type."), string(prt_in)) + "</li>"; 2124 end 2125 msg = msg + "</ul>"; 2126 msg = msg + "</body></html>"; 2127 hilite_path(path_out, msg) 2128 2129 if or(path_in<>path_out) then 2130 msg = "<html><body>"; 2131 if flagg==1 then 2132 msg = msg + gettext("<em>Please update the diagram to avoid this warning.</em><br />Block input port has a non-determined size:"); 2133 msg = msg + "<ul>"; 2134 msg = msg + "<li>" + msprintf(gettext("Output port %s size is: %s"), string(prt_out), sci2exp(nout)) + "</li>"; 2135 msg = msg + "<li>" + msprintf(gettext("Input port %s size is: %s"), string(prt_in), sci2exp(nin)) + "</li>"; 2136 else 2137 msg = msg + gettext("<em>Please update the diagram to avoid this warning.</em><br />Block input port has a non-determined type:"); 2138 msg = msg + "<ul>"; 2139 msg = msg + "<li>" + msprintf(gettext("Output port %s type."), string(prt_out)) + "</li>"; 2140 msg = msg + "<li>" + msprintf(gettext("Input port %s type."), string(prt_in)) + "</li>"; 2141 end 2142 msg = msg + "</ul>"; 2143 msg = msg + "</body></html>"; 2144 hilite_path(path_in, msg) 2145 end 2146 2147 mess=msprintf(_("Highlighted block(s) have connected ports \nwith sizes that cannot be determined by the context.\nWhat is the size of this link?")) 2148 2149 if flagg==1 then 2150 ninnout=evstr(dialog(mess,"[1,1]")) 2151 else 2152 ninnout=evstr(dialog(mess,"1")) 2153 end 2154endfunction 2155 2156function [clkconnect,exe_cons]=pak_ersi(connectmat,clkconnect,.. 2157 typ_r,typ_l,outoin,outoinptr,tblock,typ_cons,clkptr) 2158 2159 //add every event to the time event because time includes all events 2160 all_out=[] 2161 for k=1:size(clkptr,1)-1 2162 if ~typ_l(k) then 2163 kk=[1:(clkptr(k+1)-clkptr(k))]' 2164 all_out=[all_out;[k*ones(kk),kk]] 2165 end 2166 end 2167 all_out=[all_out;[0,0]] 2168 2169 //add time event if needed 2170 ind=find(tblock) 2171 ind=ind(:) 2172 for k=ind' 2173 clkconnect=[clkconnect;[all_out,ones(all_out)*[k,0;0,0]]] 2174 end 2175 if show_trace then mprintf("c_pass4444:\t%f\n", timer()),end 2176 ind1=find(typ_cons) 2177 ind=[ind;ind1(:)] 2178 exe_cons=[ind,zeros(ind)] 2179 2180 vec=-ones(1,nblk); 2181 vec(ind)=0 2182 [r,ok]=newc_tree4(vec,outoin,outoinptr,typ_r) 2183 2184 exe_cons=[exe_cons;r] 2185 2186 if show_trace then mprintf("c_pass4445:\t%f\n", timer()),end 2187 2188 [clkr,clkc]=size(clkconnect); 2189 if isempty(clkconnect) then 2190 cll=[]; 2191 else 2192 mm=max(clkconnect(:,2))+1; 2193 cll=clkconnect(:,1)*mm+clkconnect(:,2); 2194 end 2195 [cll,ind]=gsort(-cll); 2196 clkconnect=clkconnect(ind,:); 2197 if cll<>[] then mcll=max(-cll)+1, else mcll=1;end 2198 cll=[-1;-cll;mcll]; 2199 ii=find(cll(2:$)-cll(1:$-1)<>0) 2200 2201 for k=1:size(ii,"*")-1 2202 oo=[ii(k):ii(k+1)-1] 2203 vec=-ones(1,nblk); 2204 vec(clkconnect(oo,3))=0 2205 [r,ok]=newc_tree4(vec,outoin,outoinptr,typ_r) 2206 m=size(r,1) 2207 r=[clkconnect(ii(k),1)*ones(m,1),clkconnect(ii(k),2)*ones(m,1),r] 2208 clkconnect=[clkconnect;r] 2209 end 2210 // temporary fix to take care of conditional blocks inherting from 2211 // constants: make these blocks always active 2212 2213 ind=setdiff(find(typ_l),clkconnect(:,3)) 2214 ind=ind(:) 2215 for k=ind' 2216 clkconnect=[clkconnect;[all_out,ones(all_out)*[k,0;0,0]]] 2217 end 2218 // end of temoprary fix 2219 if show_trace then mprintf("c_pass4446:\t%f\n", timer()),end 2220endfunction 2221 2222function [r,ok]=tree4(vec,outoin,outoinptr,typ_r) 2223 //compute blocks which inherit 2224 ok=%t; 2225 nb=size(vec,"*"); 2226 r=[]; 2227 for j=1:nb-1 2228 fini=%t 2229 for i=1:nb 2230 if vec(i)==j-1 then 2231 for k=outoinptr(i):outoinptr(i+1)-1 2232 ii=outoin(k,1); 2233 if (vec(ii)>-1)|typ_r(ii) then 2234 fini=%f; 2235 vec(ii)=j; 2236 end 2237 if typ_r(ii) then 2238 r=[r;outoin(k,:)] 2239 end 2240 end 2241 end 2242 end 2243 if fini then break;end 2244 end 2245endfunction 2246 2247function [bllst,inplnk,outlnk,clkptr,cliptr,inpptr,outptr,dep_u,dep_uptr,dep_t,.. 2248 typ_l,typ_r,typ_m,tblock,typ_cons,typ_zx,ok]=mini_extract_info(bllst,.. 2249 connectmat,clkconnect) 2250 ok=%t 2251 nbl=length(bllst) 2252 clkptr=zeros(nbl+1,1);clkptr(1)=1 2253 cliptr=clkptr;inpptr=cliptr;outptr=inpptr; 2254 fff=ones(nbl,1)==1 2255 typ_l=fff;typ_r=fff;typ_cons=fff;typ_m=fff;typ_zx=fff; 2256 dep_t=ones(nbl,1)==1; 2257 dep_u=[];dep_uptr=1; 2258 tblock=fff 2259 //tblock=[] // specifies blocks that must be connected to time event. 2260 // 2261 for i=1:nbl 2262 ll=bllst(i) 2263 if (ll.state==[]&ll.nzcross==0) then typ_zx(i)=%f;end 2264 inpnum=ll.in;outnum=ll.out;cinpnum=ll.evtin;coutnum=ll.evtout; 2265 // 2266 if cinpnum==[] then 2267 // this block inherits 2268 //ok=%f 2269 2270 typ_r(i)=~ll.dep_ut($) 2271 tblock(i)=ll.dep_ut($) 2272 //if block depends on time but has no event input port 2273 if ~ll.dep_ut($) then 2274 //inherits from the inputs 2275 cinpnum=ones(inpnum) 2276 bllst(i).evtin=cinpnum //XXXXXXXXXXXXXXXXXXXXX 2277 end 2278 // 2279 else 2280 tblock(i)=ll.dep_ut($);typ_r(i)=%f 2281 end 2282 inpptr(i+1)=inpptr(i)+size(inpnum,"*") 2283 outptr(i+1)=outptr(i)+size(outnum,"*") 2284 cliptr(i+1)=cliptr(i)+size(cinpnum,"*") 2285 clkptr(i+1)=clkptr(i)+size(coutnum,"*") 2286 // 2287 2288 typ_l(i)=ll.blocktype=="l";typ_m(i)=ll.blocktype=="m"; 2289 typ_cons(i)=cinpnum==[]&inpnum==[]&~ll.dep_ut($) 2290 //test of the dep_ut size 2291 sizenin=size(ll.in,"*"); 2292 if (size(ll.dep_ut,"*") <> 2) then 2293 if ( size(ll.dep_ut(1:$-1),"*") <> sizenin) then 2294 msg = _("the dep_ut size of the %s block is not correct.\nIt should be a column vector of size %d.") 2295 messagebox(msprintf(msg, ll.sim(1), sizenin+1), "modal", "error") 2296 ok=%f; 2297 end 2298 end 2299 2300 dep_t(i)=ll.dep_ut($); 2301 2302 if (size(ll.dep_ut,"*") == 2) then 2303 if (sizenin == 1) then 2304 dep_u($+1)=ll.dep_ut(1); 2305 dep_uptr($+1)=dep_uptr($)+1; 2306 elseif (sizenin > 1) then 2307 dep_u=[dep_u;ones(sizenin,1)==1*ll.dep_ut(1)]; 2308 dep_uptr($+1)=dep_uptr($)+sizenin; 2309 else 2310 dep_uptr($+1)=dep_uptr($); 2311 end 2312 else 2313 dep_u_i=ll.dep_ut(1:$-1); 2314 dep_u=[dep_u;dep_u_i(:)]; 2315 dep_uptr($+1)=dep_uptr($)+sizenin; 2316 end 2317 2318 // 2319 end 2320 if show_trace then mprintf("c_pass22222222:\t%f\n", timer()),end //' 2321 nlnk=size(connectmat,1) 2322 inplnk=zeros(inpptr($)-1,1);outlnk=zeros(outptr($)-1,1);ptlnk=1; 2323 2324 for jj=1:nlnk 2325 ko=outlnk(outptr(connectmat(jj,1))+connectmat(jj,2)-1) 2326 ki=inplnk(inpptr(connectmat(jj,3))+connectmat(jj,4)-1) 2327 if ko<>0 & ki<>0 then 2328 if ko>ki then 2329 outlnk(outlnk>ko)=outlnk(outlnk>ko)-1 2330 outlnk(outlnk==ko)=ki 2331 inplnk(inplnk>ko)=inplnk(inplnk>ko)-1 2332 inplnk(inplnk==ko)=ki 2333 ptlnk=-1+ptlnk 2334 elseif ki>ko 2335 outlnk(outlnk>ki)=outlnk(outlnk>ki)-1 2336 outlnk(outlnk==ki)=ko 2337 inplnk(inplnk>ki)=inplnk(inplnk>ki)-1 2338 inplnk(inplnk==ki)=ko 2339 ptlnk=-1+ptlnk 2340 end 2341 elseif ko<>0 then 2342 inplnk(inpptr(connectmat(jj,3))+connectmat(jj,4)-1)=ko 2343 elseif ki<>0 then 2344 outlnk(outptr(connectmat(jj,1))+connectmat(jj,2)-1)=ki 2345 else 2346 outlnk(outptr(connectmat(jj,1))+connectmat(jj,2)-1)=ptlnk 2347 inplnk(inpptr(connectmat(jj,3))+connectmat(jj,4)-1)=ptlnk 2348 ptlnk=1+ptlnk 2349 end 2350 end 2351 2352 //store unconnected outputs, if any, at the end of outtb 2353 for unco=find(outlnk==0); 2354 outlnk(unco)=max(outlnk)+1 2355 end 2356 2357 //store unconnected inputs, if any, at the end of outtb 2358 for unco=find(inplnk==0); 2359 inplnk(unco)=max([inplnk;max(outlnk)])+1 2360 end 2361endfunction 2362 2363function [evoutoin,evoutoinptr]=synch_clkconnect(typ_l,clkconnect) 2364 nblk=size(typ_l,"*") 2365 evoutoin=[];evoutoinptr=1 2366 for i=1:nblk 2367 if typ_l(i) then 2368 dd=clkconnect(clkconnect(:,1)==i,3) 2369 else 2370 dd=[] 2371 end 2372 evoutoin=[evoutoin;dd] 2373 evoutoinptr=[evoutoinptr;evoutoinptr($)+size(dd,"*")] 2374 end 2375endfunction 2376 2377function clkconnect=cleanup(clkconnect) 2378 mm=max(clkconnect)+1 2379 cc=clkconnect(:,4)+mm*clkconnect(:,3)+clkconnect(:,2)*mm^2+.. 2380 clkconnect(:,1)*mm^3 2381 [cc1,ind]=gsort(-cc) 2382 clkconnect=clkconnect(ind,:) 2383 ind=find(cc1(2:$)-cc1(1:$-1)==0) 2384 clkconnect(ind,:)=[] 2385endfunction 2386 2387//function mat=cleanup1(mat) 2388// mm=max(mat)+1 2389// cc=mat(:,1)*mm 2390// [cc1,ind]=gsort(-cc) 2391// mat=mat(ind,:) 2392// ind=find(cc1(2:$)-cc1(1:$-1)==0) 2393// mat(ind,:)=[] 2394//endfunction 2395 2396function vec=intersection(vec1,vec2) 2397 vec=[] 2398 for i=1:size(vec1,1) 2399 if find(vec1(i)==vec2)~=[] then 2400 vec=[vec;vec1(i)] 2401 end 2402 end 2403endfunction 2404 2405function [r,ok]=newc_tree2(vec,outoin,outoinptr,dep_u,dep_uptr) 2406 dd=zeros(dep_u);dd(dep_u)=1; 2407 [r,ok2]=ctree2(vec,outoin,outoinptr,dd,dep_uptr) 2408 ok=ok2==1 2409endfunction 2410 2411function [r,ok]=new_tree2(vec,outoin,outoinptr,dep_u,dep_uptr) 2412 dd=zeros(dep_u);dd(dep_u)=1; 2413 [r,ok2]=sci_tree2(vec,outoin,outoinptr,dd) 2414 ok=ok2==1 2415endfunction 2416 2417function [r,ok]=new_tree3(vec,dep_ut,typ_l) 2418 dd=zeros(dep_ut);dd(dep_ut)=1; 2419 [r2,ok2]=sci_tree3(vec,dd,typ_l,bexe,boptr,blnk,blptr) 2420 r=r2' 2421 ok=ok2==1 2422endfunction 2423 2424function [r,ok]=newc_tree3(vec,dep_u,dep_uptr,typ_l) 2425 dd=zeros(dep_u);dd(dep_u)=1; 2426 [r2,ok2]=ctree3(vec,dd,dep_uptr,typ_l,bexe,boptr,blnk,blptr) 2427 r=r2' 2428 ok=ok2==1 2429endfunction 2430 2431function [r,ok]=new_tree4(vec,outoin,outoinptr,typ_r) 2432 if isempty(outoin) then 2433 nd=zeros(size(vec,"*"),1); 2434 else 2435 nd=zeros(size(vec,"*"),(max(outoin(:,2))+1)); 2436 end 2437 ddd=zeros(typ_r);ddd(typ_r)=1; 2438 [r1,r2]=sci_tree4(vec,outoin,outoinptr,nd,ddd) 2439 r=[r1',r2'] 2440 ok=%t 2441endfunction 2442 2443function [r,ok]=newc_tree4(vec,outoin,outoinptr,typ_r) 2444 if isempty(outoin) then 2445 nd=zeros(size(vec,"*"),1); 2446 else 2447 nd=zeros(size(vec,"*"),(max(outoin(:,2))+1)); 2448 end 2449 ddd=zeros(typ_r);ddd(typ_r)=1; 2450 [r1,r2]=ctree4(vec,outoin,outoinptr,nd,ddd) 2451 r=[r1',r2'] 2452 ok=%t 2453endfunction 2454 2455function [critev]=critical_events(connectmat,clkconnect,dep_t,typ_r,.. 2456 typ_l,typ_zx,outoin,outoinptr,clkptr) 2457 2458 if isempty(clkconnect) then 2459 critev = []; 2460 return 2461 end 2462 2463 typ_c=typ_l<>typ_l; 2464 typ_r=typ_r|dep_t 2465 2466 done1=%f 2467 while ~done1 2468 done1=%t 2469 [clkr,clkc]=size(clkconnect); 2470 mm=max(clkconnect)+1; 2471 2472 cll=clkconnect(:,1)*mm+clkconnect(:,2); 2473 [cll,ind]=gsort(-cll); 2474 clkconnect=clkconnect(ind,:); 2475 cll=[-1;-cll;mm]; 2476 ii=find(cll(2:$)-cll(1:$-1)<>0) 2477 2478 for k=1:size(ii,"*")-1 2479 oo=[ii(k):ii(k+1)-1] 2480 vec=-ones(1,nblk); 2481 vec(clkconnect(oo,3))=0 2482 [r,ok]=newc_tree4(vec,outoin,outoinptr,typ_r) 2483 2484 m=size(r,1) 2485 r=[clkconnect(ii(k),1)*ones(m,1),clkconnect(ii(k),2)*ones(m,1),r] 2486 clkconnect=[clkconnect;r] 2487 end 2488 2489 done=%f; 2490 while ~done 2491 done=%t; 2492 for jj=find(typ_l&(~typ_c)); 2493 if ~or(jj==clkconnect(:,3)) then 2494 typ_r(clkconnect(find(jj==clkconnect(:,1)),3))=%t 2495 clkconnect(find(jj==clkconnect(:,1)),:)=[]; 2496 typ_c(jj)=%t; 2497 done1=%f 2498 done=%f 2499 end 2500 end 2501 end 2502 end 2503 critev=zeros(clkptr($)-1,1); 2504 for bb=1:size(clkptr,1)-1 2505 for i=clkptr(bb):clkptr(bb+1)-1 2506 if or(typ_zx(clkconnect(find((clkconnect(:,1)==bb)&.. 2507 (clkconnect(:,2)==i-clkptr(bb)+1)),3))) then 2508 critev(i)=1 2509 end 2510 end 2511 end 2512endfunction 2513 2514// adjust_typ: It resolves positive and negative port types. 2515// Its Algorithm is based on the algorithm of adjust_inout 2516// Fady NASSIF: 14/06/2007 2517 2518function [ok,bllst]=adjust_typ(bllst,connectmat) 2519 2520 for i=1:length(bllst) 2521 if size(bllst(i).in,"*")<>size(bllst(i).intyp,"*") then 2522 bllst(i).intyp=bllst(i).intyp(1)*ones(bllst(i).in); 2523 end 2524 if size(bllst(i).out,"*")<>size(bllst(i).outtyp,"*") then 2525 bllst(i).outtyp=bllst(i).outtyp(1)*ones(bllst(i).out); 2526 end 2527 end 2528 nlnk=size(connectmat,1) 2529 for hhjj=1:length(bllst)+1 2530 for hh=1:length(bllst)+1 2531 ok=%t 2532 for jj=1:nlnk 2533 nnout(1,1)=bllst(connectmat(jj,1)).out(connectmat(jj,2)) 2534 nnout(1,2)=bllst(connectmat(jj,1)).out2(connectmat(jj,2)) 2535 nnin(1,1)=bllst(connectmat(jj,3)).in(connectmat(jj,4)) 2536 nnin(1,2)=bllst(connectmat(jj,3)).in2(connectmat(jj,4)) 2537 outtyp = bllst(connectmat(jj,1)).outtyp(connectmat(jj,2)) 2538 intyp = bllst(connectmat(jj,3)).intyp(connectmat(jj,4)) 2539 2540 //first case : types of source and 2541 // target ports are explicitly informed 2542 // with positive types 2543 if (intyp>0 & outtyp>0) then 2544 //if types of source and target port don't match and aren't double and complex 2545 //then call bad_connection, set flag ok to false and exit 2546 2547 if intyp<>outtyp then 2548 if (intyp==1 & outtyp==2) then 2549 bllst(connectmat(jj,3)).intyp(connectmat(jj,4))=2; 2550 elseif (intyp==2 & outtyp==1) then 2551 bllst(connectmat(jj,1)).outtyp(connectmat(jj,2))=2; 2552 else 2553 bad_connection(corinv(connectmat(jj,1)),connectmat(jj,2),.. 2554 nnout,outtyp,.. 2555 corinv(connectmat(jj,3)),connectmat(jj,4),.. 2556 nnin,intyp,1) 2557 ok=%f; 2558 return 2559 end 2560 end 2561 2562 //second case : type of source port is 2563 // positive and type of 2564 // target port is negative 2565 elseif(outtyp>0&intyp<0) then 2566 //find vector of input ports of target block with 2567 //type equal to intyp 2568 //and assign it to outtyp 2569 ww=find(bllst(connectmat(jj,3)).intyp==intyp) 2570 bllst(connectmat(jj,3)).intyp(ww)=outtyp 2571 2572 //find vector of output ports of target block with 2573 //type equal to intyp 2574 //and assign it to outtyp 2575 ww=find(bllst(connectmat(jj,3)).outtyp==intyp) 2576 bllst(connectmat(jj,3)).outtyp(ww)=outtyp 2577 2578 //third case : type of source port is 2579 // negative and type of 2580 // target port is positive 2581 elseif(outtyp<0&intyp>0) then 2582 //find vector of output ports of source block with 2583 //type equal to outtyp 2584 //and assign it to intyp 2585 ww=find(bllst(connectmat(jj,1)).outtyp==outtyp) 2586 bllst(connectmat(jj,1)).outtyp(ww)=intyp 2587 2588 //find vector of input ports of source block with 2589 //type equal to size outtyp 2590 //and assign it to intyp 2591 ww=find(bllst(connectmat(jj,1)).intyp==outtyp) 2592 bllst(connectmat(jj,1)).intyp(ww)=intyp 2593 2594 2595 //fourth (& last) case : type of both source 2596 // and target port are negatives 2597 else 2598 ok=%f //set flag ok to false 2599 end 2600 end 2601 if ok then return, end //if ok is set true then exit adjust_typ 2602 end 2603 //if failed then display message 2604 tmp = _("Not enough information to find port type.\nI will try to find the problem.") 2605 messagebox(msprintf(tmp),"modal","info"); 2606 findflag=%f 2607 for jj=1:nlnk 2608 nouttyp=bllst(connectmat(jj,1)).outtyp(connectmat(jj,2)) 2609 nintyp=bllst(connectmat(jj,3)).intyp(connectmat(jj,4)) 2610 2611 //loop on the two dimensions of source/target port 2612 //only case : target and source ports are both 2613 // negative or null 2614 if nouttyp<=0 & nintyp<=0 then 2615 findflag=%t; 2616 // 2617 inouttyp=under_connection(corinv(connectmat(jj,1)),connectmat(jj,2),nouttyp,.. 2618 corinv(connectmat(jj,3)),connectmat(jj,4),nintyp,2) 2619 // 2620 if inouttyp<1|inouttyp>8 then ok=%f;return;end 2621 // 2622 ww=find(bllst(connectmat(jj,1)).outtyp==nouttyp) 2623 bllst(connectmat(jj,1)).outtyp(ww)=inouttyp 2624 2625 // 2626 ww=find(bllst(connectmat(jj,1)).intyp==nouttyp) 2627 bllst(connectmat(jj,1)).intyp(ww)=inouttyp 2628 2629 ww=find(bllst(connectmat(jj,3)).intyp==nintyp) 2630 bllst(connectmat(jj,3)).intyp(ww)=inouttyp 2631 // 2632 ww=find(bllst(connectmat(jj,3)).outtyp==nintyp) 2633 bllst(connectmat(jj,3)).outtyp(ww)=inouttyp 2634 2635 // 2636 end 2637 end 2638 //if failed then display message 2639 if ~findflag then 2640 msg = _("I cannot find a link with undetermined size.\nMy guess is that you have a block with unconnected \nundetermined types.") 2641 messagebox(msprintf(msg), "modal","error") 2642 ok = %f 2643 return 2644 end 2645 end 2646endfunction 2647 2648