1 
2 // This file is part of the Alliance Project.
3 // Copyright (C) Laboratoire LIP6 - Departement ASIM
4 // Universite Pierre et Marie Curie
5 //
6 // The Alliance Project  is free software;  you can  redistribute it and/or
7 // modify  it  under the  terms  of  the  GNU  General  Public License  as
8 // published by  the Free  Software Foundation; either  version 2  of  the
9 // License, or (at your option) any later version.
10 //
11 // The Alliance Project  is distributed in the hope that it will be useful,
12 // but  WITHOUT  ANY  WARRANTY;  without  even  the  implied  warranty  of
13 // MERCHANTABILITY  or  FITNESS  FOR A  PARTICULAR PURPOSE.   See  the GNU
14 // General Public License for more details.
15 //
16 // You should have received a copy  of  the  GNU  General  Public  License
17 // along with  the Alliance Project;  if  not,  write to the  Free Software
18 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 //
20 //
21 // License-Tag
22 //
23 // Date   : 29/01/2004
24 // Author : Christophe Alexandre  <Christophe.Alexandre@lip6.fr>
25 //
26 // Authors-Tag
27 #include <stdio.h>
28 #include <iostream>
29 #include <ctype.h>
30 #include <string.h>
31 using namespace std;
32 
33 #include "mut.h"
34 #include "mph.h"
35 #include "mlo.h"
36 extern "C" {
37 #include "rds.h"
38 #include "rtl.h"
39 #include "rpr.h"
40 }
41 
42 #include "PPlacement.h"
43 
44 static void
Usage()45 Usage()
46 {
47     cerr << "usage: ocp [options] <netlist> <filename>" << endl
48          << "Options :"  << endl
49          << "o -help : display man page" << endl
50 	 << "o -v : verbose mode" << endl
51 	 << "o -gnuplot : create statistics files to use with gnuplot" << endl
52 	 << "o -c : create connectors (placement randomly generated)" << endl
53 	 << "o -ring : create connectors suitable for ring pad placement tool" << endl
54 	 << "          placement randomly generated unless -ioc is given" << endl
55 	 << "o -ioc : create connectors and place it using .ioc file" << endl
56          << "o -margin <MARGIN> : The amount of free area added " << endl
57 	 << "  in percentage of the cells area. " << endl
58 	 << "  The resulting area will be equal to " << endl
59 	 << "  CELL_AREA * (1 + <MARGIN>). Default value : 0.2" << endl
60 	 << "o -eqmargin : The margin is equitably distributed between all cells" << endl
61 	 << "  By default, we try to insert the maximum amount of 2-pitch tie cells" << endl
62 	 << "o -partial <PARTIAL> : " << endl
63 	 << "  The design is already partially placed (there must be a" << endl
64 	 << "  physical view describing this partial placement)." << endl
65 	 << "o -rows <NR> : the placement will have <NR> rows"<< endl
66 	 << "o -mdl <NL> : maximum loop of final optimisation "
67 	 << "default : <NL> = 2" << endl;
68 }
69 
70 static void
PrintEnv()71 PrintEnv()
72 {
73     char* allianceTop = mbkgetenv("ALLIANCE_TOP");
74     char* mbkInLo = mbkgetenv("MBK_IN_LO");
75     char* mbkOutLo = mbkgetenv("MBK_OUT_LO");
76     char* mbkInPh = mbkgetenv("MBK_IN_PH");
77     char* mbkOutPh = mbkgetenv("MBK_OUT_PH");
78     char* mbkVss = mbkgetenv("MBK_VSS");
79     char* mbkVdd = mbkgetenv("MBK_VDD");
80     char* mbkCatalName = mbkgetenv("MBK_CATAL_NAME");
81     char* mbkCataLib = mbkgetenv("MBK_CATA_LIB");
82     cout << "o ALLIANCE environment:" << endl;
83     if (allianceTop)
84 	cout << "  o ALLIANCE_TOP   : " << allianceTop << endl;
85     else
86 	cout << "  o Warning: no ALLIANCE_TOP variable set ...." << endl;
87     cout << "o MBK environment:" << endl;
88     if (mbkInLo)
89 	cout << "  o MBK_IN_LO      : " << mbkInLo << endl;
90     else
91 	cout << "  o Warning: no MBK_IN_LO variable set ...." << endl;
92     if (mbkOutLo)
93 	cout << "  o MBK_OUT_LO     : " << mbkOutLo << endl;
94     else
95 	cout << "  o Warning: no MBK_OUT_LO variable set ...." << endl;
96     if (mbkInPh)
97 	cout << "  o MBK_IN_PH      : " << mbkInPh << endl;
98     else
99 	cout << "  o Warning: no MBK_IN_PH variable set ...." << endl;
100     if (mbkOutPh)
101 	cout << "  o MBK_OUT_PH     : " << mbkOutPh << endl;
102     else
103 	cout << "  o Warning: no MBK_OUT_PH variable set ...." << endl;
104     if (mbkVss)
105 	cout << "  o MBK_VSS        : " << mbkVss << endl;
106     else
107 	cout << "  o Warning: no MBK_VSS variable set ...." << endl;
108     if (mbkVdd)
109 	cout << "  o MBK_VDD        : " << mbkVdd << endl;
110     else
111 	cout << "  o Warning: no MBK_VDD variable set ...." << endl;
112     if (mbkCatalName)
113 	cout << "  o MBK_CATAL_NAME : " << mbkCatalName << endl;
114     else
115 	cout << "  o Warning: no MBK_CATAL_NAME variable set ...." << endl;
116     if (mbkCataLib)
117     {
118 	cout << "  o MBK_CATA_LIB   : ";
119 	while (*mbkCataLib !=  '\0')
120 	{
121 	    while ((*mbkCataLib != '\0') && (*mbkCataLib !=  ':'))
122 	    {
123 		cout << *mbkCataLib++;
124 	    }
125 	    if (*mbkCataLib == ':')
126 	    {
127 		cout << endl << "                     ";
128 		++mbkCataLib;
129 	    }
130 	    else
131 		cout << endl;
132 	}
133     }
134     else
135 	cout << "  o Warning: no MBK_CATA_LIB variable set ...." << endl;
136     cout << endl;
137 }
138 
139 int
main(int argc,char ** argv)140 main(int argc, char **argv)
141 {
142     double		BBoxOccCostRatio	= 0.5;
143     double		Margin			= 0.2;
144     bool		marginflag		= false;
145     int			MaxDetLoop		= 2;
146     int			NbRows			= 0;
147     char		PartialFile[256]	;	 //.ap file
148     char		IocFile[256]		;	 //.ioc file
149     bool		RowFlg			= false;
150     bool		HelpFlg			= false; // display help
151     bool		UsageFlg		= false; // print usage
152     bool		PartialFlg		= false; // .ap file loaded
153     bool		PlotFlg			= false; // GnuPlot graphics
154     bool		ConFlg			= false; // Connectors
155     bool		RingFlg			= false; // Connectors
156     bool		IocFlg			= false; // file for Connectors
157     bool		VerboseFlg		= false; // verbose mode
158     bool		EqMarginFlg		= false; // don't try to maximise
159     							 // 2-pitch cells
160     double		NetMult			= 1.0 ;
161     double		BinMult			= 0 ;
162     double		RowMult			= 0 ;
163 
164     /* ###------------------------------------------------------### */
165     /* analyse the command line, set option flags and find the	    */
166     /* first file in the argument list				    */
167     /* ###------------------------------------------------------### */
168 
169     //mbkenv();
170     rdsenv();
171     loadrdsparam ();
172     mbkenv();
173 
174     alliancebanner ("OCP", VERSION, "Placer for Standards Cells", "2001", ALLIANCE_VERSION);
175 
176     if (argc < 2)
177     {
178 	Usage();
179 	exit(0);
180     }
181 
182     for (int i=1; i<argc; i++)
183     {
184 	if (!strcmp (argv[i], "-help"))
185 	{
186 	    HelpFlg = true;
187 	}
188 	else
189 	    if (!strcmp (argv[i], "-v"))
190 	    {
191 		if (i+2 < argc) VerboseFlg = true;
192 		else	      UsageFlg = true;
193 	    }
194 	    else
195 		if (!strcmp (argv[i], "-eqmargin"))
196 		{
197 		    if (i+2 < argc) EqMarginFlg = true;
198 		    else	      UsageFlg = true;
199 		}
200 		else
201 		    if (!strcmp (argv[i], "-gnuplot"))
202 		    {
203 			if (i+2 < argc) PlotFlg = true;
204 			else	      UsageFlg = true;
205 		    }
206 		    else
207 			if (!strcmp (argv[i], "-c"))
208 			{
209 			    if (i+2 < argc) ConFlg = true;
210 			    else	      UsageFlg = true;
211 			}
212 			else
213 			    if (!strcmp (argv[i], "-ring"))
214 			    {
215 				if (i+2 < argc) RingFlg = true;
216 				else UsageFlg = true;
217 			    }
218 			    else
219 				if (!strcmp (argv[i], "-r"))
220 				{
221 				    if (i+3 < argc)
222 				    {
223 					if (!sscanf(argv[i+1], "%22lg", &BBoxOccCostRatio))
224 					{
225 					    cout << "WARNING : invalid argument for -r" << endl;
226 					    UsageFlg = true;
227 					}
228 	      } else {
229 	    	cout << "WARNING : no file or argument given" << endl;
230 		UsageFlg = true;
231 	      }
232             }
233 
234 	    else
235 
236             if (!strcmp (argv[i], "-nbrmult")) {
237               if (i+5 < argc)
238               {
239         	if (!sscanf(argv[i+1], "%22lg", &NetMult))
240         	{
241             	  cout << "WARNING : invalid argument for -nbrmult" << endl;
242         	  UsageFlg = true;
243         	}
244         	if (!sscanf(argv[i+2], "%22lg", &RowMult))
245         	{
246             	  cout << "WARNING : invalid argument for -nbrmult" << endl;
247         	  UsageFlg = true;
248         	}
249         	if (!sscanf(argv[i+3], "%22lg", &BinMult))
250         	{
251             	  cout << "WARNING : invalid argument for -nbrmult" << endl;
252         	  UsageFlg = true;
253         	}
254               } else {
255             	cout << "WARNING : no file or argument given" << endl;
256         	UsageFlg = true;
257 
258               }
259             }
260 
261 	    else
262 
263 	    if (!strcmp (argv[i], "-margin")) {
264 	      if (i+3 < argc)
265 	      {
266                 if (!sscanf(argv[i+1], "%22lg", &Margin))
267 		{
268 	    	  cout << "WARNING : invalid argument for -margin" << endl;
269 		  UsageFlg = true;
270 		}
271 	      } else {
272 	    	cout << "WARNING : no file or argument given" << endl;
273 		UsageFlg = true;
274 	      }
275 	      marginflag = true;
276             }
277 
278 	    else
279 
280 	    if (!strcmp (argv[i], "-partial")) {
281 	      if (i+3 < argc)
282 	      {
283                 if (!sscanf(argv[i+1], "%255s", PartialFile))
284 		{
285 	    	  cout << "WARNING : invalid argument for -partial" << endl;
286 		  UsageFlg = true;
287 		}
288 		PartialFlg = true;
289 	      } else {
290 	        cout << "WARNING : no file or argument given" << endl;
291 		UsageFlg = true;
292 	      }
293             }
294 
295 	    else
296 
297 	    if (!strcmp (argv[i], "-ioc")) {
298 	      if (i+3 < argc)
299 	      {
300                 if (!sscanf(argv[i+1], "%255s", IocFile))
301 		{
302 	    	  cout << "WARNING : invalid argument for -partial" << endl;
303 		  UsageFlg = true;
304 		}
305 		IocFlg = true;
306 		strcat(IocFile,".ioc");
307 	      } else {
308 	        cout << "WARNING : no file or argument given" << endl;
309 		UsageFlg = true;
310 	      }
311             }
312 
313 	    else
314 
315 	    if (!strcmp (argv[i], "-mdl")) {
316 	      if (i+3 < argc)
317 	      {
318                 if (!sscanf(argv[i+1], "%11d", &MaxDetLoop))
319 		{
320 		  cout << "WARNING : invalid argument for -mdl" << endl;
321 		  UsageFlg = true;
322 		}
323 
324 	      } else {
325 		cout << "WARNING : no file or argument given" << endl;
326 		UsageFlg = true;
327 	      }
328             }
329 
330 	    else
331 
332 	    if (!strcmp (argv[i], "-rows")) {
333 	      if (i+3 < argc)
334 	      {
335 	        if (!sscanf(argv[i+1], "%11d", &NbRows))
336 		{
337 		  cout << "WARNING : invalid argument for -rows" << endl;
338 		  UsageFlg = true;
339 		}
340 		RowFlg = true;
341 	      } else {
342 		cout << "WARNING : no file or argument given" << endl;
343 		UsageFlg = true;
344 	      }
345             }
346 
347 	    else
348 
349 	    if (!strncmp (argv[i], "-", 1))
350 	    {
351 	      cout << "WARNING : unavailable option : " << argv[i] << endl;
352 	      UsageFlg = true;
353 	    }
354         }
355 
356     /* ###------------------------------------------------------### */
357     /*      cases of error in the command line:			    */
358     /*      - no argument					    */
359     /*      - argument unrecognized as an option		    */
360     /*      - number of files do not match:			    */
361     /* ###------------------------------------------------------### */
362 
363     if (HelpFlg == true) {
364       system("man ocp");
365       exit (0);
366     }
367 
368     if (argc < 3) {
369       Usage();
370       exit(1);
371     }
372 
373     if ( BBoxOccCostRatio < 0.0 || BBoxOccCostRatio > 1.0)
374         UsageFlg = true;
375 
376     if ( Margin < 0 )
377         UsageFlg = true;
378 
379     if ( Margin < 0.15 )
380     {
381       cerr << " o Ocp Warning : the value of margin: "
382 	   << Margin << " is very low... Try a value around 0.15 ..." << endl;
383     }
384 
385     if ( Margin > 3 )
386     {
387       cerr << " o Ocp Warning : the value of margin: "
388 	   << Margin << " cannot be respected..." << endl
389 	   << " o value forced to 0.4 !!" << endl;
390       Margin = 0.4;
391     }
392 
393     if ( marginflag && PartialFlg )
394     {
395 	cerr << " o Ocp Warning : the switch margin and partial are not coherent "
396 	     << "and should not be use together...." << endl
397 	     << " o In case of a preplacement the margin is determined"
398 	     << " by the value of the Abutment Box and the net netlist you give me." << endl
399 	     << " o In consequence the switch margin has no sense and is bypassed ...."
400 	     << endl;
401     }
402 
403     if (IocFlg && ConFlg)
404     {
405 	cerr << " o You cannot have a connectors placement file and ask "
406 	    << "for a automatic connectors placement at the same time ...." << endl
407 	    << " o Use either -ioc or -c" << endl;
408 	exit(1);
409     }
410 
411     if (UsageFlg) {
412         Usage();
413         exit (1);
414     }
415 
416     if (VerboseFlg)
417 	PrintEnv();
418 
419     // Initializations
420     // ***************
421 
422     struct lofig* fig = NULL;
423     fig = getlofig(argv[argc-2],'A');
424 
425     char *namefile = argv[argc-1];
426 
427     struct phfig* physicalfig = NULL;
428     if (PartialFlg) physicalfig = getphfig(PartialFile,'A');
429 
430     // On fait le placement
431     // ********************
432     PPlacement Placement(ConFlg, RingFlg, RowMult, BinMult, NetMult,
433 	IocFlg, IocFile, PlotFlg, VerboseFlg, PartialFlg, EqMarginFlg,
434 	physicalfig, namefile);
435     Placement.SetMargin(Margin);
436     Placement.SetMaxDetLoop(MaxDetLoop);
437     if (!RowFlg)
438 	NbRows = 0;
439     Placement.Place(fig, NbRows);
440 
441     // On sauve le resultat
442     // ********************
443     cout  << endl << "Ocp : placement finished" << endl;
444     if (Placement.GetBoolPlot())
445     {
446       Placement.PlotFinal("view");
447       Placement.PlotStat();
448       cout << "gnuplot files created - in order to use them, please type :"
449 	<< endl << "gnuplot afterglobal.gpl"
450 	<< endl << "gnuplot binsafterglobal.gpl"
451 	<< endl << "gnuplot init.gpl"
452 	<< endl << "gnuplot instances-init.gpl"
453 	<< endl << "gnuplot stat.gpl"
454 	<< endl << "gnuplot view.gpl" << endl;
455     }
456     int superr = Placement.Save();
457     dellofig(fig->NAME);
458 
459     return (superr);
460 }
461