1 /*
2 * This file is part of the Alliance CAD System
3 * Copyright (C) Laboratoire LIP6 - D�partement ASIM
4 * Universite Pierre et Marie Curie
5 *
6 * Home page : http://www-asim.lip6.fr/alliance/
7 * E-mail : mailto:alliance-users@asim.lip6.fr
8 *
9 * This progam is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version.
13 *
14 * Alliance VLSI CAD System is distributed in the hope that it will be
15 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
17 * Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with the GNU C Library; see the file COPYING. If not, write to the Free
21 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 */
23
24 /*
25 * Tool : LooN - format library cells
26 * Date : 2000
27 * Author : Francois Donnet
28 */
29
30
31 #include <stdlib.h>
32 #include <mut.h>
33 #include <abl.h>
34 #include <mlo.h>
35 #include <abe.h>
36 #include <mlu.h>
37 #include <abv.h>
38 #include "lon_lib_format.h"
39
40
41
42 /******************************************************************************/
43 /* return 1 if input is found in abl */
44 /******************************************************************************/
is_input_used(char * input,chain_list * abl)45 static int is_input_used(char* input, chain_list* abl)
46 {
47 if (!abl) return 0;
48
49 if (ABL_ATOM(abl)) {
50 char *value=ABL_ATOM_VALUE(abl);
51 /*constant*/
52 if (value==getablatomzero() || value==getablatomone()
53 || value==getablatomtristate() || value==getablatomdc()) return 0;
54 if (value==input) return 1;
55 return 0; /*not found*/
56 }
57
58 for (abl=ABL_CDR(abl); abl; abl=ABL_CDR(abl)) {
59 if (is_input_used(input,ABL_CAR(abl))) return 1;
60 }
61
62 return 0; /*not found*/
63 }
64
65
66 /******************************************************************************/
67 /* seek if all inputs are used in abl */
68 /******************************************************************************/
used_inputs(befig_list * befig)69 static int used_inputs(befig_list* befig)
70 {
71 bepor_list* bepor;
72 bereg_list *bereg;
73 beaux_list *beaux;
74 bebus_list *bebus;
75 bebux_list *bebux;
76 beout_list *beout;
77 biabl_list *biabl;
78
79
80 /*all inputs should be used*/
81 for (bepor=befig->BEPOR; bepor; bepor=bepor->NEXT) {
82 /*only input*/
83 if (bepor->DIRECTION!=IN && bepor->DIRECTION!=INOUT
84 && bepor->DIRECTION!=TRANSCV) continue;
85 if (!isvdd(bepor->NAME) && !isvss(bepor->NAME)) {
86
87 for ( beout = befig->BEOUT; beout; beout = beout->NEXT )
88 {
89 if ( is_input_used(bepor->NAME, beout->ABL) ) break;
90 }
91 if ( beout ) continue;
92
93 for ( beaux = befig->BEAUX; beaux; beaux = beaux->NEXT )
94 {
95 if ( is_input_used(bepor->NAME, beaux->ABL) ) break;
96 }
97 if ( beaux ) continue;
98
99 for ( bebux = befig->BEBUX; bebux; bebux = bebux->NEXT )
100 {
101 for ( biabl = bebux->BIABL; biabl; biabl = biabl->NEXT )
102 {
103 if ( is_input_used(bepor->NAME, biabl->CNDABL) ) break;
104 if ( is_input_used(bepor->NAME, biabl->VALABL) ) break;
105 }
106 if ( biabl ) break;
107 }
108 if ( bebux ) continue;
109
110 for ( bereg = befig->BEREG; bereg; bereg = bereg->NEXT )
111 {
112 for ( biabl = bereg->BIABL; biabl; biabl = biabl->NEXT )
113 {
114 if ( is_input_used(bepor->NAME, biabl->CNDABL) ) break;
115 if ( is_input_used(bepor->NAME, biabl->VALABL) ) break;
116 }
117 if ( biabl ) break;
118 }
119 if ( bereg ) continue;
120
121 for ( bebus = befig->BEBUS; bebus; bebus = bebus->NEXT )
122 {
123 for ( biabl = bebus->BIABL; biabl; biabl = biabl->NEXT )
124 {
125 if ( is_input_used(bepor->NAME, biabl->CNDABL) ) break;
126 if ( is_input_used(bepor->NAME, biabl->VALABL) ) break;
127 }
128 if ( biabl ) break;
129 }
130 if ( bebus ) continue;
131
132 fprintf(stderr,"BEH: %s input unused\n",bepor->NAME);
133 return 0;
134
135 }
136 }
137
138 return 1;/*all used*/
139 }
140
141
142 /******************************************************************************/
143 /******************************************************************************/
format_subst_abl(chain_list * abl,beaux_list * BeauxSubst)144 static chain_list* format_subst_abl( chain_list* abl, beaux_list *BeauxSubst )
145 {
146 chain_list *chain;
147
148 if (ABL_ATOM(abl)) {
149 char *value=ABL_ATOM_VALUE(abl);
150 if (value == BeauxSubst->NAME) return dupablexpr( BeauxSubst->ABL );
151 return abl;
152 }
153
154 for (chain=ABL_CDR(abl); chain; chain=ABL_CDR(chain)) {
155 ABL_CAR_L(chain) = format_subst_abl( ABL_CAR( chain ), BeauxSubst );
156 }
157
158 return abl;
159 }
160
161 /******************************************************************************/
162 /******************************************************************************/
format_subst_befig(befig_list * befig,beaux_list * BeauxSubst)163 static void format_subst_befig( befig_list *befig, beaux_list *BeauxSubst )
164 {
165 bereg_list *bereg;
166 beaux_list *beaux;
167 bebus_list *bebus;
168 bebux_list *bebux;
169 beout_list *beout;
170 biabl_list *biabl;
171
172 for ( beout = befig->BEOUT; beout; beout = beout->NEXT )
173 {
174 beout->ABL = format_subst_abl( beout->ABL, BeauxSubst );
175 }
176 for ( beaux = befig->BEAUX; beaux; beaux = beaux->NEXT )
177 {
178 if ( beaux == BeauxSubst ) continue;
179 beaux->ABL = format_subst_abl( beaux->ABL, BeauxSubst );
180 }
181 for ( bebux = befig->BEBUX; bebux; bebux = bebux->NEXT )
182 {
183 for ( biabl = bebux->BIABL; biabl; biabl = biabl->NEXT )
184 {
185 biabl->CNDABL = format_subst_abl( biabl->CNDABL, BeauxSubst );
186 biabl->VALABL = format_subst_abl( biabl->VALABL, BeauxSubst );
187 }
188 }
189 for ( bereg = befig->BEREG; bereg; bereg = bereg->NEXT )
190 {
191 for ( biabl = bereg->BIABL; biabl; biabl = biabl->NEXT )
192 {
193 biabl->CNDABL = format_subst_abl( biabl->CNDABL, BeauxSubst );
194 biabl->VALABL = format_subst_abl( biabl->VALABL, BeauxSubst );
195 }
196 }
197 for ( bebus = befig->BEBUS; bebus; bebus = bebus->NEXT )
198 {
199 for ( biabl = bebus->BIABL; biabl; biabl = biabl->NEXT )
200 {
201 biabl->CNDABL = format_subst_abl( biabl->CNDABL, BeauxSubst );
202 biabl->VALABL = format_subst_abl( biabl->VALABL, BeauxSubst );
203 }
204 }
205 }
206
207
208
209 /******************************************************************************/
210 /* return 1 if format is ok */
211 /******************************************************************************/
format_cell(befig_list * befig)212 extern int format_cell(befig_list* befig)
213 {
214 beaux_list *beaux;
215 biabl_list *biabl;
216
217 /*internal signal forbidden*/
218 for ( beaux = befig->BEAUX; beaux; beaux = beaux->NEXT )
219 {
220 format_subst_befig( befig, beaux );
221 }
222 befig->BEAUX = NULL;
223
224 if (befig->BEREG) {
225 /*only one register*/
226 if (befig->BEREG->NEXT || befig->BEBUS || befig->BEBUX) return 0;
227 #if 0 /*to accept multiple condition block*/
228 /*only one condition*/
229 if (!befig->BEREG->BIABL || befig->BEREG->BIABL->NEXT) return 0;
230 #endif
231 /*one ouput*/
232 if (!befig->BEOUT || befig->BEOUT->NEXT) return 0;
233 /* forbid logic on output */
234 if (!ABL_ATOM(befig->BEOUT->ABL)) {
235 chain_list* abl;
236 abl=befig->BEOUT->ABL;
237 if (ABL_OPER(abl)!=ABL_NOT) return 0;
238 abl=ABL_CADR(abl);
239 if (!ABL_ATOM(abl) || ABL_ATOM_VALUE(abl)!=befig->BEREG->NAME)return 0;
240 /* output <= not reg; -> move not to register value*/
241 freeablexpr(befig->BEOUT->ABL);
242 befig->BEOUT->ABL=createablatom(befig->BEREG->NAME);
243 for (biabl=befig->BEREG->BIABL; biabl; biabl=biabl->NEXT) {
244 biabl->VALABL=simpablexpr(createablnotexpr(biabl->VALABL));
245 }
246 }
247 }
248
249 if (befig->BEBUS) {
250 /*only one bus*/
251 if (befig->BEBUS->NEXT || befig->BEREG || befig->BEBUX) return 0;
252 /*only one condition*/
253 if (!befig->BEBUS->BIABL || befig->BEBUS->BIABL->NEXT) return 0;
254 /*one ouput: bebus*/
255 if (befig->BEOUT) return 0;
256 }
257
258 if (befig->BEBUX) {
259 /*only one internal bus*/
260 if (befig->BEBUX->NEXT || befig->BEREG || befig->BEBUS) return 0;
261 /*only one condition*/
262 if (!befig->BEBUX->BIABL || befig->BEBUX->BIABL->NEXT) return 0;
263 /*one ouput: beout*/
264 if (!befig->BEOUT || befig->BEOUT->NEXT) return 0;
265 /* forbid logic on output */
266 if (!ABL_ATOM(befig->BEOUT->ABL)) {
267 chain_list* abl;
268 abl=befig->BEOUT->ABL;
269 if (ABL_OPER(abl)!=ABL_NOT) return 0;
270 abl=ABL_CADR(abl);
271 if (!ABL_ATOM(abl) || ABL_ATOM_VALUE(abl)!=befig->BEBUX->NAME)return 0;
272 /* output <= not bus; */
273 freeablexpr(befig->BEOUT->ABL);
274 befig->BEOUT->ABL=createablatom(befig->BEBUX->NAME);
275 befig->BEBUX->BIABL->VALABL=simpablexpr(
276 createablnotexpr(befig->BEBUX->BIABL->VALABL));
277 }
278 /*normalize befig -> move bebux to bebus */
279 befig->BEBUS=beh_addbebus(befig->BEBUS,befig->BEOUT->NAME,
280 befig->BEBUX->BIABL,NULL,'M'/*mux_bit instead of wor_bit'W'*/);
281 befig->BEBUX->BIABL=NULL; /*protect from beh_frebebux()*/
282 beh_frebebux(befig->BEBUX);
283 freeablexpr(befig->BEOUT->ABL);
284 beh_frebeout(befig->BEOUT);
285 befig->BEBUX=NULL;
286 befig->BEOUT=NULL;
287 }
288
289 if (befig->BEOUT) {
290 /*one kind of ouput: beout*/
291 if ( befig->BEBUS ) return 0;
292 }
293
294 return used_inputs(befig);
295
296 /*illegal befig*/
297 return 0;
298 }
299
300
301 /******************************************************************************/
302 /*put the locon of the lofig associated to the befig */
303 /*in the same order than bepor */
304 /* return 0 if no error */
305 /******************************************************************************/
sortbepor(befig_list * befig)306 extern int sortbepor(befig_list* befig)
307 {
308 lofig_list* lofig;
309 bepor_list* bepor;
310 locon_list* locon, *pred;
311
312 lofig=getlofig(befig->NAME,'P');
313
314 for (bepor=befig->BEPOR; bepor; bepor=bepor->NEXT) {
315
316 pred=NULL;
317 for (locon=lofig->LOCON; locon; locon=locon->NEXT) {
318 if (bepor->NAME==locon->NAME) {
319 /*disconnect*/
320 if (pred) pred->NEXT=locon->NEXT;
321 else lofig->LOCON=locon->NEXT;
322 /*reconnect*/
323 locon->NEXT=lofig->LOCON;
324 lofig->LOCON=locon;
325 break;
326 }
327 pred=locon;
328 }
329
330 if (!locon) {
331 fprintf(stderr,
332 "BEH: mismatch with %s.al for cell %s.vbe on port %s\n",
333 befig->NAME, befig->NAME, bepor->NAME);
334 return 1;
335 }
336 }
337
338 lofig->LOCON=(locon_list*) reverse((chain_list*) lofig->LOCON);
339
340 return 0;
341 }
342
343
344
345