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