Initial version of donated sources by Avertec, 3.4p5.
[tas-yagle.git] / distrib / sources / api / tma / tma_API_blackbox.c
1 /****************************************************************************/
2 /* */
3 /* Chaine de CAO & VLSI Alliance */
4 /* */
5 /* Produit : TMA Version 1 */
6 /* Fichier : tma_blackbox.c */
7 /* */
8 /* (c) copyright 1997-1998 Laboratoire LIP6 equipe ASIM */
9 /* Tous droits reserves */
10 /* Support : e-mail alliance-support@asim.lip6.fr */
11 /* */
12 /* Auteur(s) : Gilles AUGUSTINS */
13 /* */
14 /****************************************************************************/
15
16 #include MUT_H
17 #include MLO_H
18 #include MLU_H
19 #include RCN_H
20 #include MSL_H
21 #include AVT_H
22 #include INF_H
23 #include ELP_H
24 #include CNS_H
25 #include YAG_H
26 #include TLC_H
27 #include TRC_H
28 #include STM_H
29 #include TTV_H
30 #include MCC_H
31 #include SIM_H
32 #include TAS_H
33 #include FCL_H
34 #include BEH_H
35 #include BHL_H
36 #include BEF_H
37 #include BVL_H
38 #include CBH_H
39 #include TUT_H
40 #include LIB_H
41 #include TLF_H
42 #include STB_H
43 #include TMA_H
44
45 #define API_USE_REAL_TYPES
46 #include "tma_API.h"
47 #include "ttv_API.h"
48
49 float Compute_Delay (ttvfig_list *fig, float slope, float load, ttvpath_list *path, char *max)
50 {
51 char start_tran,
52 end_tran;
53 ttvsig_list *start_sig,
54 *end_sig;
55 char *start_name,
56 *end_name;
57 chain_list *res_path;
58 ttvpath_list *pt_res_path;
59 int prop;
60 float delay;
61 char tran[8];
62
63 start_tran = ttv_GetPathStartDirection (path);
64 end_tran = ttv_GetPathEndDirection (path);
65 start_sig = ttv_GetPathStartSignal (path);
66 end_sig = ttv_GetPathEndSignal (path);
67 start_name = ttv_GetSignalName (start_sig);
68 end_name = ttv_GetSignalName (end_sig);
69 sprintf (tran, "%c%c", start_tran, end_tran);
70 // no slope propagation prop = 0
71 // full slope propagation prop = 1
72 // 1-stage slope propagation prop = 2
73 prop = 1;
74 res_path = ttv_CharacPaths (fig, slope, start_name, end_name, tran, 1, "critic", "path", max, load, prop);
75 pt_res_path = (ttvpath_list*)res_path->DATA;
76 freechain (res_path);
77 delay = ttv_GetPathRefDelay (pt_res_path);
78 return delay;
79 }
80 /* -------------------------------------------------------------------------------------------------- */
81 /* -------------------------------------------------------------------------------------------------- */
82 /* -------------------------------------------------------------------------------------------------- */
83
84 chain_list *Global_Prop (ttvfig_list *fig, float *slope_tab, float *load_tab, ttvpath_list *path, char *max, int nb_slope, int nb_load)
85 {
86 int i, j;
87 float delay;
88
89 for (i = 0; i < nb_slope; i++)
90 for (j = 0; j < nb_load; j++) {
91 delay = Compute_Delay (fig, slope_tab[i], load_tab[j], path, max);
92 fprintf (stdout, "delay (%g, %g) = %g\n", slope_tab[i], load_tab[j], delay);
93 }
94
95 return NULL;
96 }
97 /* -------------------------------------------------------------------------------------------------- */
98 /* -------------------------------------------------------------------------------------------------- */
99 /* -------------------------------------------------------------------------------------------------- */
100
101 chain_list **extractSetupHold (float *slope_tab, int nb_slope, ttvfig_list *fig, char *clock, char *pin, char *mode)
102 {
103 return NULL;
104 }
105
106 /* -------------------------------------------------------------------------------------------------- */
107
108 chain_list **extractAccess (float *slope_tab, float *load_tab, int nb_slope, int nb_load, ttvfig_list *fig, char *clock, char *pin, char *mode, char *minmax)
109 {
110 return NULL;
111 }
112
113 /* -------------------------------------------------------------------------------------------------- */
114
115 chain_list **extractPropDelay (float *slope_tab, float *load_tab, int nb_slope, int nb_load, ttvfig_list *fig, char *input, char *output, char *mode, char *minmax)
116 {
117 chain_list *prop_rr = NULL,
118 *prop_rf = NULL,
119 *prop_fr = NULL,
120 *prop_ff = NULL;
121 chain_list *prop_list;
122 ttvpath_list *pt_path;
123 chain_list *path, *path_list;
124 ttvsig_list *start_sig, *end_sig;
125 char start_tran, end_tran;
126 chain_list **clist = (chain_list**)malloc (4 * sizeof (chain_list*));
127
128 if (!strcmp (minmax, "max"))
129 path_list = ttv_GetPaths (fig, input, output, "??", 1000, "critic", "path", "max");
130 else
131 path_list = ttv_GetPaths (fig, input, output, "??", 1000, "critic", "path", "min");
132
133 for (path = path_list; path; path = path->NEXT) {
134 pt_path = (ttvpath_list*)path->DATA;
135 start_sig = ttv_GetPathStartSignal (pt_path);
136 end_sig = ttv_GetPathEndSignal (pt_path);
137 start_tran = ttv_GetPathStartDirection (pt_path);
138 end_tran = ttv_GetPathEndDirection (pt_path);
139
140 prop_list = Global_Prop (fig, slope_tab, load_tab, pt_path, minmax, nb_slope, nb_load);
141
142 if (start_tran == 'u') {
143 if (end_tran == 'u') prop_rr = prop_list;
144 if (end_tran == 'd') prop_rf = prop_list;
145 } else if (start_tran == 'd') {
146 if (end_tran == 'u') prop_fr = prop_list;
147 if (end_tran == 'd') prop_ff = prop_list;
148 }
149 }
150
151 clist[0] = prop_rr;
152 clist[1] = prop_rf;
153 clist[2] = prop_fr;
154 clist[3] = prop_ff;
155
156 return clist;
157 }
158
159 /* -------------------------------------------------------------------------------------------------- */
160 /* -------------------------------------------------------------------------------------------------- */
161 /* -------------------------------------------------------------------------------------------------- */
162
163 void tma_addSetupHold (float *slope_tab, int nb_slope, ttvfig_list *fig, ttvfig_list *bb, char *clock, char *input, char *mode)
164 {
165 chain_list **clist = NULL;
166 chain_list *su_rr = NULL,
167 *su_rf = NULL,
168 *su_fr = NULL,
169 *su_ff = NULL,
170 *ho_rr = NULL,
171 *ho_rf = NULL,
172 *ho_fr = NULL,
173 *ho_ff = NULL;
174
175 fprintf (stdout, "SETUP/HOLD %s -> %s\n", clock, input);
176
177 if ((clist = extractSetupHold (slope_tab, nb_slope, fig, clock, input, mode))) {
178 su_rr = clist [0];
179 su_rf = clist [1];
180 ho_rr = clist [2];
181 ho_rf = clist [3];
182 su_fr = clist [4];
183 su_ff = clist [5];
184 ho_fr = clist [6];
185 ho_ff = clist [7];
186 }
187
188 if (su_rr) freechain (su_rr);
189 if (su_rf) freechain (su_rf);
190 if (ho_rr) freechain (ho_rr);
191 if (ho_rf) freechain (ho_rf);
192 if (su_fr) freechain (su_fr);
193 if (su_ff) freechain (su_ff);
194 if (ho_fr) freechain (ho_fr);
195 if (ho_ff) freechain (ho_ff);
196
197 if (clist) free (clist);
198 }
199
200 /* -------------------------------------------------------------------------------------------------- */
201
202 void tma_addPropDelay (float *slope_tab, float *load_tab, int nb_slope, int nb_load, ttvfig_list *fig, ttvfig_list *bb, char *input, char *output, char *mode)
203 {
204 chain_list **clist = NULL;
205 chain_list *prop_rr_min = NULL,
206 *prop_rf_min = NULL,
207 *prop_fr_min = NULL,
208 *prop_ff_min = NULL;
209 chain_list *prop_rr_max = NULL,
210 *prop_rf_max = NULL,
211 *prop_fr_max = NULL,
212 *prop_ff_max = NULL;
213
214 fprintf (stdout, "PROP %s -> %s\n", input, output);
215
216 if ((clist = extractPropDelay (slope_tab, load_tab, nb_slope, nb_load, fig, input, output, mode, "min"))) {
217 prop_rr_min = clist[0];
218 prop_rf_min = clist[1];
219 prop_fr_min = clist[2];
220 prop_ff_min = clist[3];
221 }
222
223 if ((clist = extractPropDelay (slope_tab, load_tab, nb_slope, nb_load, fig, input, output, mode, "max"))) {
224 prop_rr_max = clist[0];
225 prop_rf_max = clist[1];
226 prop_fr_max = clist[2];
227 prop_ff_max = clist[3];
228 }
229
230 if (prop_rr_min) freechain (prop_rr_min);
231 if (prop_rf_min) freechain (prop_rf_min);
232 if (prop_fr_min) freechain (prop_fr_min);
233 if (prop_ff_min) freechain (prop_ff_min);
234 if (prop_rr_max) freechain (prop_rr_max);
235 if (prop_rf_max) freechain (prop_rf_max);
236 if (prop_fr_max) freechain (prop_fr_max);
237 if (prop_ff_max) freechain (prop_ff_max);
238
239 if (clist) free (clist);
240 }
241
242 /* -------------------------------------------------------------------------------------------------- */
243
244 void tma_addAccess (float *slope_tab, float *load_tab, int nb_slope, int nb_load, ttvfig_list *fig, ttvfig_list *bb, char *clock, char *output, char *mode)
245 {
246 chain_list **clist = NULL;
247 chain_list *acs_rr_min = NULL,
248 *acs_rf_min = NULL,
249 *acs_fr_min = NULL,
250 *acs_ff_min = NULL;
251 chain_list *acs_rr_max = NULL,
252 *acs_rf_max = NULL,
253 *acs_fr_max = NULL,
254 *acs_ff_max = NULL;
255
256 fprintf (stdout, "ACCESS %s -> %s\n", clock, output);
257
258 if ((clist = extractAccess (slope_tab, load_tab, nb_slope, nb_load, fig, clock, output, mode, "min"))) {
259 acs_rr_min = clist[0];
260 acs_rf_min = clist[1];
261 acs_fr_min = clist[2];
262 acs_ff_min = clist[3];
263 }
264
265 if ((clist = extractAccess (slope_tab, load_tab, nb_slope, nb_load, fig, clock, output, mode, "max"))) {
266 acs_rr_max = clist[0];
267 acs_rf_max = clist[1];
268 acs_fr_max = clist[2];
269 acs_ff_max = clist[3];
270 }
271
272 if (acs_rr_min) freechain (acs_rr_min);
273 if (acs_rf_min) freechain (acs_rf_min);
274 if (acs_fr_min) freechain (acs_fr_min);
275 if (acs_ff_min) freechain (acs_ff_min);
276 if (acs_rr_max) freechain (acs_rr_max);
277 if (acs_rf_max) freechain (acs_rf_max);
278 if (acs_fr_max) freechain (acs_fr_max);
279 if (acs_ff_max) freechain (acs_ff_max);
280
281 if (clist) free (clist);
282 }
283
284 /* -------------------------------------------------------------------------------------------------- */
285 /* -------------------------------------------------------------------------------------------------- */
286 /* -------------------------------------------------------------------------------------------------- */
287 ttvfig_list *tma_APIBlackBox (ttvfig_list *fig, char *suffix)
288 {
289 int verbose = V_BOOL_TAB[__TMA_VERBOSE].VALUE;
290 stbfig_list *stbfig = NULL;
291 ttvsig_list *pt_pin;
292 char dir, *name, *figname, *bbname;
293 chain_list *pin_list, *pin,
294 *input_list = NULL,
295 *output_list = NULL,
296 *clock_list = NULL;
297 chain_list *input, *output, *clock;
298 float slope_unit, cap_unit;
299 char buf[4096];
300 float *slope_tab, *load_tab;
301 int nb_slope, nb_load;
302 ttvfig_list *blackbox;
303
304 /* CONFIG REQUIRED HERE */
305 slope_unit = 1e-12;
306 cap_unit = 1e-15;
307 nb_slope = 3;
308 nb_load = 4;
309 slope_tab = (float*)malloc (nb_slope * sizeof (float));
310 load_tab = (float*)malloc (nb_load * sizeof (float));
311 load_tab[0] = 10 * cap_unit;
312 load_tab[1] = 50 * cap_unit;
313 load_tab[2] = 100 * cap_unit;
314 slope_tab[0] = 100 * slope_unit;
315 slope_tab[1] = 200 * slope_unit;
316 slope_tab[2] = 300 * slope_unit;
317 clock_list = addchain (clock_list, (void*)"ck");
318
319 if (!fig) return NULL;
320
321 stbfig = stb_getstbfig(fig);
322
323 figname = fig->INFO->FIGNAME;
324
325 avt_log( LOGTMA, 1, "timing figure is %s\n", figname );
326
327 if (suffix) {
328 sprintf (buf, "%s_%s", figname, suffix);
329 bbname = namealloc (buf);
330 } else
331 bbname = figname;
332
333 blackbox = tma_DupTtvFigHeader (bbname, fig, "*");
334 stm_addcell (bbname);
335 tma_DupConnectorList (blackbox, fig);
336
337 pin_list = ttv_GetTimingSignalList (blackbox, "connector", "interface");
338 for (pin = pin_list; pin; pin = pin->NEXT) {
339 pt_pin = (ttvsig_list*)(pin->DATA);
340 dir = ttv_GetConnectorDirection (pt_pin);
341 if (dir == 'i') {
342 name = ttv_GetSignalName (pt_pin);
343 input_list = addchain (input_list, name);
344 }
345 if (dir == 'o' || dir == 'b' || dir == 't' || dir == 'z') {
346 name = ttv_GetSignalName (pt_pin);
347 output_list = addchain (output_list, name);
348 }
349 }
350
351 for (input = input_list; input; input = input->NEXT) {
352 for (clock = clock_list; clock; clock = clock->NEXT)
353 tma_addSetupHold (slope_tab, nb_slope, fig, blackbox, (char*)clock->DATA, (char*)input->DATA, "debug");
354
355 for (output = output_list; output; output = output->NEXT)
356 tma_addPropDelay (slope_tab, load_tab, nb_slope, nb_load, fig, blackbox, (char*)input->DATA, (char*)output->DATA, "debug");
357 }
358
359 for (output = output_list; output; output = output->NEXT)
360 for (clock = clock_list; clock; clock = clock->NEXT)
361 tma_addAccess (slope_tab, load_tab, nb_slope, nb_load, fig, blackbox, (char*)clock->DATA, (char*)output->DATA, "debug");
362
363 freechain (clock_list);
364 freechain (input_list);
365 freechain (output_list);
366 free (slope_tab);
367 free (load_tab);
368
369 return blackbox;
370 }
371
372 void tma_SetMaxCapacitance(ttvfig_list *bbox, char *name, double value)
373 {
374 chain_list *cl;
375 ttvsig_list *tvs;
376 ptype_list *pt;
377
378 if ((cl=ttv_GetMatchingSignal(bbox, name, "connector"))==NULL)
379 avt_errmsg(TMA_API_ERRMSG, "002", AVT_WARNING, name);
380
381 while (cl!=NULL)
382 {
383 tvs=(chain_list *)cl->DATA;
384 if ((pt=getptype(tvs->USER, LIB_MAX_CAPACITANCE))==NULL)
385 pt=tvs->USER=addptype(tvs->USER, LIB_MAX_CAPACITANCE, NULL);
386 *(float *)&pt->DATA=value;
387 cl=delchain(cl,cl);
388 }
389 }
390