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 <unistd.h>
28 #include <string.h>
29 #include <set>
30 #include <algorithm>
31 #include <string>
32 using namespace std;
33
34 #include "mut.h"
35 #include "mph.h"
36 #include "mpu.h"
37 #include "mlo.h"
38 #include "mlu.h"
39
40 #include "iocheader.h"
41 #include "PMove.h"
42 #include "PConstants.h"
43 #include "PCommon.h"
44 #include "PPlacement.h"
45
46 struct CompPInsByWidth {
operator ()CompPInsByWidth47 bool operator()(PIns* Ins1, PIns* Ins2) {
48 return (Ins1->GetWidth() > Ins2->GetWidth());
49 }
50 };
51
~PPlacement()52 PPlacement::~PPlacement()
53 {
54 if (_verbose)
55 {
56 cout << " o Destruction of DATABASE ...." << endl;
57 }
58
59 for (PFixedInss::iterator fit = _fixedInss.begin();
60 fit != _fixedInss.end();
61 fit++)
62 {
63 delete *fit;
64 }
65
66 for (PToPlaceInss::iterator toit = _toPlaceInss.begin();
67 toit != _toPlaceInss.end();
68 toit++)
69 {
70 delete *toit;
71 }
72
73 for (PCons::iterator cit = _cons.begin();
74 cit != _cons.end();
75 cit++)
76 {
77 delete *cit;
78 }
79
80 for (PONets::iterator nit = _nets.begin();
81 nit != _nets.end();
82 nit++)
83 {
84 delete *nit;
85 }
86
87 for (PRows::iterator rit = _rows.begin();
88 rit != _rows.end();
89 rit++)
90 {
91 delete *rit;
92 }
93
94 for (PDetSubRows::iterator srit = _detSubRows.begin();
95 srit != _detSubRows.end();
96 srit++)
97 {
98 delete *srit;
99 }
100 }
101
102 void
Init(lofig * fig,int NbRows)103 PPlacement::Init(lofig* fig, int NbRows)
104 {
105 rflattenlofig(fig, YES, YES);
106 lofigchain(fig);
107 _fig = fig;
108 _dx = _dy = 0;
109 // construction des tables
110 PNetMap pnetmap;
111 PInsMap pinsmap;
112 PConMap pconmap;
113 PFixedMap fixedmap;
114 PLoconMap ploconmap;
115
116 if (_prePlace)
117 {
118 rflattenphfig(_prePlaceFig, YES, YES);
119 for (phins* pins = _prePlaceFig->PHINS; pins; pins = pins->NEXT)
120 {
121 fixedmap[pins->INSNAME] = 1;
122 }
123
124 _dx = _prePlaceFig->XAB1;
125 _dy = _prePlaceFig->YAB1;
126
127 for (phins* pins = _prePlaceFig->PHINS; pins; pins = pins->NEXT)
128 {
129 // on elimine les tie et rowend
130 // qui peuvent etre dans la figure physique sans etre
131 // dans la figure logique ....
132 if (IsTie(pins))
133 {
134 continue;
135 }
136 // on verifie que la loins existe en memoire
137 loins* ins = getloins(_fig, pins->INSNAME);
138 // verification de la coherence figure logique / figure physique
139 if (ins->FIGNAME != pins->FIGNAME)
140 {
141 cerr << " o ERROR: The logical figure and the physical figure are not coherent:" << endl
142 << " Logical Instance: " << ins->INSNAME << " -> logical model: "<< ins->FIGNAME << endl
143 << " Physical Instance: " << pins->INSNAME << " -> physical model: "<< pins->FIGNAME << endl;
144 exit(1);
145 }
146 PFixedIns* fixedins = InsertFixedIns(ins, pins, _dx, _dy);
147 pinsmap[ins->INSNAME] = fixedins;
148 }
149
150 if (_prePlaceFig->PHCON &&
151 (_placeCons || _ringPlaceCons || _iocFile))
152 {
153 cerr << " o ERROR: impossible to have simultaneously preplaced connectors" << endl
154 << " and automatically placed connectors" << endl;
155 exit(1);
156
157 }
158
159 for (phcon* pcon = _prePlaceFig->PHCON; pcon; pcon = pcon->NEXT)
160 {
161 locon* lCon = getlocon(_fig, pcon->NAME);
162 //generates an error if no locon
163 PCon* pCon = InsertCon(lCon, pcon, _dx, _dy);
164 pconmap[pcon->NAME] = pCon;
165 }
166 }
167
168
169 for (loins* ins = fig->LOINS; ins; ins = ins->NEXT)
170 {
171 PFixedMap::iterator fit = fixedmap.find(ins->INSNAME);
172 if (fit == fixedmap.end())
173 {
174 // on evite de compter deux fois le meme net pour
175 // chaque instance.....
176 phfig* phmodel = getphfig(ins->FIGNAME, '0');
177 int height = (int)((double)(phmodel->YAB2 - phmodel->YAB1) / PITCH + 0.5);
178 if (height != ROWHEIGHT)
179 {
180 cerr << " o ERROR : All cells must have the same height: i cannot place the instance: "
181 << ins->INSNAME << endl;
182 exit(1);
183 }
184 PToPlaceIns* toplaceins = InsertToPlaceIns(ins);
185 pinsmap[ins->INSNAME] = toplaceins;
186 }
187 }
188 _nInsToPlace = _toPlaceInss.size();
189
190 // Traitement des connecteurs ....
191 if (_placeCons || (_ringPlaceCons && !_iocFile))
192 {
193 for (locon* con = fig->LOCON; con; con = con->NEXT)
194 {
195 losig* sig = con->SIG;
196 if (!IsSpecialNet(sig))
197 {
198 PCon* pcon = InsertCon(con);
199 pconmap[con->NAME] = pcon;
200 }
201 }
202 }
203
204 for (locon* con = fig->LOCON; con; con = con->NEXT)
205 ploconmap[con->NAME] = con;
206
207 // traitement de l'emplacement des connecteurs
208 // creation des PCon si fichier ioc
209 if (_iocFile)
210 {
211 ParseIocFile(ploconmap);
212 for (PCons::iterator pcon = _cons.begin() ; pcon != _cons.end(); pcon++)
213 pconmap[(*pcon)->GetLocon()->NAME] = *pcon;
214 }
215
216 for (losig* sig = fig->LOSIG; sig; sig = sig->NEXT)
217 {
218 if (!IsSpecialNet(sig))
219 {
220 set<loins*> siginsset;
221 int totreatinscpt = 0;
222 int elemcpt = 0;
223 for (chain_list* it = (chain_list *)(getptype(sig->USER, (long)LOFIGCHAIN)->DATA);
224 it;
225 it = it->NEXT)
226 {
227 locon_list* con = (locon_list*)(it->DATA);
228 if (con->TYPE == EXTERNAL) {
229 if ( (_prePlaceFig && _prePlaceFig->PHCON)
230 || _placeCons || _ringPlaceCons || _iocFile) {
231 PConMap::iterator cit = pconmap.find(con->NAME);
232 if (cit != pconmap.end()) {
233 ++totreatinscpt;
234 }
235 }
236 }
237 else
238 {
239 loins* ins = (loins*)(con->ROOT);
240 set<loins*>::iterator liit = siginsset.find(ins);
241 if (liit == siginsset.end())
242 {
243 ++totreatinscpt;
244 siginsset.insert(ins);
245 }
246 }
247 ++elemcpt;
248 }
249 if (elemcpt < 2)
250 {
251 cerr << " o OCP Warning: strange net detected ...: " << endl;
252 cerr << " o Net:" << endl;
253 cerr << " o ";
254 PrintLosig(cerr, sig);
255 if (elemcpt == 0)
256 cerr << " o is not connected ......" << endl;
257 if (elemcpt == 1)
258 {
259 cerr << " o is connected to only one element: ";
260 chain_list* it = (chain_list *)(getptype(sig->USER, (long)LOFIGCHAIN)->DATA);
261 locon_list* con = (locon_list*)(it->DATA);
262 if (con->TYPE == EXTERNAL)
263 {
264 cerr << "connector " << con->NAME;
265 }
266 else
267 {
268 loins* ins = (loins*)(con->ROOT);
269 cerr << "instance " << ins->INSNAME;
270 }
271 cerr << endl;
272 }
273
274 }
275
276 PONet* net = InsertNet(sig);
277 pnetmap[sig->INDEX] = net;
278 }
279 else {
280 cerr << " o Special Net detected : " << getsigname(sig) << endl;
281 }
282 }
283
284
285 for (loins* ins = fig->LOINS ; ins ; ins = ins->NEXT)
286 {
287 set<losig*> inssigset;
288 PInsMap::iterator iit = pinsmap.find(ins->INSNAME);
289 if (iit == pinsmap.end())
290 {
291 cerr << "ins " << ins->INSNAME << " is not present in data...." << endl;
292 exit(1);
293 }
294 PElem::PNets& netvector = iit->second->GetNets();
295 for (locon* con = ins->LOCON ; con ; con = con->NEXT)
296 {
297 losig* sig = con->SIG;
298 set<losig*>::iterator lsit = inssigset.find(sig);
299 if (lsit == inssigset.end())
300 {
301 if (!IsSpecialNet(sig))
302 {
303 PNetMap::iterator nit = pnetmap.find(sig->INDEX);
304 if (nit == pnetmap.end())
305 {
306 cerr << "net " << sig->INDEX << " is not present in data...." << endl;
307 exit(1);
308 }
309 netvector.push_back(nit->second);
310 inssigset.insert(sig);
311 }
312 }
313 }
314 }
315
316 if ( (_prePlaceFig && _prePlaceFig->PHCON)
317 || _placeCons || _ringPlaceCons || _iocFile)
318 {
319 for (locon* con = fig->LOCON; con; con = con->NEXT)
320 {
321 losig* sig = con->SIG;
322 if (!IsSpecialNet(sig))
323 {
324 PConMap::iterator cit = pconmap.find(con->NAME);
325 if (cit != pconmap.end())
326 {
327 PElem::PNets& netvector = cit->second->GetNets();
328 PNetMap::iterator nit = pnetmap.find(sig->INDEX);
329 if (nit == pnetmap.end())
330 {
331 cerr << "net " << sig->INDEX
332 << " is not present in data...." << endl;
333 exit(1);
334 }
335 netvector.push_back(nit->second);
336 }
337 }
338 }
339 }
340
341 for (losig* sig = fig->LOSIG ; sig ; sig=sig->NEXT)
342 {
343 set<loins*> siginsset;
344 if (!IsSpecialNet(sig))
345 {
346 PNetMap::iterator nit = pnetmap.find(sig->INDEX);
347 if (nit == pnetmap.end())
348 {
349 cerr << "net " << sig->INDEX << " is not present in data...." << endl;
350 exit(1);
351 }
352 PNet::PElems& elemsvector = nit->second->GetElems();
353 for (chain_list* it = (chain_list *)(getptype(sig->USER, (long)LOFIGCHAIN)->DATA);
354 it;
355 it = it->NEXT)
356 {
357 locon_list* con = (locon_list*)(it->DATA);
358 if (con->TYPE == INTERNAL)
359 {
360 loins* ins = (loins*)(con->ROOT);
361 set<loins*>::iterator liit = siginsset.find(ins);
362 if (liit == siginsset.end())
363 {
364 PInsMap::iterator iit = pinsmap.find(ins->INSNAME);
365 if (iit == pinsmap.end())
366 {
367 cerr << "ins " << ins->INSNAME << " is not present in data...." << endl;
368 exit(1);
369 }
370 elemsvector.push_back(iit->second);
371 siginsset.insert(ins);
372 }
373 }
374 else if ( (_prePlaceFig && _prePlaceFig->PHCON)
375 || _placeCons || _ringPlaceCons || _iocFile)
376 {
377
378 PConMap::iterator cit = pconmap.find(con->NAME);
379 if (cit != pconmap.end())
380 {
381 elemsvector.push_back(cit->second);
382 }
383 }
384
385 }
386 }
387
388 }
389
390 if (_verbose)
391 {
392 cout << " o Number total of instances is .... " << _fixedInss.size()+ _toPlaceInss.size() << endl;
393 cout << " o Number of instances to place is .... " << _toPlaceInss.size() << endl;
394 cout << " o Number of instances already placed is .... " << _fixedInss.size() << endl;
395 cout << " o Number of nets is .... " << _nets.size() << endl;
396 }
397
398 // getting NetList Caracteristics
399
400 _sumToPlaceInssWidth = 0.0;
401 _biggestToPlaceInsWidth = 0.0;
402 double inswidth = 0.0;
403 for (PToPlaceInss::const_iterator ins_it = _toPlaceInss.begin();
404 ins_it != _toPlaceInss.end(); ins_it++)
405 {
406 if (_biggestToPlaceInsWidth < (inswidth = (*ins_it)->GetWidth()))
407 _biggestToPlaceInsWidth = inswidth;
408 _sumToPlaceInssWidth += inswidth;
409 }
410
411 if (_verbose)
412 {
413 cout << " o Sum of instances to place widths is ... " << _sumToPlaceInssWidth << endl;
414 }
415
416 _binsMaxWidth = (double)(int)(2.0 * _biggestToPlaceInsWidth * (1.0 + _margin) + 0.5);
417 _binsMinWidth = (double)(int)(_binsMaxWidth / 2);
418
419 if (_prePlace)
420 {
421 InitPlaceWithPrePlace();
422 if (_nInsToPlace > 0)
423 {
424 if (_rows.begin() == _rows.end())
425 {
426 cout << " o ERROR: No SPACE to place instances ....." << endl;
427 exit(1);
428 }
429 }
430 }
431 else
432 if (_nInsToPlace > 0)
433 InitPlace(NbRows);
434
435 // set positions of connectors in case of no ioc file
436 if (_placeCons && !_ringPlaceCons) GenerateConsPlacement();
437
438 if (_ringPlaceCons && !_iocFile) GenerateRingConsPlacement();
439
440 // set positions of connectors when ioc file is given
441 if (_iocFile) SetPosIocFile(pconmap);
442
443 if (_nInsToPlace==0)
444 return;
445
446 // sorting instances by their Width (biggest -> smallest)
447 vector<PToPlaceIns*> ClassedInss;
448 ClassedInss.reserve(_nInsToPlace);
449 for (PToPlaceInss::iterator ifirst = _toPlaceInss.begin(); ifirst != _toPlaceInss.end(); ifirst++)
450 {
451 PToPlaceIns* InsPt;
452 ClassedInss.push_back(InsPt);
453 ClassedInss.back() = *ifirst;
454 }
455 sort(ClassedInss.begin(), ClassedInss.end(), CompPInsByWidth());
456
457 // Insertion of instances on rows
458 vector<PToPlaceIns*>::iterator iptfirst = ClassedInss.begin();
459 PRows::iterator rfirst = _rows.begin();
460 PRow::PSubRows::iterator subrfirst = (*rfirst)->GetSubRows().begin();
461
462 PIns* InsInserting = *iptfirst;
463 while(1)
464 {
465 int NbOfBins;
466 int BinNumber;
467
468 if (iptfirst == ClassedInss.end())
469 {
470 if (_verbose) cout << " o Initial Placement Computing ... done. " << endl;
471 break;
472 // end of insertion
473 }
474
475 if (subrfirst == (*rfirst)->GetSubRows().end()
476 && (++rfirst != _rows.end()))
477 {
478 subrfirst = (*rfirst)->GetSubRows().begin();
479 }
480
481 if (rfirst == _rows.end())
482 {
483 if (InsInserting != *iptfirst)
484 {
485 InsInserting = *iptfirst;
486 rfirst = _rows.begin();
487 subrfirst = (*rfirst)->GetSubRows().begin();
488 }
489 else
490 {
491 // insertion of instances with respect of Bins margin
492 // did not succed, inserting what's left.
493 rfirst = _rows.begin();
494 subrfirst = (*rfirst)->GetSubRows().begin();
495 NbOfBins = (*subrfirst)->GetNBins();
496 BinNumber = 0;
497 while (iptfirst != ClassedInss.end())
498 {
499 if ((*iptfirst)->GetWidth() <=
500 (*subrfirst)->GetWidth() - (*subrfirst)->GetSize())
501 {
502 (*subrfirst)->ForceIns(**(iptfirst++), BinNumber++);
503 }
504 else
505 BinNumber++;
506 if (BinNumber >= NbOfBins)
507 {
508 subrfirst++;
509 BinNumber = 0;
510 if (subrfirst != (*rfirst)->GetSubRows().end())
511 NbOfBins = (*subrfirst)->GetNBins();
512 }
513
514 if (subrfirst == (*rfirst)->GetSubRows().end()
515 && (++rfirst != _rows.end()))
516 {
517 subrfirst = (*rfirst)->GetSubRows().begin();
518 NbOfBins = (*subrfirst)->GetNBins();
519 }
520
521 if (rfirst == _rows.end())
522 {
523 if (InsInserting == *iptfirst)
524 {
525 // impossible to succed
526 cerr << " o The is no enough free space, I need a bigger abutment box ......" << endl;
527 cerr << " o There are still "
528 << ClassedInss.end() - iptfirst
529 << " Instances to place ..." << endl;
530 exit(1);
531 }
532 rfirst = _rows.begin();
533 subrfirst = (*rfirst)->GetSubRows().begin();
534 NbOfBins = (*subrfirst)->GetNBins();
535 BinNumber = 0;
536 InsInserting = *iptfirst;
537 }
538 }
539 }
540 }
541 NbOfBins = (*subrfirst)->GetNBins();
542 BinNumber = 0;
543 while ((iptfirst != ClassedInss.end())
544 && (BinNumber < NbOfBins)
545 && ((*iptfirst)->GetWidth() <= (*subrfirst)->GetCapa() - (*subrfirst)->GetSize()))
546 {
547 if ((*subrfirst)->InsertIns(**iptfirst, BinNumber++))
548 {
549 iptfirst++;
550 }
551 }
552 subrfirst++;
553 }
554
555 }
556
557 // ======================================================================
558 // void SetPosIocFile(PConMap& pconmap)
559 // ======================================================================
560 void
SetPosIocFile(PConMap & pconmap)561 PPlacement::SetPosIocFile(PConMap& pconmap)
562 {
563 int topcount = 0;
564 int bottomcount = 0;
565 int rightcount = 0;
566 int leftcount = 0;
567 int topspace = 0;
568 int bottomspace = 0;
569 int rightspace = 0;
570 int leftspace = 0;
571 int nbspacetop = 0;
572 int nbspacebottom = 0;
573 int nbspaceright = 0;
574 int nbspaceleft = 0;
575
576 con_list* pttop = NULL;
577 con_list* ptbottom = NULL;
578 con_list* ptright = NULL;
579 con_list* ptleft = NULL;
580
581 PPos position;
582
583 int Width = (int)(BBox.GetMaxX() - BBox.GetMinX());
584 int Height = (int)(BBox.GetMaxY() - BBox.GetMinY());
585 if (_verbose) cout << " o Width of the abutment box : " << Width << endl
586 << " o Height of the abutment box : " << Height << endl;
587
588 con_list* tmpnext;
589
590 for(con_list* tmpcon = _PtList ; tmpcon; tmpcon = tmpnext)
591 {
592 tmpnext = tmpcon->NEXT;
593 switch (tmpcon->ORIENT)
594 {
595 case 'T' : tmpcon->NEXT = pttop;
596 pttop = tmpcon;
597 if (strcmp(tmpcon->NAME,"SPACE")==0)
598 {
599 topspace += tmpcon->VALUE;
600 nbspacetop++;
601 } else topcount++;
602 break;
603
604 case 'B' : tmpcon->NEXT = ptbottom;
605 ptbottom = tmpcon;
606 if (strcmp(tmpcon->NAME,"SPACE")==0)
607 {
608 bottomspace += tmpcon->VALUE;
609 nbspacebottom++;
610 } else bottomcount++;
611 break;
612
613 case 'R' : tmpcon->NEXT = ptright;
614 ptright = tmpcon;
615 if (strcmp(tmpcon->NAME,"SPACE")==0)
616 {
617 rightspace += tmpcon->VALUE;
618 nbspaceright++;
619 } else rightcount++;
620 break;
621
622 case 'L' : tmpcon->NEXT = ptleft;
623 ptleft = tmpcon;
624 if (strcmp(tmpcon->NAME,"SPACE")==0)
625 {
626 leftspace += tmpcon->VALUE;
627 nbspaceleft++;
628 } else leftcount++;
629 break;
630 }
631 }
632
633 if (topcount != 0)
634 {
635 double pos = 0.0;
636 if (topspace >= Width-topcount)
637 {
638 cerr << " o ERROR : in ioc file : space too important" << endl;
639 exit(1);
640 }
641 double conspace = ((double)(Width-topspace)/(double)(topcount-nbspacetop));
642 pos += conspace / 2.0;
643
644 if (_verbose)
645 cout << " o conspace : " << conspace
646 << " 1st connector : " << pos << endl;
647
648 for(con_list* tmpcon = pttop ; tmpcon; tmpcon = tmpcon->NEXT)
649 {
650 if (strcmp(tmpcon->NAME,"SPACE") == 0)
651 {
652 pos += (double)tmpcon->VALUE;
653 pos -= conspace;
654 }
655 else
656 {
657 if (_verbose) cout << " o adding connector : " << tmpcon->NAME
658 << " x : " << (int)pos << " y : " << Height << endl;
659 position.SetX((double)(int)pos);
660 position.SetY(Height);
661 // test a rajouter pour verifier si locon present ou pas!!!
662 pconmap[tmpcon->NAME]->SetPos(position);
663 pos += conspace;
664 }
665 }
666 }
667
668 if (bottomcount != 0)
669 {
670 double pos = 0.0;
671 if (bottomspace >= Width-topcount)
672 {
673 cerr << " o ERROR : in ioc file : space too important" << endl;
674 exit(1);
675 }
676 double conspace = ((double)(Width-bottomspace)/
677 (double)(bottomcount-nbspacebottom));
678 pos += conspace / 2.0;
679
680 if (_verbose) cout << " o conspace : " << conspace << " 1st connector : " << pos << endl;
681
682 for(con_list* tmpcon = ptbottom ; tmpcon; tmpcon = tmpcon->NEXT)
683 {
684 if (strcmp(tmpcon->NAME,"SPACE") == 0)
685 {
686 pos += (double)tmpcon->VALUE;
687 pos -= conspace;
688 }
689 else
690 {
691 if (_verbose) cout << " o adding connector : " << tmpcon->NAME
692 << " x : " << (int)pos << " y : " << 0 << endl;
693 position.SetX((double)(int)pos);
694 position.SetY(0.0);
695 // test a rajouter pour verifier si locon present ou pas!!!
696 pconmap[tmpcon->NAME]->SetPos(position);
697 pos += conspace;
698 }
699 }
700 }
701
702 if (leftcount != 0)
703 {
704 double pos = 0.0, ppos = pos;
705 if (leftspace >= Width-topcount)
706 {
707 cerr << " o ERROR : in ioc file : space too important" << endl;
708 exit(1);
709 }
710 double conspace = ((double)(Height-leftspace)/
711 (double)(leftcount-nbspaceleft));
712 if (_ringPlaceCons) ppos = pos;
713 pos += conspace / 2.0;
714
715 for(con_list* tmpcon = ptleft ; tmpcon; tmpcon = tmpcon->NEXT)
716 {
717 if (strcmp(tmpcon->NAME,"SPACE") == 0)
718 {
719 pos += (double)tmpcon->VALUE;
720 pos -= conspace;
721 }
722 else
723 {
724 if (_ringPlaceCons)
725 {
726 int delta = (int)pos % ROWHEIGHT;
727 if (delta == 0) pos -= 2.0;
728 else if (delta == 1) pos += 1.0;
729 else if (delta == 9) pos -= 1.0;
730 // Just in case there are so many connectors
731 if (pos < ppos) pos = ppos + 1;
732 }
733
734 if (_verbose) cout << " o adding connector : " << tmpcon->NAME
735 << " x : " << 0 << " y : " << (int)pos << endl;
736 position.SetX(0.0);
737 position.SetY((double)(int)pos);
738 // test a rajouter pour verifier si locon present ou pas!!!
739 pconmap[tmpcon->NAME]->SetPos(position);
740 if (_ringPlaceCons) ppos = pos;
741 pos += conspace;
742 }
743 }
744 }
745
746 if (rightcount != 0)
747 {
748 double pos = 0.0, ppos = pos;
749 if (rightspace >= Width-topcount)
750 {
751 cerr << " o ERROR : in ioc file : space too important" << endl;
752 exit(1);
753 }
754 double conspace = ((double)(Height-rightspace)/
755 (double)(rightcount-nbspaceright));
756 if (_ringPlaceCons) ppos = pos;
757 pos += conspace / 2.0;
758
759 for(con_list* tmpcon = ptright ; tmpcon; tmpcon = tmpcon->NEXT)
760 {
761 if (strcmp(tmpcon->NAME,"SPACE") == 0)
762 {
763 pos += (double)tmpcon->VALUE;
764 pos -= conspace;
765 }
766 else
767 {
768 if (_ringPlaceCons)
769 {
770 int delta = (int)pos % ROWHEIGHT;
771 if (delta == 0) pos -= 2.0;
772 else if (delta == 1) pos += 1.0;
773 else if (delta == 9) pos -= 1.0;
774 // Just in case there are so many connectors
775 if (pos < ppos) pos = ppos + 1;
776 }
777
778 if (_verbose) cout << " o adding connector: " << tmpcon->NAME
779 << " x : " << Width << " y : " << (int)pos << endl;
780 position.SetX(Width);
781 position.SetY((double)(int)pos);
782 // test a rajouter pour verifier si locon present ou pas!!!
783 pconmap[tmpcon->NAME]->SetPos(position);
784 if (_ringPlaceCons) ppos = pos;
785 pos += conspace;
786 }
787 }
788 }
789 }
790 // ======================================================================
791 // void ParseIocFile(PLoconMap& ploconmap)
792 // ======================================================================
793
794 void
ParseIocFile(PLoconMap & ploconmap)795 PPlacement::ParseIocFile(PLoconMap& ploconmap)
796 {
797 PPos position;
798
799 _PtList = iocparse(_iocFileName);
800
801 char orientation;
802
803 for(con_list* tmpcon = _PtList ; tmpcon ; tmpcon = tmpcon->NEXT)
804 {
805 if (strcmp(tmpcon->NAME,"SPACE") != 0)
806 {
807 if (ploconmap.find(tmpcon->NAME) == ploconmap.end())
808 {
809 cerr << " o Error in ioc file ...." << endl
810 << " The connector " << tmpcon->NAME
811 << " doesn't exist in your figure ...."
812 << endl;
813 exit(1);
814 }
815 switch (tmpcon->ORIENT)
816 {
817 case 'T':
818 orientation = NORTH;
819 break;
820 case 'B':
821 orientation = SOUTH;
822 break;
823 case 'L':
824 orientation = WEST;
825 break;
826 case 'R':
827 orientation = EAST;
828 break;
829 default:
830 cerr << "Unknown Orientation for connector: "
831 << tmpcon->NAME << endl;
832 exit(1);
833 }
834 position.SetX(0);
835 position.SetY(0);
836 InsertCon(ploconmap[tmpcon->NAME], position, orientation);
837 }
838 }
839 }
840
841 // ======================================================================
842 // void Place(lofig* fig, int NbRows);
843 // ======================================================================
844 void
Place(lofig * fig,int NbRows)845 PPlacement::Place(lofig* fig, int NbRows)
846 {
847 Init(fig, NbRows);
848 if (_boolPlot)
849 {
850 PlotOnlyInstances("instances-init");
851 PlotAll("init");
852 }
853 if (_nInsToPlace > 0)
854 {
855 PlaceGlobal();
856 if (_boolPlot)
857 {
858 PlotAll("afterglobal");
859 PlotOnlyBins("binsafterglobal");
860 }
861 PlaceFinal();
862 }
863 }
864
865 PFixedIns*
InsertFixedIns(const loins * ins,const phins * pins,const int dx,const int dy)866 PPlacement::InsertFixedIns(const loins* ins, const phins* pins, const int dx, const int dy)
867 {
868 PFixedIns* fixedins = new PFixedIns(ins, pins, dx, dy);
869 _fixedInss.push_back(fixedins);
870 return fixedins;
871 }
872
873 PToPlaceIns*
InsertToPlaceIns(const loins * ins)874 PPlacement::InsertToPlaceIns(const loins* ins)
875 {
876 PToPlaceIns* toplaceins = new PToPlaceIns(ins);
877 _toPlaceInss.push_back(toplaceins);
878 return toplaceins;
879 }
880
881 PCon*
InsertCon(const locon * con,phcon * phycon,int dx,int dy)882 PPlacement::InsertCon(const locon* con, phcon* phycon, int dx, int dy)
883 {
884 PCon* pcon = new PCon(con, phycon);
885 _cons.push_back(pcon);
886 return pcon;
887 }
888
889 PCon*
InsertCon(const locon * con,PPos position,const char orientation)890 PPlacement::InsertCon(const locon* con, PPos position, const char orientation)
891 {
892 PCon* pcon = new PCon(con, position, orientation);
893 _cons.push_back(pcon);
894 return pcon;
895 }
896
897 PONet*
InsertNet(const losig * sig)898 PPlacement::InsertNet(const losig* sig)
899 {
900 PONet* net = new PONet(sig);
901 _nets.push_back(net);
902 return net;
903 }
904
905 ostream&
Print(ostream & os) const906 PPlacement::Print(ostream& os) const
907 {
908 PToPlaceInss::const_iterator ifirst = _toPlaceInss.begin();
909 PToPlaceInss::const_iterator ilast = _toPlaceInss.end();
910 while (ifirst != ilast) {
911 const PToPlaceIns& ins = **ifirst++;
912 os << " + ins: " << ins << endl;
913 PIns::PNets::const_iterator first = ins.GetConstNets().begin();
914 PIns::PNets::const_iterator last = ins.GetConstNets().end();
915 while (first != last)
916 os << " - net: " << *first++ << endl;
917 }
918
919 PONets::const_iterator nfirst = _nets.begin();
920 PONets::const_iterator nlast = _nets.end();
921 while (nfirst != nlast) {
922 const PNet& net = **nfirst++;
923 os << " + net: " << net << endl;
924 PNet::PElems::const_iterator first = net.GetConstElems().begin();
925 PNet::PElems::const_iterator last = net.GetConstElems().end();
926 while (first != last)
927 os << " - ins: " << *first++ << endl;
928 }
929
930 return os;
931 }
932
933 // ======================================================================
934 // void PlotInstances(ofstream& out) const
935 // ======================================================================
936 void
PlotInstances(ofstream & out) const937 PPlacement::PlotInstances(ofstream& out) const
938 {
939
940 out << "#rows" << endl;
941 for (PRows::const_iterator rit=_rows.begin(); rit!=_rows.end(); rit++)
942 {
943 (*rit)->Plot(out);
944 }
945 out << "EOF" << endl;
946 out << "#to place instances" << endl;
947 for (PToPlaceInss::const_iterator insit = _toPlaceInss.begin();
948 insit != _toPlaceInss.end(); insit++)
949 {
950 (*insit)->Plot(out);
951 }
952 out << "EOF" << endl;
953 out << "#preplaced instances" << endl;
954 for (PFixedInss::const_iterator insit = _fixedInss.begin();
955 insit != _fixedInss.end(); insit++)
956 {
957 (*insit)->Plot(out);
958 }
959 out << "EOF" << endl;
960 }
961 // ======================================================================
962 // void PlotAll(char *output) const
963 // ======================================================================
964 void
PlotAll(const string & output) const965 PPlacement::PlotAll(const string& output) const
966 {
967 string name = output + ".gpl";
968 ofstream out(name.c_str());
969
970 out << "set noxtics\nset noytics\n"
971 << "set noborder\nset nokey\nset title '" << _fig->NAME << "'\n"
972 << "#set terminal postscript eps color solid\n#set output '"
973 << output << ".ps'\n"
974 << "set xrange[" << GetMinX() << ":" << GetMaxX() << "]\n"
975 << "set yrange[" << GetMinY() << ":" << GetMaxY() << "]\n"
976 << "plot [:][:][:][:] '-' w l, '-' w l 2, '-' w l 3, '-' w l 4\n"
977 << GetMinX() << " " << GetMinY() << endl
978 << GetMinX() << " " << GetMaxY() << endl
979 << GetMaxX() << " " << GetMaxY() << endl
980 << GetMaxX() << " " << GetMinY() << endl
981 << GetMinX() << " " << GetMinY() << endl << endl;
982
983 PlotInstances(out);
984
985 out << "#nets" << endl;
986 for (PONets::const_iterator nit=_nets.begin(); nit!=_nets.end(); nit++)
987 {
988 (*nit)->Plot(out);
989 }
990 out << "EOF" << endl << "pause -1 'press any key'" << endl;
991 }
992
993 // ======================================================================
994 // void PlotFinal(char *output) const
995 // ======================================================================
996 void
PlotFinal(const string & output) const997 PPlacement::PlotFinal(const string& output) const
998 {
999 string name = output + ".gpl";
1000 ofstream out(name.c_str());
1001
1002 out << "set noxtics\nset noytics\n"
1003 << "set noborder\nset nokey\nset title '" << _fig->NAME << "'\n"
1004 << "#set terminal postscript eps color solid\n#set output '"
1005 << output << ".ps'\n"
1006 << "set xrange[" << GetMinX() << ":" << GetMaxX() << "]\n"
1007 << "set yrange[" << GetMinY() << ":" << GetMaxY() << "]\n"
1008 << "plot [:][:][:][:] '-' w l, '-' w l 2, '-' w l 3, '-' w l 4\n"
1009 << GetMinX() << " " << GetMinY() << endl
1010 << GetMinX() << " " << GetMaxY() << endl
1011 << GetMaxX() << " " << GetMaxY() << endl
1012 << GetMaxX() << " " << GetMinY() << endl
1013 << GetMinX() << " " << GetMinY() << endl << endl;
1014
1015 out << "#preplaced instances" << endl;
1016 for (PFixedInss::const_iterator insit = _fixedInss.begin();
1017 insit != _fixedInss.end(); insit++)
1018 {
1019 (*insit)->Plot(out);
1020 }
1021 out << "EOF" << endl;
1022
1023 out << "#subrows" << endl;
1024 for (PDetSubRows::const_iterator srit = _detSubRows.begin() ;
1025 srit != _detSubRows.end() ;
1026 srit++)
1027 {
1028 (*srit)->Plot(out);
1029 }
1030 out << "EOF" << endl;
1031
1032 out << "#instances" << endl;
1033
1034 for (PDetSubRows::const_iterator srit = _detSubRows.begin() ;
1035 srit != _detSubRows.end() ;
1036 srit++)
1037 {
1038 for (PDetSubRow::PDetInsVector::const_iterator iit = (*srit)->GetConstInssVector().begin() ;
1039 iit != (*srit)->GetConstInssVector().end() ;
1040 iit++)
1041 {
1042 (*iit)->Plot(out);
1043 }
1044 }
1045 out << "EOF" << endl;
1046 out << "#nets" << endl;
1047
1048 for (PONets::const_iterator nit=_nets.begin(); nit!=_nets.end(); nit++)
1049 {
1050 (*nit)->Plot(out);
1051 }
1052 out << "EOF" << endl << "pause -1 'press any key'" << endl;
1053 }
1054 // ======================================================================
1055 // void PlotOnlyInstances(char* output) const
1056 // ======================================================================
1057 void
PlotOnlyInstances(const string & output) const1058 PPlacement::PlotOnlyInstances(const string& output) const
1059 {
1060 string name = output + ".gpl";
1061 ofstream out(name.c_str());
1062
1063 out << "set noxtics\nset noytics\n"
1064 << "set noborder\nset nokey\nset title '" << _fig->NAME << "'\n"
1065 << "#set terminal postscript eps color solid\n#set output '"
1066 << output << ".ps'\n";
1067 out << "set xrange[" << GetMinX() << ":" << GetMaxX() << "]\n"
1068 << "set yrange[" << GetMinY() << ":" << GetMaxY() << "]\n"
1069 << "plot [:][:][:] '-' w l, '-' w l 2, '-' w l 3\n"
1070 << GetMinX() << " " << GetMinY() << endl
1071 << GetMinX() << " " << GetMaxY() << endl
1072 << GetMaxX() << " " << GetMaxY() << endl
1073 << GetMaxX() << " " << GetMinY() << endl
1074 << GetMinX() << " " << GetMinY() << endl << endl;
1075 PlotInstances(out);
1076 out << "pause -1 'press any key'" << endl;
1077 }
1078 // ======================================================================
1079 // void PlotOnlyBins(char* output) const
1080 // ======================================================================
1081 void
PlotOnlyBins(const string & output) const1082 PPlacement::PlotOnlyBins(const string& output) const
1083 {
1084 string name = output + ".gpl";
1085 ofstream out(name.c_str());
1086
1087 out << "set noxtics\nset noytics\n"
1088 << "set noborder\nset nokey\nset title '" << _fig->NAME << "'\n"
1089 << "#set terminal postscript eps color solid\n#set output '"
1090 << output << ".ps'\n";
1091
1092 if (_totalMoves != 0)
1093 {
1094 for (PRows::const_iterator rit=_rows.begin(); rit!=_rows.end(); rit++)
1095 {
1096 (*rit)->PlotLabel(out, _totalMoves);
1097 }
1098 }
1099
1100 out << "plot [:][:] '-' w l 1, '-' w l 2" << endl << "#bins" << endl;
1101 for (PRows::const_iterator rit=_rows.begin(); rit!=_rows.end(); rit++)
1102 {
1103 (*rit)->Plot(out);
1104 }
1105
1106 out << "EOF" << endl;
1107 out << "#preplaced instances" << endl;
1108 for (PFixedInss::const_iterator iit = _fixedInss.begin();
1109 iit != _fixedInss.end(); iit++)
1110 {
1111 (*iit)->Plot(out);
1112 }
1113 out << "EOF" << endl;
1114 out << "pause -1 'press any key'" << endl;
1115 }
1116 // ======================================================================
1117 // void PlotStat()
1118 // ======================================================================
1119 void
PlotStat()1120 PPlacement::PlotStat()
1121 {
1122 ofstream out("stat.gpl");
1123
1124 out << "set title 'all stats'" << endl
1125 << "#set terminal postscript color solid" << endl
1126 << "#set output 'stat.ps'" << endl
1127 << "plot 'alldata.dat' using 1:2 title 'temperature' with lines,"
1128 << "'alldata.dat' using 1:3 title 'cost' with lines,"
1129 << "'alldata.dat' using 1:4 title 'rowcost' with lines,"
1130 << "'alldata.dat' using 1:5 title 'bincost' with lines,"
1131 << "'alldata.dat' using 1:6 title 'netcost' with lines,"
1132 << "'alldata.dat' using 1:7 title 'success ratio' with lines,"
1133 << "'alldata.dat' using 1:8 title 'dist' with lines,"
1134 << "'alldata.dat' using 1:9 title 'delta' with lines" << endl
1135 << "pause -1 'press any key'" << endl;
1136 }
1137
1138 // ======================================================================
1139 // void GenerateConsPlacement()
1140 // ======================================================================
1141 void
GenerateConsPlacement()1142 PPlacement::GenerateConsPlacement()
1143 {
1144 //creation d'un placement aleatoire des connecteurs.
1145 unsigned faces[4];
1146 double aspectRatio = GetWidth() / GetHeight();
1147 double repartition = aspectRatio + 1.0;
1148 unsigned nbConsNorthSouth = (unsigned)( aspectRatio * _cons.size() / repartition);
1149 unsigned nbConsEastWest = _cons.size() - nbConsNorthSouth;
1150
1151 //faces north est sud ouest
1152 faces[0] = nbConsNorthSouth / 2;
1153 faces[2] = nbConsNorthSouth - faces[0];
1154 faces[1] = nbConsEastWest / 2;
1155 faces[3] = nbConsEastWest - faces[1];
1156
1157 PCons::iterator cit = _cons.begin();
1158
1159 unsigned minx = (unsigned)BBox.GetMinX();
1160 unsigned miny = (unsigned)BBox.GetMinY();
1161 unsigned maxx = (unsigned)BBox.GetMaxX();
1162 unsigned maxy = (unsigned)BBox.GetMaxY();
1163
1164 unsigned pos = 0;
1165 unsigned interval = 0;
1166 int spaceLeft = 0;
1167
1168 //placement au nord.
1169 if (faces[0])
1170 {
1171 interval = (maxx - minx) / faces[0];
1172 spaceLeft = (maxx - minx) % faces[0];
1173 pos = minx + interval / 2;
1174 while(faces[0]--)
1175 {
1176 if (spaceLeft-- > 0)
1177 pos += 1;
1178 (*cit)->SetOrient(NORTH);
1179 (*cit++)->SetPos(PPos(pos , maxy));
1180 pos += interval;
1181 }
1182 }
1183
1184 //placement a l'est.
1185 if (faces[1])
1186 {
1187 interval = (maxy - miny) / faces[1];
1188 spaceLeft = (maxy - miny) % faces[1];
1189 pos = miny + interval / 2;
1190 while(faces[1]--)
1191 {
1192 if (spaceLeft-- > 0)
1193 pos += 1;
1194 (*cit)->SetOrient(EAST);
1195 (*cit++)->SetPos(PPos(maxx , pos));
1196 pos += interval;
1197 }
1198 }
1199
1200 //placement au sud.
1201 if (faces[2])
1202 {
1203 interval = (maxx - minx) / faces[2];
1204 spaceLeft = (maxx - minx) % faces[2];
1205 pos = minx + interval / 2;
1206 while(faces[2]--)
1207 {
1208 if (spaceLeft-- > 0)
1209 pos += 1;
1210 (*cit)->SetOrient(SOUTH);
1211 (*cit++)->SetPos(PPos(pos , miny));
1212 pos += interval;
1213 }
1214 }
1215
1216 //placement a l'ouest.
1217 if (faces[3])
1218 {
1219 interval = (maxy - miny) / faces[3];
1220 spaceLeft = (maxy - miny) % faces[3];
1221 pos = miny + interval / 2;
1222 while(faces[3]--)
1223 {
1224 if (spaceLeft-- > 0)
1225 pos += 1;
1226 (*cit)->SetOrient(WEST);
1227 (*cit++)->SetPos(PPos(minx , pos));
1228 pos += interval;
1229 }
1230 }
1231 }
1232
1233 // ======================================================================
1234 // void GenerateRingConsPlacement()
1235 // this method will be deleted in the future ( .... I HOPE ;) .. )
1236 // His purpose is to give a ring suitable connectors placement
1237 // ======================================================================
1238 void
GenerateRingConsPlacement()1239 PPlacement::GenerateRingConsPlacement()
1240 {
1241 //creation d'un placement aleatoire des connecteurs pour ring.
1242 unsigned faces[2];
1243 unsigned nbConsNorth = _cons.size() / 2;
1244 unsigned nbConsSouth = _cons.size() - nbConsNorth;
1245
1246 //faces north est sud ouest
1247 faces[0] = nbConsNorth;
1248 faces[1] = nbConsSouth;
1249
1250 PCons::iterator cit = _cons.begin();
1251
1252 unsigned minx = (unsigned)BBox.GetMinX();
1253 unsigned miny = (unsigned)BBox.GetMinY();
1254 unsigned maxx = (unsigned)BBox.GetMaxX();
1255 unsigned maxy = (unsigned)BBox.GetMaxY();
1256
1257 unsigned pos = 0;
1258 unsigned interval = 0;
1259 int spaceLeft = 0;
1260
1261 //placement au nord.
1262 if (faces[0])
1263 {
1264 interval = (maxx - minx) / faces[0];
1265 spaceLeft = (maxx - minx) % faces[0];
1266 pos = minx + interval / 2;
1267 while(faces[0]--)
1268 {
1269 if (spaceLeft-- > 0)
1270 pos += 1;
1271 (*cit)->SetOrient(NORTH);
1272 (*cit++)->SetPos(PPos(pos , maxy));
1273 pos += interval;
1274 }
1275 }
1276
1277 //placement au sud.
1278 if (faces[1])
1279 {
1280 interval = (maxx - minx) / faces[1];
1281 spaceLeft = (maxx - minx) % faces[1];
1282 pos = minx + interval / 2;
1283 while(faces[1]--)
1284 {
1285 if (spaceLeft-- > 0)
1286 pos += 1;
1287 (*cit)->SetOrient(SOUTH);
1288 (*cit++)->SetPos(PPos(pos , miny));
1289 pos += interval;
1290 }
1291 }
1292 }
1293
1294 // ======================================================================
1295 // void InitPlace(int NbRows)
1296 // private method
1297 // ======================================================================
1298 void
InitPlace(int NbRows)1299 PPlacement::InitPlace(int NbRows)
1300 {
1301 // no preplacement
1302 // we make a rectangle of rows with for each one subrow
1303 // of size = size of the row
1304 // composed of bins of constant size
1305 int NRows = NbRows;
1306
1307 if (_verbose)
1308 cout << " o Computing Initial Placement ..." << endl;
1309
1310 if (_verbose)
1311 {
1312 cout << " o User Margin : " << 100.0 * _margin << "%" << endl;
1313 }
1314
1315 double rowwidth = SquareShape(_margin, _sumToPlaceInssWidth,
1316 _binsMinWidth, NRows);
1317
1318 if (_verbose)
1319 {
1320 cout << " o Number of Rows : " << NRows << endl;
1321 }
1322
1323 // computing Effective Margin
1324 double realSurface = NRows * rowwidth;
1325 _realMargin = 1.0 - _sumToPlaceInssWidth / realSurface;
1326 if (_verbose)
1327 {
1328 cout << " o Real Margin : " << 100.0 * _realMargin << "%" << endl;
1329 }
1330
1331
1332 _rows.reserve(NRows);
1333
1334 double Y = 0.0;
1335 unsigned rowidx = 0;
1336 bool RowOrientation = false;
1337 _rowZeroOrientation = RowOrientation;
1338 for (int i = 0; i < NRows; i++)
1339 {
1340 _rows.push_back(new PRow(1));
1341 double XMin = 0.0;
1342 _rows.back()->Init(Y, XMin, *this, RowOrientation);
1343 _rowsYMax[Y + ROWHEIGHT] = rowidx;
1344 _rowsYMinInv[Y] = rowidx;
1345 ++rowidx;
1346 PSubRow& subrow = *(_rows.back()->_subRows[0]);
1347 subrow.Init(_rows.back(), Y, XMin, rowwidth, _realMargin, _binsMaxWidth, _binsMinWidth);
1348 _rows.back()->_subRowsXMax[rowwidth + XMin] = 0;
1349 _rows.back()->_subRowsXMaxInv[rowwidth + XMin] = 0;
1350 Y += ROWHEIGHT;
1351 RowOrientation = !RowOrientation;
1352 }
1353
1354 // Computing Placement BBox
1355 double MaxX = 0.0, MaxY = 0.0, RowMaxX = 0.0, RowMaxY = 0.0;
1356 for (PRows::iterator rit = _rows.begin(); rit != _rows.end(); rit++)
1357 {
1358 RowMaxX = (*rit)->GetMaxX();
1359 RowMaxY = (*rit)->GetMaxY();
1360 if (MaxX < RowMaxX)
1361 MaxX = RowMaxX;
1362 if (MaxY < RowMaxY)
1363 MaxY = RowMaxY;
1364 }
1365 BBox.SetMinX(0.0);
1366 BBox.SetMinY(0.0);
1367 BBox.SetMaxX(RowMaxX);
1368 BBox.SetMaxY(RowMaxY);
1369 }
1370
1371 // ======================================================================
1372 // void InitPlaceWithPrePlace()
1373 // private method
1374 // ======================================================================
1375 void
InitPlaceWithPrePlace()1376 PPlacement::InitPlaceWithPrePlace()
1377 {
1378 // abutment box
1379 if (!_prePlaceFig)
1380 {
1381 cerr << " o ERROR: impossible to init preplacement with empty preplacement figure" << endl;
1382 exit(1);
1383 }
1384
1385 int Width = _prePlaceFig->XAB2 - _prePlaceFig->XAB1;
1386 int Height = _prePlaceFig->YAB2 - _prePlaceFig->YAB1;
1387
1388 // VERIFICATION OF THE PREPLACEMENT
1389 // abutment box
1390 if (Width % PITCH != 0)
1391 {
1392 cerr << " o ERROR : abutment box's width must be a multiple of 5 lambdas"
1393 << endl;
1394 exit(1);
1395 }
1396
1397 if (Height % (PITCH * ROWHEIGHT) != 0)
1398 {
1399 cerr << " o ERROR : abutment box's height must be a multiple of 50 lambdas"
1400 << endl;
1401 exit(1);
1402 }
1403
1404 Width =(int)(Width / PITCH);
1405 Height = (int)(Height / (PITCH * ROWHEIGHT));
1406
1407 PrePlaceTab tabpreplace(Height, PrePlaceRow(Width, false));
1408
1409 // find the orientation of the first row.
1410 phins* refpins = _prePlaceFig->PHINS;
1411
1412 if (refpins)
1413 {
1414 int ycoord = (int)((refpins->YINS - _dy) / (ROWHEIGHT * PITCH));
1415 phfig* refpinsmodel = getphfig(refpins->FIGNAME, 'P');
1416 int refpinsheight = (int)((refpinsmodel->YAB2 - refpinsmodel->YAB1)
1417 / (ROWHEIGHT * PITCH));
1418 char transf = refpins->TRANSF;
1419
1420 if (ycoord % 2 == 0)
1421 {
1422 if ((refpinsheight == 2) || (transf == NOSYM) || (transf == SYM_X))
1423 _rowZeroOrientation = true;
1424 else
1425 _rowZeroOrientation = false;
1426 } else {
1427 if ((refpinsheight == 2) || (transf == NOSYM) || (transf == SYM_X))
1428 _rowZeroOrientation = false;
1429 else
1430 _rowZeroOrientation = true;
1431 }
1432
1433 // tests for each instance
1434 for (phins* pins = _prePlaceFig->PHINS; pins; pins = pins->NEXT)
1435 {
1436 phfig_list* phmodel = getphfig(pins->FIGNAME, '0');
1437 int pinswidth = phmodel->XAB2 - phmodel->XAB1;
1438 int pinsheight = phmodel->YAB2 - phmodel->YAB1;
1439
1440 pinswidth = (int)(pinswidth / PITCH); // largeur ramene au pitch
1441 pinsheight = (int)(pinsheight / PITCH); // hauteur ramene au pitch
1442 int pinsheightrow = (int)(pinsheight / ROWHEIGHT); // hauteur ramene a l'unite
1443 // (taille des lignes)
1444 int ypos = (int)((pins->YINS - _dy) / PITCH); // position en y ramene au pitch
1445 int xpos = (int)((pins->XINS - _dx) / PITCH); // position en x ramene au pitch
1446 int ycoord = (int)(ypos / ROWHEIGHT); // position en y ramene a l'unite
1447
1448 if ((pins->YINS - _dy) % 50 != 0)
1449 {
1450 cerr << " o ERROR : in preplacement file : y position of "
1451 << pins->INSNAME << " is incorrect" << endl;
1452 exit (1);
1453 }
1454
1455 if ((pins->XINS - _dx) % 5 != 0)
1456 {
1457 cerr << " o ERROR : in preplacement file : x position of "
1458 << pins->INSNAME << " is incorrect" << endl;
1459 exit (1);
1460 }
1461
1462 if ( (pins->TRANSF == ROT_P) || (pins->TRANSF == ROT_M)
1463 || (pins->TRANSF == SY_RP) || (pins->TRANSF == SY_RM) )
1464 {
1465 cerr << " o ERROR : " << pins->INSNAME << " : incorrect rotation" << endl;
1466 exit(1);
1467 }
1468
1469 // check if orientation of instance matches
1470 bool insOrient;
1471 if ((pinsheightrow == 2) || (pins->TRANSF == NOSYM) || (pins->TRANSF == SYM_X))
1472 insOrient = true;
1473 else
1474 insOrient = false;
1475
1476 if ( ((ycoord % 2 == 0) && (insOrient != _rowZeroOrientation))
1477 || ((ycoord % 2 != 0) && (insOrient == _rowZeroOrientation)) )
1478 {
1479 cerr << " o ERROR : " << pins->INSNAME << " badly oriented" << endl
1480 << " Incoherence with " << refpins->INSNAME << endl;
1481 exit(1);
1482 }
1483
1484 for (int yit = ycoord; yit < ycoord + pinsheightrow; yit++)
1485 {
1486 for (int xit = xpos; xit < xpos + pinswidth; xit++)
1487 {
1488 if ( (xit > Width - 1) || (yit > Height - 1)
1489 || (xit < 0 ) || (yit < 0 ) )
1490 {
1491 cerr << " o ERROR : " << pins->INSNAME
1492 << " out of the abutment box" << endl;
1493 exit(1);
1494 }
1495
1496 if (tabpreplace[yit][xit] == false)
1497 {
1498 tabpreplace[yit][xit] = true;
1499 }
1500 else{
1501 cerr << " o ERROR : " << pins->INSNAME << " badly placed .... There is already an instance at its position ...." << endl;
1502 exit (1);
1503 }
1504 }
1505 }
1506 }
1507 }
1508
1509 // create rows and subrows
1510 if (_nInsToPlace > 0)
1511 {
1512 int nbrows = 0;
1513 for (int yit = 0; yit < Height; yit++)
1514 {
1515 if (CheckCreateRow(tabpreplace, yit, Width) > 0) ++nbrows;
1516 }
1517
1518
1519 _rows.reserve(nbrows);
1520
1521 bool orientation = _rowZeroOrientation;
1522 int numrows = 0;
1523 for (int yit = 0; yit < Height; yit++)
1524 {
1525 int numsubrows = CheckCreateRow(tabpreplace, yit, Width);
1526 if (numsubrows > 0)
1527 {
1528 PRow* row = new PRow(*this, (double)(yit * ROWHEIGHT), Width, numsubrows, orientation);
1529 _rows.push_back(row);
1530 _rowsYMax[(yit + 1) * ROWHEIGHT] = numrows;
1531 _rowsYMinInv[yit * ROWHEIGHT] = numrows;
1532 ++numrows;
1533 CreateSubRows(_rows.back(), tabpreplace, yit, numsubrows, Width);
1534 }
1535 orientation = !orientation;
1536 }
1537 }
1538 BBox.SetMinX(0.0);
1539 BBox.SetMinY(0.0);
1540 BBox.SetMaxX(Width);
1541 BBox.SetMaxY(Height * ROWHEIGHT);
1542 }
1543
1544 // ======================================================================
1545 // void CreateSubRows(PRow* row, PrePlaceTab& tabpreplace,int coordy, int nbsubrows, int Width)
1546 // private method
1547 // ======================================================================
1548 void
CreateSubRows(PRow * row,PrePlaceTab & tabpreplace,int coordy,int nbsubrows,int Width)1549 PPlacement::CreateSubRows(PRow* row, PrePlaceTab& tabpreplace,
1550 int coordy, int nbsubrows, int Width)
1551 {
1552 int coordx = 0;
1553 int subrowscreated = 0;
1554
1555 while (coordx < Width)
1556 {
1557 while (( coordx < Width )
1558 && ( tabpreplace[coordy][coordx] == true ))
1559 ++coordx;
1560
1561 if (coordx >= Width)
1562 break;
1563
1564 int xmin = coordx;
1565
1566 while (( coordx < Width )
1567 && ( tabpreplace[coordy][coordx] == false ))
1568 ++coordx;
1569
1570 int xmax = coordx;
1571
1572 if ( (xmax - xmin) >= _binsMinWidth)
1573 {
1574 row->_subRows[subrowscreated]->Init(row, (double)(coordy * ROWHEIGHT), (double)xmin,(double)xmax,
1575 (double)_margin, _binsMaxWidth, _binsMinWidth);
1576 row->_subRowsXMax[(double)xmax] = subrowscreated;
1577 ++subrowscreated;
1578 }
1579 for (PRow::PSubRowsXMax::iterator srymit = row->_subRowsXMax.begin();
1580 srymit != row->_subRowsXMax.end();
1581 srymit++)
1582 {
1583 row->_subRowsXMaxInv[srymit->first] = srymit->second;
1584 }
1585 }
1586 if (subrowscreated != nbsubrows)
1587 {
1588 cerr << " o INTERNAL ERROR : in subrow creation" << endl;
1589 exit (1);
1590 }
1591 }
1592
1593 // ======================================================================
1594 // void CheckCreateRow(PrePlaceTab& tabpreplace, int coordy, int Width)
1595 // private method
1596 // ======================================================================
1597 int
CheckCreateRow(PrePlaceTab & tabpreplace,int coordy,int Width)1598 PPlacement::CheckCreateRow(PrePlaceTab& tabpreplace, int coordy, int Width)
1599 {
1600 int coordx = 0;
1601 int nbsubrows = 0;
1602
1603 while (coordx < Width)
1604 {
1605 while ( ( coordx < Width )
1606 && ( tabpreplace[coordy][coordx] == true ))
1607 ++coordx;
1608
1609 if (coordx >= Width)
1610 break;
1611
1612 int xmin = coordx;
1613
1614 while ( ( coordx < Width )
1615 && ( tabpreplace[coordy][coordx] == false ))
1616 ++coordx;
1617
1618 int xmax = coordx;
1619
1620 if ( (xmax - xmin) >= _binsMinWidth)
1621 ++nbsubrows;
1622 }
1623
1624 return (nbsubrows);
1625 }
1626
1627 // ======================================================================
1628 // PRow& GetRow(const PRow* row, const double dist)
1629 // private method
1630 // ======================================================================
1631 PRow&
GetRow(const PRow * row,const double dist)1632 PPlacement::GetRow(const PRow* row, const double dist)
1633 {
1634 // returns randomly a row at maximum distance from yorig
1635 double bornesup, borneinf;
1636
1637
1638 if ((bornesup = (row->GetMinY() + row->GetHeight() / 2.0) + (double)(int)(dist * GetHeight() + 0.5) ) > GetMaxY())
1639 bornesup = GetMaxY();
1640
1641 if ((borneinf = (row->GetMinY() + row->GetHeight() / 2.0) - (double)(int)(dist * GetHeight() + 0.5) ) < GetMinY())
1642 borneinf = GetMinY();
1643
1644 PRowsYMax::iterator rinf = _rowsYMax.upper_bound(borneinf);
1645 PRowsYMax::iterator rsup = _rowsYMinInv.upper_bound(bornesup);
1646
1647 unsigned randidx = rinf->second + (unsigned)((double)(rsup->second - rinf->second + 1) * (rand() / (RAND_MAX+1.0)));
1648 return *_rows[randidx];
1649 }
1650
GetBinsCapa() const1651 double PPlacement::GetBinsCapa() const
1652 {
1653 double binsCapa = 0.0;
1654 for (PRows::const_iterator rit = _rows.begin(); rit != _rows.end(); rit++)
1655 {
1656 binsCapa += (*rit)->GetBinsCapa();
1657 }
1658 return binsCapa;
1659 }
1660
GetSubRowsCapa() const1661 double PPlacement::GetSubRowsCapa() const
1662 {
1663 double subRowsCapa = 0.0;
1664 for (PRows::const_iterator rit = _rows.begin(); rit != _rows.end(); rit++)
1665 {
1666 subRowsCapa += (*rit)->GetSubRowsCapa();
1667 }
1668 return subRowsCapa;
1669 }
1670
GetBinsSize() const1671 double PPlacement::GetBinsSize() const
1672 {
1673 double binsSize = 0.0;
1674 for (PRows::const_iterator rit = _rows.begin(); rit != _rows.end(); rit++)
1675 {
1676 binsSize += (*rit)->GetBinsSize();
1677 }
1678 return binsSize;
1679 }
1680