2011CaoTme45: MbkBridge.cpp

File MbkBridge.cpp, 8.8 KB (added by jpc, 13 years ago)

C++ Module: Corps du convertisseur vers Hurricane

Line 
1
2// -*- mode: c++ -*-
3
4#include <cstdlib>
5#include <iostream>
6#include <memory>
7#include <list>
8using std::cout;
9using std::cerr;
10using std::endl;
11using std::auto_ptr;
12using std::list;
13
14#include "Lofig.h"
15#include "Loins.h"
16#include "Locon.h"
17#include "Losig.h"
18
19#include "hurricane/Warning.h"
20#include "hurricane/UpdateSession.h"
21#include "hurricane/Collection.h"
22#include "hurricane/DataBase.h"
23#include "hurricane/Technology.h"
24#include "hurricane/Layer.h"
25#include "hurricane/Library.h"
26#include "hurricane/Cell.h"
27#include "hurricane/Instance.h"
28#include "hurricane/Net.h"
29#include "hurricane/Plug.h"
30#include "hurricane/Pin.h"
31#include "hurricane/NetExternalComponents.h"
32#include "crlcore/AllianceFramework.h"
33#include "crlcore/Catalog.h"
34#include "crlcore/ToolBox.h"
35#include "RawViewer.h"
36#include "MbkBridge.h"
37
38using Hurricane::ForEachIterator;
39using Hurricane::dbo_ptr;
40using Hurricane::Error;
41using Hurricane::DbU;
42using Hurricane::Point;
43using Hurricane::Box;
44using Hurricane::Transformation;
45using Hurricane::DataBase;
46using Hurricane::Technology;
47using Hurricane::Layer;
48using Hurricane::Instance;
49using Hurricane::Cell;
50using Hurricane::Library;
51using Hurricane::Net;
52using Hurricane::Plug;
53using Hurricane::Pin;
54using Hurricane::NetExternalComponents;
55using Hurricane::UpdateSession;
56using CRL::AllianceFramework;
57using CRL::Catalog;
58using CRL::createPlugsAndPinsRing;
59using CRL::placeNet;
60
61
62static Library* __mbkLibrary = NULL;
63
64
65Cell* toHurricane ( Lofig* lofig )
66{
67  Cell* cell = NULL;
68
69  try {
70    if ( !lofig ) {
71      cerr << "[ERROR] mbkloParser(): empty lofig." << endl;
72      exit(1);
73    }
74
75    if ( !DataBase::getDB() ) DataBase::create();
76
77    if ( !__mbkLibrary ) {
78      __mbkLibrary = Library::create ( DataBase::getDB(), "MBK" );
79    }
80
81  //cerr << "toHurricane() " << lofig->getName() << endl;
82
83    if ( lofig->getName() == "and2" )
84      return AllianceFramework::get()->getCell ( "a2_x2", Catalog::State::Views );
85    if ( lofig->getName() == "or2" )
86      return AllianceFramework::get()->getCell ( "o2_x2", Catalog::State::Views );
87    if ( lofig->getName() == "xor2" )
88      return AllianceFramework::get()->getCell ( "xr2_x1", Catalog::State::Views );
89
90    cell = __mbkLibrary->getCell(lofig->getName());
91    if ( cell ) return cell;
92
93    cell = Cell::create ( __mbkLibrary, lofig->getName() );
94
95    const list<Losig*>& sigs = lofig->getSignals();
96    list<Losig*>::const_iterator isig = sigs.begin();
97    for ( ; isig != sigs.end() ; ++isig ) {
98      Net* net = Net::create ( cell, (*isig)->getName() );
99      net->setExternal ( (*isig)->getType() == Locon::External );
100    }
101
102    const list<Locon*>& connectors = lofig->getConnectors();
103    list<Locon*>::const_iterator icon = connectors.begin();
104    for ( ; icon != connectors.end() ; ++icon ) {
105    // Note: Signal name override connector name.
106      string netName;
107      Losig* sig = (*icon)->getSignal();
108
109      if ( sig ) netName = sig->getName();
110      else {
111        netName = (*icon)->getName();
112        cerr << "[ERROR] Locon <" << (*icon)->getName()
113             << " of Lofig <" << getString(cell->getName())
114             << "> is not connected (making dummy signal)." << endl;
115      }
116     
117      Net* net = cell->getNet ( netName );
118      if ( not net ) {
119        Net* net = Net::create ( cell, netName );
120        net->setExternal ( true );
121      }
122
123      switch ( (*icon)->getDirection() ) {
124        case Locon::In:        net->setDirection(Net::Direction::IN);        break;
125        case Locon::Out:       net->setDirection(Net::Direction::OUT);       break;
126        case Locon::Inout:     net->setDirection(Net::Direction::INOUT);     break;
127        case Locon::Tristate:  net->setDirection(Net::Direction::TRISTATE);  break;
128        case Locon::Transcv:   net->setDirection(Net::Direction::TRISTATE);  break;
129        default:
130        case Locon::Unknown:   net->setDirection(Net::Direction::UNDEFINED); break;
131      }
132    }
133
134    const list<Loins*>& instances = lofig->getInstances();
135    list<Loins*>::const_iterator iins = instances.begin();
136    for ( ; iins != instances.end() ; ++iins ) {
137      Cell*     model      = toHurricane ( (*iins)->getModel() );
138      Instance* huInstance = Instance::create ( cell, (*iins)->getName(), model );
139
140      const list<Locon*>& connectors = (*iins)->getConnectors();
141      list<Locon*>::const_iterator icon = connectors.begin();
142      for ( ; icon != connectors.end() ; ++icon ) {
143        Net* masterNet = huInstance->getMasterCell()->getNet((*icon)->getName());
144        if ( not masterNet ) {
145          cerr << "[ERROR] Model (Lofig) <" << getString(huInstance->getMasterCell()->getName())
146               << "> of Instance (Loins) <" << getString(huInstance->getName())
147               << "> do not have connector (Locon) named <" << (*icon)->getName()
148               << "> (ignored)." << endl;
149          continue;
150        }
151
152        Losig* signal = (*icon)->getSignal();
153        if ( not signal ) {
154          cerr << "[ERROR] Locon <" << (*icon)->getName()
155               << " of instance <" << getString(huInstance->getName())
156               << "> is not connected (ignored)." << endl;
157          continue;
158        }
159
160        Net*  net  = cell->getNet(signal->getName());
161        Plug* plug = huInstance->getPlug(masterNet);
162        plug->setNet(net);
163      }
164    }
165  }
166  catch ( Error& e ) {
167    cerr << e.what() << endl;
168    exit ( 1 );
169  }
170
171  return cell;
172}
173
174
175Cell* placeAsNetlist ( Cell* cell, unsigned int depth )
176{
177  if (  cell->isTerminal() ) return cell;
178  if ( !cell->getAbutmentBox().isEmpty() ) return cell;
179
180  try {
181    UpdateSession::open();
182 
183    Point bottomLeft (0,0);
184 
185    forEach ( Instance*, iinstance, cell->getInstances() ) {
186      placeAsNetlist(iinstance->getMasterCell(),depth+1);
187      Box modelBox = iinstance->getMasterCell()->getAbutmentBox();
188 
189      if (depth % 2)
190        bottomLeft.translate(-modelBox.getXMin(),0);
191      else
192        bottomLeft.translate(0,-modelBox.getYMin());
193 
194      iinstance->setTransformation(Transformation(bottomLeft));
195      iinstance->materialize();
196 
197      if (depth % 2)
198        bottomLeft.translate(modelBox.getXMax(),0);
199      else
200        bottomLeft.translate(0,modelBox.getYMax());
201    }
202 
203    Box ab = cell->getBoundingBox().inflate(DbU::lambda(10.0));
204    cell->setAbutmentBox( ab );
205 
206    vector<Net*> inputs;
207    vector<Net*> outputs;
208    vector<Net*> undefineds;
209 
210    forEach ( Net*, inet, cell->getNets() ) {
211      if ( not inet->isExternal() ) continue;
212
213      switch ( inet->getDirection() ) {
214        case Net::Direction::IN:
215          inputs.push_back(*inet); break;
216        case Net::Direction::OUT:
217        case Net::Direction::INOUT:
218        case Net::Direction::TRISTATE:
219          outputs.push_back(*inet); break;
220        case Net::Direction::UNDEFINED:
221          undefineds.push_back(*inet); break;
222      }
223    }
224 
225    Layer* layer = DataBase::getDB()->getTechnology()->getLayer("METAL2");
226 
227    if (inputs.size()) {
228      DbU::Unit step = ab.getHeight() / inputs.size();
229      DbU::Unit y    = ab.getYMin() + step/2;
230 
231      for ( size_t i=0 ; i<inputs.size() ; ++i ) {
232      //cerr << inputs[i]->getName() << ":" << DbU::getValueString(y) << endl;
233        Pin* pin = Pin::create( inputs[i]
234                              , inputs[i]->getName()
235                              , Pin::AccessDirection::WEST
236                              , Pin::PlacementStatus::PLACED
237                              , layer
238                              , ab.getXMin()
239                              , y
240                              , DbU::lambda(2.0)
241                              , DbU::lambda(2.0)
242                              );
243        NetExternalComponents::setExternal(pin);
244        y += step;
245      }
246    }
247 
248    if (outputs.size()) {
249      DbU::Unit step = ab.getHeight() / outputs.size();
250      DbU::Unit y    = ab.getYMin() + step/2;
251 
252      for ( size_t i=0 ; i<outputs.size() ; ++i ) {
253      //cerr << outputs[i]->getName() << ":" << DbU::getValueString(y) << endl;
254        Pin* pin = Pin::create( outputs[i]
255                              , outputs[i]->getName()
256                              , Pin::AccessDirection::EAST
257                              , Pin::PlacementStatus::PLACED
258                              , layer
259                              , ab.getXMax()
260                              , y
261                              , DbU::lambda(2.0)
262                              , DbU::lambda(2.0)
263                              );
264        NetExternalComponents::setExternal(pin);
265        y += step;
266      }
267    }
268 
269    createPlugsAndPinsRing(cell);
270 
271    cerr << cell << endl;
272    forEach ( Net*, inet, cell->getNets() ) {
273      if ( not placeNet(*inet) ) {
274        cerr << "  " << *inet << " is not placed" << endl;
275        inet->setPosition(cell->getAbutmentBox().getCenter());
276      }
277    }
278     
279    UpdateSession::close();
280  }
281  catch ( Error& e ) {
282    cerr << e.what() << endl;
283    exit ( 1 );
284  }
285
286  return cell;
287}