Initial version of donated sources by Avertec, 3.4p5.
[tas-yagle.git] / distrib / sources / api / ttv / ttv_API_lines.c
1
2 #include BCK_H
3 #include STM_H
4 #include TTV_H
5 #include MLU_H
6 #include MUT_H
7 #include INF_H
8 #include EFG_H
9 #include TAS_H
10 #include TRC_H
11 #include YAG_H
12 #include MCC_H
13 #include INF_H
14
15 #define API_USE_REAL_TYPES
16 #include "ttv_API_LOCAL.h"
17 #include "ttv_API.h"
18 #include "ttv_API_util.h"
19
20 chain_list *ttv_GetLines(ttvfig_list *tvf, char *start, char *end, char *dir, char *linetype)
21 {
22
23 long type;
24 chain_list *startlist;
25 chain_list *endlist, *cl, *outlist=NULL;
26 ttvline_list *line;
27 int a, b, idir, data=0, i;
28 long val=0;
29 char *c, *tok;
30 char buf[1024];
31 ttvsig_list *tvs;
32
33 if (tvf==NULL) return NULL;
34
35 ttv_disablecache(tvf); // desactivation du cache
36
37 ttv_DirectionStringToIndices(dir, &a, &b);
38 if (a == -1 || b == -1) {
39 avt_errmsg(TTV_API_ERRMSG, "018", AVT_ERROR, dir);
40 /* avt_error("ttvapi", 4, AVT_ERR, "invalid direction '%s', function call ignored\n", dir);
41 avt_error("ttvapi", 4, AVT_INFO, "a direction should look like \"uu\" (start signal rising, end signal rising) or \"ud\" (start signal rising, end signal falling) for instance.\n");*/
42 return NULL;
43 }
44
45 strcpy(buf, linetype);
46 tok=strtok_r(buf, " ", &c);
47 while (tok!=NULL)
48 {
49 if (strcasecmp(tok,"access")==0) val|=TTV_LINE_A;
50 else if (strcasecmp(tok,"setup")==0) val|=TTV_LINE_U;
51 else if (strcasecmp(tok,"hold")==0) val|=TTV_LINE_O;
52 else if (strcasecmp(tok,"data")==0) data=1;
53 else if (strcasecmp(tok,"hz")==0) val|=TTV_LINE_HZ;
54 else if (strcasecmp(tok,"rc")==0) val|=TTV_LINE_RC;
55 else if (strcasecmp(tok,"prech")==0) val|=TTV_LINE_PR;
56 else if (strcasecmp(tok,"eval")==0) val|=TTV_LINE_EV;
57 else if (strcasecmp(tok,"all")==0) val=-1;
58 else //avt_error("ttvapi", -1, AVT_ERR, "bad value '%s' in 'ttv_GetLines'\n",tok);
59 avt_errmsg(TTV_API_ERRMSG, "028", AVT_ERROR, tok);
60
61 tok=strtok_r(NULL, " ", &c);
62 }
63
64 val&=~TTV_LINE_CONT;
65 if (val==0 && !data) val=-1;
66
67 if (a == TTVAPI_UP) a=1;
68 else if (a == TTVAPI_DN) a=0;
69 else a=2;
70 if (b == TTVAPI_UP) b=1;
71 else if (b == TTVAPI_DN) b=0;
72 else b=2;
73
74 if ((ttv_getloadedfigtypes(tvf) & TTV_FILE_DTX)==TTV_FILE_DTX)
75 type = TTV_FIND_LINE;
76 else
77 type = TTV_FIND_PATH;
78
79 cl=addchain(NULL, namealloc(start));
80 startlist=ttv_getsigbytype_and_netname(tvf,NULL,TTV_SIG_TYPEALL,cl) ;
81 freechain(cl);
82 for (cl=startlist; cl!=NULL; cl=cl->NEXT)
83 ((ttvsig_list *)cl->DATA)->TYPE|=TTV_SIG_MARQUE;
84
85 cl=addchain(NULL, namealloc(end));
86 endlist=ttv_getsigbytype_and_netname(tvf,NULL,TTV_SIG_TYPEALL,cl) ;
87 freechain(cl);
88
89 for (cl=endlist; cl!=NULL; cl=cl->NEXT)
90 {
91 tvs=(ttvsig_list *)cl->DATA;
92 if((type & TTV_FIND_PATH) == TTV_FIND_PATH)
93 {
94 ttv_expfigsig(tvf,tvs,tvs->ROOT->INFO->LEVEL,tvf->INFO->LEVEL,
95 TTV_STS_CL_PJT, TTV_FILE_TTX);
96 }
97 else
98 {
99 ttv_expfigsig(tvf,tvs,tvs->ROOT->INFO->LEVEL,tvf->INFO->LEVEL,
100 TTV_STS_CLS_FED, TTV_FILE_DTX);
101 }
102
103 for (i=0; i<2; i++)
104 {
105 if (b==2 || i==b)
106 {
107 if ((type & TTV_FIND_PATH) == TTV_FIND_PATH)
108 line=tvs->NODE[i].INPATH;
109 else
110 line=tvs->NODE[i].INLINE;
111
112
113 while (line!=NULL)
114 {
115 if(!((((line->TYPE & (TTV_LINE_D | TTV_LINE_T)) != 0) &&
116 (line->FIG != tvf)) ||
117 (((line->TYPE & (TTV_LINE_P | TTV_LINE_F)) != 0) &&
118 (line->FIG->INFO->LEVEL < tvs->ROOT->INFO->LEVEL))))
119 {
120 idir=(line->NODE->TYPE & TTV_NODE_UP)!=0?1:0;
121 if ((line->NODE->ROOT->TYPE & TTV_SIG_MARQUE)!=0
122 && (a==2 || idir==a)
123 && (val==-1 ||
124 (line->TYPE & val)!=0 ||
125 (data && (line->TYPE & TTV_LINE_CONT)==0))
126 )
127 outlist=addchain(outlist, line);
128 }
129 line=line->NEXT;
130 }
131 }
132 }
133 }
134
135 for (cl=startlist; cl!=NULL; cl=cl->NEXT)
136 ((ttvsig_list *)cl->DATA)->TYPE&=~TTV_SIG_MARQUE;
137
138 freechain(startlist);
139 freechain(endlist);
140 return outlist;
141 }
142
143 double ttv_GetTimingLineFloatProperty(ttvline_list *tl, char *prop, char *sub_prop)
144 {
145 long val=TTV_NOTIME;
146 int fail=0;
147
148 if (((tl->TYPE & TTV_LINE_U)==TTV_LINE_U
149 || (tl->TYPE & TTV_LINE_O)==TTV_LINE_O) && strcasecmp(sub_prop,"min")==0)
150 return ttv_GetTimingLineFloatProperty(tl, prop, "max");
151
152 if (strcasecmp(prop,"delay")==0)
153 {
154 if (strcasecmp(sub_prop,"min")==0) val=ttv_getdelaymin(tl);
155 else if (strcasecmp(sub_prop,"max")==0) val=ttv_getdelaymax(tl);
156 else fail=1;
157 }
158 else if (strcasecmp(prop,"slope")==0)
159 {
160 if (strcasecmp(sub_prop,"min")==0) val=ttv_getslopemin(tl);
161 else if (strcasecmp(sub_prop,"max")==0) val=ttv_getslopemax(tl);
162 else fail=1;
163 }
164 else if (strcasecmp(prop,"ref_delay")==0)
165 {
166 if (strcasecmp(sub_prop,"min")==0) val=tl->VALMIN;
167 else if (strcasecmp(sub_prop,"max")==0) val=tl->VALMAX;
168 else fail=1;
169 }
170 else if (strcasecmp(prop,"ref_slope")==0)
171 {
172 if (strcasecmp(sub_prop,"min")==0) val=tl->FMIN;
173 else if (strcasecmp(sub_prop,"max")==0) val=tl->FMAX;
174 else fail=1;
175 }
176
177 if (fail) //printf("unrecognized propoerty '%s':'%s'\n", prop, sub_prop);
178 avt_errmsg(TTV_API_ERRMSG, "029", AVT_ERROR, prop, sub_prop);
179 if (val==TTV_NOTIME) return -1;
180 return _LONG_TO_DOUBLE(val);
181 }
182
183 ttvevent_list *ttv_GetTimingLineEventProperty(ttvline_list *tl, char *prop)
184 {
185 long val=TTV_NOTIME;
186 int fail=0;
187 if (strcasecmp(prop,"start")==0) return tl->NODE;
188 else if (strcasecmp(prop,"end")==0) return tl->ROOT;
189 else fail=1;
190
191 if (fail)// printf("unrecognized property '%s'\n", prop);
192 avt_errmsg(TTV_API_ERRMSG, "030", AVT_ERROR, prop);
193 return NULL;
194 }
195
196 char *ttv_GetTimingLineStringProperty(ttvline_list *tl, char *prop)
197 {
198 long val=TTV_NOTIME;
199 int fail=0;
200 if (strcasecmp(prop,"type")==0)
201 {
202 if ((tl->TYPE & TTV_LINE_A)==TTV_LINE_A) return "access";
203 if ((tl->TYPE & TTV_LINE_U)==TTV_LINE_U) return "setup";
204 if ((tl->TYPE & TTV_LINE_O)==TTV_LINE_O) return "hold";
205 if ((tl->TYPE & TTV_LINE_HZ)==TTV_LINE_HZ) return "hz";
206 if ((tl->TYPE & TTV_LINE_RC)==TTV_LINE_RC) return "rc";
207 if ((tl->TYPE & TTV_LINE_PR)==TTV_LINE_PR) return "prech";
208 if ((tl->TYPE & TTV_LINE_EV)==TTV_LINE_EV) return "eval";
209 return "data";
210 }
211 else fail=1;
212
213 if (fail) //printf("unrecognized property '%s'\n", prop);
214 avt_errmsg(TTV_API_ERRMSG, "030", AVT_ERROR, prop);
215 return "?";
216 }
217
218 static inline char *tostring(double val, char *buf)
219 {
220 sprintf(buf, "%g", val);
221 return strdup(buf);
222 }
223
224 Property *ttv_GetTimingLineProperty (TimingLine *tl, char *code)
225 {
226 char buf[256];
227
228 if (!tl) {
229 return addptype (NULL, TYPE_CHAR, strdup ("error_null_timing_line"));
230 }
231
232 if (!strcasecmp (code, "TYPE")) {
233 return addptype (NULL, TYPE_CHAR, strdup (ttv_GetTimingLineStringProperty(tl, "type")));
234 }
235
236 if (!strcasecmp (code, "START_EVENT"))
237 return addptype (NULL, TYPE_TIMING_EVENT, ttv_GetTimingLineEventProperty(tl, "start"));
238
239 if (!strcasecmp (code, "END_EVENT"))
240 return addptype (NULL, TYPE_TIMING_EVENT, ttv_GetTimingLineEventProperty(tl, "end"));
241
242 if (!strcasecmp (code, "DELAY_MAX"))
243 return addptype (NULL, TYPE_CHAR, tostring(ttv_GetTimingLineFloatProperty(tl, "delay", "max"),buf));
244
245 if (!strcasecmp (code, "REF_DELAY_MAX"))
246 return addptype (NULL, TYPE_CHAR, tostring(ttv_GetTimingLineFloatProperty(tl, "ref_delay", "max"),buf));
247
248 if (!strcasecmp (code, "SLOPE_MAX"))
249 return addptype (NULL, TYPE_CHAR, tostring(ttv_GetTimingLineFloatProperty(tl, "slope", "max"),buf));
250
251 if (!strcasecmp (code, "REF_SLOPE_MAX"))
252 return addptype (NULL, TYPE_CHAR, tostring(ttv_GetTimingLineFloatProperty(tl, "ref_slope", "max"),buf));
253
254 if (!strcasecmp (code, "DELAY_MIN"))
255 return addptype (NULL, TYPE_CHAR, tostring(ttv_GetTimingLineFloatProperty(tl, "delay", "min"),buf));
256
257 if (!strcasecmp (code, "REF_DELAY_MIN"))
258 return addptype (NULL, TYPE_CHAR, tostring(ttv_GetTimingLineFloatProperty(tl, "ref_delay", "min"),buf));
259
260 if (!strcasecmp (code, "SLOPE_MIN"))
261 return addptype (NULL, TYPE_CHAR, tostring(ttv_GetTimingLineFloatProperty(tl, "slope", "min"),buf));
262
263 if (!strcasecmp (code, "REF_SLOPE_MIN"))
264 return addptype (NULL, TYPE_CHAR, tostring(ttv_GetTimingLineFloatProperty(tl, "ref_slope", "min"),buf));
265
266 if (!strcasecmp (code, "COMMAND"))
267 return addptype (NULL, TYPE_TIMING_EVENT, ttv_getlinecmd(ttv_GetTopTimingFigure(tl->FIG), tl, TTV_LINE_CMDMAX));
268
269 avt_errmsg(TTV_API_ERRMSG, "030", AVT_ERROR, code);
270 //fprintf (stderr, "error: unknown property %s\n", code);
271 return NULL;
272 }
273
274 double ttv_ComputeLineDelay(ttvline_list *tl, double slope_in, double output_capa, char *delayslope, char *maxmin)
275 {
276 float slope, val;
277 char *model=NULL;
278 int err=0;
279
280 API_TEST_TOKEN_SUB(TMA_API,"tma")
281
282 if (tl==NULL) return -1;
283
284 if (strcasecmp(delayslope,"delay")==0)
285 {
286 if (strcasecmp(maxmin,"max")==0) model=tl->MDMAX;
287 else if (strcasecmp(maxmin,"min")==0) model = tl->MDMIN ;
288 else err=1;
289 }
290 else if (strcasecmp(delayslope,"slope")==0)
291 {
292 if (strcasecmp(maxmin,"max")==0) model=tl->MFMAX;
293 else if (strcasecmp(maxmin,"min")==0) model = tl->MFMIN ;
294 else err=1;
295 }
296 else err=2;
297
298 if (!err)
299 {
300 if (model!=NULL)
301 {
302 if (strcasecmp(delayslope,"delay")==0)
303 val = stm_getdelay (tl->FIG->INFO->FIGNAME, model, output_capa * 1e15, slope_in*1e12, NULL,tl->ROOT->ROOT->NAME);
304 else
305 val = stm_getslew (tl->FIG->INFO->FIGNAME, model, output_capa * 1e15, slope_in*1e12, NULL, NULL,tl->ROOT->ROOT->NAME);
306 return val*1e-12;
307 }
308 else
309 {
310 if (strcasecmp(delayslope,"delay")==0)
311 {
312 if (strcasecmp(maxmin,"max")==0) val=_LONG_TO_DOUBLE(tl->VALMAX);
313 else val=_LONG_TO_DOUBLE(tl->VALMIN);
314 }
315 else if (strcasecmp(delayslope,"slope")==0)
316 {
317 if (strcasecmp(maxmin,"max")==0) val=_LONG_TO_DOUBLE(tl->FMAX);
318 else val = _LONG_TO_DOUBLE(tl->FMIN) ;
319 }
320 return val;
321 }
322 }
323 else
324 {
325 avt_errmsg(TTV_API_ERRMSG, "031", AVT_ERROR, err==2?delayslope:maxmin);
326 // fprintf (stderr, "error: unknown parameter value '%s'\n", err==2?delayslope:maxmin);
327 }
328 return -1;
329 }
330
331 void ttv_SetTimingLineDelay(ttvline_list *tl, char *prop, char *sub_prop, double value)
332 {
333 long val=mbk_long_round(value*1e12*TTV_UNIT);
334 int fail=1;
335
336 if (strcasecmp(prop,"delay")==0)
337 {
338 if (strcasecmp(sub_prop,"min")==0 || strcasecmp(sub_prop,"all")==0)
339 {
340 tl->VALMIN=val;
341 tl->MDMIN=NULL;
342 fail=0;
343 }
344 if (strcasecmp(sub_prop,"max")==0 || strcasecmp(sub_prop,"all")==0)
345 {
346 tl->VALMAX=val;
347 tl->MDMAX=NULL;
348 fail=0;
349 }
350 }
351 else if (strcasecmp(prop,"slope")==0)
352 {
353 if (val<=0)
354 {
355 avt_errmsg(TTV_API_ERRMSG, "032", AVT_ERROR, value);
356 // printf("ttv_SetTimingLineDelay: negative slope given (%g), set to 1e-12\n", value);
357 val=mbk_long_round(TTV_UNIT);
358 }
359
360 if (strcasecmp(sub_prop,"min")==0 || strcasecmp(sub_prop,"all")==0)
361 {
362 tl->FMIN=val;
363 tl->MFMIN=NULL;
364 fail=0;
365 }
366 if (strcasecmp(sub_prop,"max")==0 || strcasecmp(sub_prop,"all")==0)
367 {
368 tl->FMAX=val;
369 tl->MFMAX=NULL;
370 fail=0;
371 }
372 }
373
374 if (fail) //printf("unrecognized property '%s':'%s'\n", prop, sub_prop);
375 avt_errmsg(TTV_API_ERRMSG, "029", AVT_ERROR, prop, sub_prop);
376 }