3 // Copyright (C) INRIA - METALAU Project <scicos@inria.fr>
4 // - Ramine Nikoukhah <ramine.nikoukhah@inria.fr> - 2003
5 // - Serge Steer <serge.steer@inria.fr> - 2003
6 // - Fady Nassif <fady.nassif@inria.fr> - 2007
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 2 of the License, or
11 // (at your option) any later version.
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU General Public License for more details.
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the Free Software
20 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 // See the file ../license.txt
25 function [cor,corinv,links_table,cur_fictitious,sco_mat,ok, IN, OUT, EIN, EOUT]=scicos_flat(scs_m,ksup,MaxBlock)
26 //This function takes a hierarchical Scicos diagram and computes the
27 //"flat" equivalent, removing "non computational" blocs like splits.
28 //S. Steer, R. Nikoukhah 2003. Copyright INRIA
30 //NB::--------------------------------------------------------------
31 // Modifying this function to take care of the GOTO FROM SampleCLK and VirtualCLK0 blocks.
32 // A negatif number in cor and in links_table is refer to a GOTO,FROM
33 // GotoTagVisibility, SampleCLK, VirtualCLK0. in other words the blocks that are virtual.
34 // These blocks are removed in the compilation part.
35 // Modification of shiftcors. It will not shift the negatives numbers.
36 // A sco_mat is a string matrix composed by the :
37 // For the blocks GOTO, FROM, VirtualCLK0
38 // - the first column : the negatif of the number of the virtual block in the cor.
39 // - the second column: 1 if it is a GOTO; -1 if it is a FROM.
40 // The VirtualCLK0 is considered as a GOTO.
41 // - the third column : the tag value. 'scicostimeclk0' is used in the case of the VirtualCLK0
42 // - the forth column : the tag visibility
43 // For the GOTO: + 2: scoped
46 // For the VirtualCLK0: 2
47 // - the fifth column : 1=regular 2=event 3=modelica 10=VirtualCLK0
49 // - the first column : the negatif of the number of the virtual block in the cor.
50 // - the second column: the value 1.
51 // - the third column : The frequency value.
52 // - the forth column : The offset value.
53 // - the fifth column : the value 4.
54 // Another two string matrices are used for the GOTO/FROM blocks. The loc_mat it is used when the GOTO
55 // block is local. The from_mat to match the local from with the local goto.
56 // A tag_exprs matrices is used for the GotoTagVisibility and the VirtualCLK0:
58 // - the first column: The tag value. 'scicostimeclk0' in the VirtualCLK0 case.
59 // - the second column: 1=regular 2=event 3=modelica 10=VirtualCLK0
60 // The local and scoped cases are studied in this function.
61 // The global case is studied in the function global_case in c_pass1.
62 // A Modification of update_cor in c_pass1. For the negatives numbers
63 // the cor will be set to 0. (In this case the blocks are considered as IN_f ...)
64 // Fady NASSIF 2007. INRIA.
65 //-------------------------------------------------------------------
67 if argn(2)<=1 then ksup=0;end //used for recursion
68 if ksup==0 then // main scheme
69 MaxBlock=countblocks(scs_m);
70 //last created fictitious block (clock split,clock sum,super_blocks, superbloc))
71 cur_fictitious=MaxBlock
72 path=[]; // for delete_unconnected
73 scs_m_s=scs_m ;// for delete_unconnected
75 //-------------- suppress blocks with an unconnected regular port --------------
76 scs_m=delete_unconnected(scs_m);
78 //list of blocks with are not retained in the final block list
79 blocks_to_remove=["CLKSPLIT_f" "SPLIT_f" "IMPSPLIT_f" "CLKSOM_f" "CLKSOMV_f" "NRMSOM_f" "PAL_f" "xcos_block"]
80 port_blocks=["IN_f","INIMPL_f","OUT_f","OUTIMPL_f","CLKIN_f","CLKINV_f","CLKOUT_f","CLKOUTV_f"]
81 block_goto=["GOTO","CLKGOTO","GOTOMO"]
82 block_from=["FROM","CLKFROM","FROMMO"]
83 block_tag=["GotoTagVisibility","CLKGotoTagVisibility","GotoTagVisibilityMO"]
84 n=lstsize(scs_m.objs) //number of "objects" in the data structure
85 //-------------- initialize outputs --------------
89 cor=list();for k=1:n, cor(k)=0;end
92 IN=[];OUT=[];EIN=[];EOUT=[];
93 Links=[] //to memorize links position in the data structure
95 //-------------- Analyse blocks --------------
96 loc_mat=[];from_mat=[];tag_exprs=[];sco_mat=[];
97 for k=1:n //loop on all objects
101 if x(1)=="Block" then
102 if or(o.gui==block_goto) then
103 cur_fictitious=cur_fictitious+1;
104 cor(k)=-cur_fictitious;
105 if (o.graphics.exprs(2)=="1") then
106 loc_mat=[loc_mat;[string(cur_fictitious),string(1),(o.graphics.exprs(1)),string(find(block_goto(:)==o.gui))]]
108 for i=1:size(loc_mat,1)
109 locomat=[locomat;strcat([loc_mat(i,3) loc_mat(i,4)])]
112 if size(vec,1)<>size(loc_mat,1) then
113 if flgcdgen<>-1 then path=[numk path];scs_m=all_scs_m; end
114 if (ksup==0)|flgcdgen<>-1 then
115 hilite_path([path,k],"There is another local GOTO in this diagram with the same tag ''"+loc_mat($,3)+"''",%t);
117 hilite_path([path,k], "There is another local GOTO in this diagram with the same tag ''"+loc_mat($,3)+"''",%t);
119 disp(mprintf("%s: goto tag not unique", "scicos_flat"));
123 sco_mat=[sco_mat;[string(cur_fictitious),string(1),o.graphics.exprs(1),o.graphics.exprs(2),string(find(block_goto(:)==o.gui))]]
125 elseif or(o.gui==block_from) then
126 cur_fictitious=cur_fictitious+1;
127 cor(k)=-cur_fictitious
128 sco_mat=[sco_mat;[string(cur_fictitious),string(-1),o.graphics.exprs(1),string(1),string(find(block_from(:)==o.gui))]]
129 from_mat=[from_mat;[string(cur_fictitious),string(-1),o.graphics.exprs(1),string(find(block_from(:)==o.gui))]]
130 elseif or(o.gui==block_tag) then
131 tag_exprs=[tag_exprs;[o.graphics.exprs(1),string(find(block_tag(:)==o.gui))]]
132 cur_fictitious=cur_fictitious+1;
133 cor(k)=-cur_fictitious
134 elseif o.gui=="SampleCLK" then
135 if o.graphics.peout<>0 then
136 cur_fictitious=cur_fictitious+1;
137 cor(k)=-cur_fictitious
138 [Nf,Df]=rat(o.model.rpar(1),1d-9);
139 [No,Do]=rat(o.model.rpar(2),1d-9);
140 sco_mat=[sco_mat;[string(cur_fictitious),string(1),string(Nf)+"/"+string(Df),..
141 string(No)+"/"+string(Do),string(4)]]
143 //Adding the VirtualCLK0. Fady 18/11/2007
144 elseif o.gui=="VirtualCLK0" then
145 cur_fictitious=cur_fictitious+1;
146 cor(k)=-cur_fictitious
147 sco_mat=[sco_mat;[string(cur_fictitious),string(1),"scicostimeclk0",..
148 string(2),string(10)]]
149 tag_exprs=[tag_exprs;["scicostimeclk0",string(10)]]
150 elseif or(o.gui==blocks_to_remove) then
151 cur_fictitious=cur_fictitious+1;
152 cor(k)=cur_fictitious
153 elseif o.gui=="SUM_f"|o.gui=="SOM_f" then
157 //scs_m=adjust_sum(scs_m,k)
158 elseif or(o.gui==port_blocks) then
159 //here we suppose to be inside a superblock
160 //may be we can handle this blocks just as blocks_to_remove
163 hilite_path([path,k],gettext("I/O blocks must be only used in a Super Block"),%f)
164 disp(mprintf("%s: Port out of hierarchy", "scicos_flat"));
167 connected=get_connected(scs_m,k)
168 if connected==[] then
170 hilite_path([path,k],gettext("This Super block input port is not connected."),%t)
171 disp(mprintf("%s: Not connected super block input", "scicos_flat"));
174 if or(o.gui==["IN_f","INIMPL_f"]) then
177 elseif or(o.gui==["OUT_f","OUTIMPL_f"]) then
179 OUT=[OUT o.model.ipar]
180 elseif or(o.gui==["CLKIN_f","CLKINV_f"]) then
182 EIN=[EIN o.model.ipar]
183 elseif or(o.gui==["CLKOUT_f","CLKOUTV_f"]) then
185 EOUT=[EOUT o.model.ipar]
187 //connect the link to the fictitious bloc replacing the superblock
188 if scs_m.objs(connected).from(1)==k then
189 scs_m.objs(connected).from(1)=-(pind+o.model.ipar)
191 if scs_m.objs(connected).to(1)==k then
192 scs_m.objs(connected).to(1)=-(pind+o.model.ipar)
194 elseif o.model.sim(1)=="asuper" then
198 if o.graphics.exprs(3).dep_ut($)==%t then
199 sco_mat=[sco_mat;[string(nb) "-1" "scicostimeclk0" "1" "10"]]
201 elseif o.model.sim=="super"|o.model.sim=="csuper" then
202 path=[path k] //superbloc path in the hierarchy
203 //replace superbloc by a set of fictitious blocks (one per port)
204 //and reconnect links connected to the superblock to these
206 Pinds=[];if exists("Pind") then Pinds=Pind,end
207 Pind=[] //base of ports numbering
208 //mprintf("entering superblock at level "+string(size(path,'*'))+"\r\n")
209 nb_pin=size(scs_m.objs(k).graphics("pin"),1);
210 nb_pein=size(scs_m.objs(k).graphics("pein"),1);
211 for port_type=["pin","pout","pein","peout"]
212 Pind=[Pind cur_fictitious]
213 ip=scs_m.objs(k).graphics(port_type);
217 //** a link is connected to the same sblock on both ends
218 if scs_m.objs(kc).to(1)==scs_m.objs(kc).from(1) then
219 //** regular input port
220 if port_type=="pin" then
221 scs_m.objs(kc).to(1)=-(cur_fictitious+scs_m.objs(kc).to(2));
222 scs_m.objs(kc).to(2)=1
224 if scs_m.objs(kc).from(3)==0 then //** in connected to out
225 scs_m.objs(kc).from(1)=-(cur_fictitious+scs_m.objs(kc).from(2)+nb_pin);
226 scs_m.objs(kc).from(2)=1
227 else //** in connected to in
228 scs_m.objs(kc).from(1)=-(cur_fictitious+scs_m.objs(kc).from(2));
229 scs_m.objs(kc).from(2)=1
232 //** regular output port
233 elseif port_type=="pout" then
234 scs_m.objs(kc).from(1)=-(cur_fictitious+scs_m.objs(kc).from(2));
235 scs_m.objs(kc).from(2)=1
237 if scs_m.objs(kc).to(3)==0 then //** out connected to out
238 scs_m.objs(kc).to(1)=-(cur_fictitious+scs_m.objs(kc).to(2));
239 scs_m.objs(kc).to(2)=1
242 //** event input port
243 elseif port_type=="pein" then
244 scs_m.objs(kc).to(1)=-(cur_fictitious+scs_m.objs(kc).to(2));
245 scs_m.objs(kc).to(2)=1
247 scs_m.objs(kc).from(1)=-(cur_fictitious+scs_m.objs(kc).from(2)+nb_pein);
248 scs_m.objs(kc).from(2)=1
250 //** peout and pein are never connected to themselves
253 elseif scs_m.objs(kc).to(1)==k then // a link going to the superblock
254 scs_m.objs(kc).to(1)=-(cur_fictitious+scs_m.objs(kc).to(2));
255 scs_m.objs(kc).to(2)=1
257 elseif scs_m.objs(kc).from(1)==k then // a link coming from the superblock
258 scs_m.objs(kc).from(1)=-(cur_fictitious+scs_m.objs(kc).from(2));
259 scs_m.objs(kc).from(2)=1
262 cur_fictitious=cur_fictitious+size(ip,"*")
266 //Analyze the superblock contents
267 [cors,corinvs,lt,cur_fictitious,scop_mat,ok, localIN, localOUT, localEIN, localEOUT]=scicos_flat(o.model.rpar,cur_fictitious,MaxBlock)
269 disp(mprintf("%s: Invalid super block at %d", "scicos_flat", k));
273 // check if the ports has the right order
274 localIN=-gsort(-localIN);
275 if or(localIN<>[1:size(localIN,"*")]) then
277 msg=gettext("Input ports are not numbered properly.")
278 hilite_path(path,msg,%t)
279 disp(mprintf("%s: Input ports are not numbered properly.", "scicos_flat"))
282 localOUT=-gsort(-localOUT);
283 if or(localOUT<>[1:size(localOUT,"*")]) then
285 msg=gettext("Output ports are not numbered properly.")
286 hilite_path(path,msg,%t)
287 disp(mprintf("%s: Output ports are not numbered properly.", "scicos_flat"))
290 localEIN=-gsort(-localEIN);
291 if or(localEIN<>[1:size(localEIN,"*")]) then
293 msg=gettext("Event input ports are not numbered properly.")
294 hilite_path(path,msg,%t)
295 disp(mprintf("%s: Event input ports are not numbered properly.", "scicos_flat"))
298 localEOUT=-gsort(-localEOUT);
299 if or(localEOUT<>[1:size(localEOUT,"*")]) then
301 msg=gettext("Event output ports are not numbered properly.")
302 hilite_path(path,msg,%t)
303 disp(mprintf("%s: Event output ports are not numbered properly.", "scicos_flat"))
307 //shifting the scop_mat for regular blocks. Fady 08/11/2007
309 v_mat=find(eval(scop_mat(:,1))<MaxBlock)
312 scop_mat(j,1)=string(eval(scop_mat(j,1))+nb)
315 //Adding the scop_mat to the old sco_mat.
316 sco_mat=[sco_mat;scop_mat]
319 //catenate superbloc data with current data
321 f=find(lt(:,1)>0<(:,1)<=nbs);if f<>[] then lt(f,1)=lt(f,1)+nb,end
322 links_table=[links_table;lt]
324 for kk=1:nbs, corinv(nb+kk)=[k,corinvs(kk)];end
325 cors=shiftcors(cors,nb)
326 // cur_fictitious=cur_fictitious+nb
332 else //standard blocks
335 //[model,ok]=build_block(o.model)
337 //Adding the always activated blocks to the sco_mat to take care of the enabling if exists.
339 if ~is_modelica_block(o) then
340 if o.model.dep_ut($) then
341 sco_mat=[sco_mat;[string(nb) "-1" "scicostimeclk0" "1" "10"]]
344 mod_blk_exist=%t // Flag for the existance of modelica's blocks
347 elseif x(1)=="Deleted"|x(1)=="Text" then
348 //this objects are ignored
350 Links=[Links k] // memorize their position for use during links analysis
352 end //end of loop on objects
354 if ksup==0&nb==0 then
355 messagebox(msprintf(gettext("%s: Empty diagram"), "Xcos"),"modal")
357 disp(msprintf("%s: Empty diagram", "scicos_flat"));
360 //-------------- Analyse links --------------
364 if o.from(1)<0|o.from(1)>MaxBlock then //Link coming from a superblock input port
366 o.from(1)=cor(o.from(1));
368 if o.to(1)<0 |o.to(1)>MaxBlock then //Link going to a superblock output port
370 o.to(1)=cor(o.to(1)),
373 if o.ct(2)==2 //implicit links
374 //if abs(o.from(1))==125|abs(o.to(1))==125 then pause,end
375 links_table=[links_table
378 else //regular or event links
379 links_table=[links_table
380 o.from(1:2) -1 o.ct(2) //outputs are tagged with -1
381 o.to(1:2) 1 o.ct(2) ] //inputs are tagged with 1
384 // Warning in case of modelica's blocks in an enabled diagram.
386 tof=find((sco_mat(:,2)=="1")& (sco_mat(:,5)=="10"))
388 if mod_blk_exist then
389 messagebox("Warning the enable does not consider the modelica blocks","modal")
392 //----------------------Goto From Analyses--------------------------
395 for i=1:size(loc_mat,1)
396 index1=find((from_mat(:,2)=="-1")&(from_mat(:,3)==loc_mat(i,3))&(from_mat(:,4)==loc_mat(i,4)))
398 index2=find(links_table(:,1)==-evstr(from_mat(j,1)))
400 // links_table(k,1)=-evstr(loc_mat(i,1))
403 links_table(index2',1)=-evstr(loc_mat(i,1))
405 index2=find(sco_mat(:,1)==from_mat(j,1))
406 sco_mat(index2',:)=[]
411 if tag_exprs<>[] then
412 //to be modified !!!!!
413 // vec=unique(tag_exprs)
414 for i=1:size(tag_exprs,1)
415 index=find((tag_exprs(:,1)==tag_exprs(i,1))&(tag_exprs(:,2)==tag_exprs(i,2)))
416 if size(index,"*") > 1 then
417 messagebox(["Error In Compilation. You cannot have multiple GotoTagVisibility";..
418 " with the same tag value in the same scs_m"],"modal")
420 disp(mprintf("%s: Multiple GotoTagVisibility at the same level", "scicos_flat"));
425 for i=1:size(tag_exprs,1)
426 index=find((sco_mat(:,2)=="1")&(sco_mat(:,3)==tag_exprs(i,1))&(sco_mat(:,4)=="2")&(sco_mat(:,5)==tag_exprs(i,2)))
428 if size(index,"*")>1 then
429 messagebox(["Error in compilation";"Multiple GOTO are taged by the same GotoTagVisibility"],"modal")
431 disp(mprintf("%s: Shared GotoTagVisibility across GOTO", "scicos_flat"));
434 index1=find((sco_mat(:,2)=="-1")&(sco_mat(:,3)==tag_exprs(i,1))&(sco_mat(:,5)==tag_exprs(i,2)))
437 index2=find(links_table(:,1)==-evstr(sco_mat(j,1)))
439 links_table(index2',1)=-evstr(sco_mat(index,1))
441 //linking the always active blocks to the VirtualCLK0 if exists.
442 if sco_mat(j,5)=="10" then
443 links_table($+1,:)=[-evstr(sco_mat(index,1)) 1 -1 -1]
444 links_table($+1,:)=[evstr(sco_mat(j,1)) 0 1 -1]
448 sco_mat([index1';index'],:)=[]
449 //sco_mat(index,:)=[]
454 // function global_case in c_pass1
455 //------------------------------------------------------------------------