2017-12-01 07:17:47 -06:00
|
|
|
// -*- C++ -*-
|
|
|
|
//
|
|
|
|
// This file is part of the Coriolis Software.
|
2018-01-06 10:55:44 -06:00
|
|
|
// Copyright (c) UPMC 2017-2018, All Rights Reserved
|
2017-12-01 07:17:47 -06:00
|
|
|
//
|
|
|
|
// +-----------------------------------------------------------------+
|
|
|
|
// | C O R I O L I S |
|
|
|
|
// | T o o l E n g i n e T u t o r i a l |
|
|
|
|
// | |
|
|
|
|
// | Author : Jean-Paul CHAPUT |
|
|
|
|
// | E-mail : Jean-Paul.Chaput@lip6.fr |
|
|
|
|
// | =============================================================== |
|
|
|
|
// | C++ Module : "./TutorialEngine.cpp" |
|
|
|
|
// +-----------------------------------------------------------------+
|
|
|
|
|
|
|
|
|
|
|
|
#include <Python.h>
|
|
|
|
#include <sstream>
|
|
|
|
#include <fstream>
|
|
|
|
#include <iomanip>
|
Migration towards Python3, first stage: still based on C-Macros.
* New: Python/C++ API level:
* Write a new C++/template wrapper to get rid of boost::python
* The int & long Python type are now merged. So a C/C++ level,
it became "PyLong_X" (remove "PyInt_X") and at Python code
level, it became "int" (remove "long").
* Change: VLSISAPD finally defunct.
* Configuration is now integrated as a Hurricane component,
makes use of the new C++/template wrapper.
* vlsisapd is now defunct. Keep it in the source for now as
some remaining non essential code may have to be ported in
the future.
* Note: Python code (copy of the migration howto):
* New print function syntax print().
* Changed "dict.has_key(k)" for "k" in dict.
* Changed "except Exception, e" for "except Exception as e".
* The division "/" is now the floating point division, even if
both operand are integers. So 3/2 now gives 1.5 and no longer 1.
The integer division is now "//" : 1 = 3//2. So have to carefully
review the code to update. Most of the time we want to use "//".
We must never change to float for long that, in fact, represents
DbU (exposed as Python int type).
* execfile() must be replaced by exec(open("file").read()).
* iter().__next__() becomes iter(x).__next__().
* __getslice__() has been removed, integrated to __getitem__().
* The formating used for str(type(o)) has changed, so In Stratus,
have to update them ("<class 'MyClass'>" instead of "MyClass").
* the "types" module no longer supply values for default types
like str (types.StringType) or list (types.StringType).
Must use "isinstance()" where they were occuring.
* Remove the 'L' to indicate "long integer" (like "12L"), now
all Python integer are long.
* Change in bootstrap:
* Ported Coriolis builder (ccb) to Python3.
* Ported Coriolis socInstaller.py to Python3.
* Note: In PyQt4+Python3, QVariant no longer exists. Use None or
directly convert using the python syntax: bool(x), int(x), ...
By default, it is a string (str).
* Note: PyQt4 bindings & Python3 under SL7.
* In order to compile user's must upgrade to my own rebuild of
PyQt 4 & 5 bindings 4.19.21-1.el7.soc.
* Bug: In cumulus/plugins.block.htree.HTree.splitNet(), set the root
buffer of the H-Tree to the original signal (mainly: top clock).
Strangely, it was only done when working in full chip mode.
2021-09-19 12:41:24 -05:00
|
|
|
#include "hurricane/utilities/Path.h"
|
2017-12-01 07:17:47 -06:00
|
|
|
#include "hurricane/DebugSession.h"
|
|
|
|
#include "hurricane/UpdateSession.h"
|
|
|
|
#include "hurricane/Bug.h"
|
|
|
|
#include "hurricane/Error.h"
|
|
|
|
#include "hurricane/Warning.h"
|
|
|
|
#include "hurricane/DataBase.h"
|
|
|
|
#include "hurricane/Technology.h"
|
|
|
|
#include "hurricane/Breakpoint.h"
|
|
|
|
#include "hurricane/Layer.h"
|
|
|
|
#include "hurricane/Net.h"
|
|
|
|
#include "hurricane/RoutingPad.h"
|
|
|
|
#include "hurricane/Plug.h"
|
|
|
|
#include "hurricane/Cell.h"
|
|
|
|
#include "hurricane/Instance.h"
|
|
|
|
#include "hurricane/Vertical.h"
|
|
|
|
#include "hurricane/Horizontal.h"
|
|
|
|
#include "crlcore/AllianceFramework.h"
|
|
|
|
#include "tutorial/TutorialEngine.h"
|
|
|
|
|
|
|
|
|
|
|
|
namespace Tutorial {
|
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
using Hurricane::dbo_ptr;
|
|
|
|
using Hurricane::UpdateSession;
|
|
|
|
using Hurricane::DebugSession;
|
|
|
|
using Hurricane::tab;
|
|
|
|
using Hurricane::Bug;
|
|
|
|
using Hurricane::Error;
|
|
|
|
using Hurricane::Warning;
|
|
|
|
using Hurricane::Breakpoint;
|
|
|
|
using Hurricane::Timer;
|
|
|
|
using Hurricane::DbU;
|
|
|
|
using Hurricane::Box;
|
|
|
|
using Hurricane::Layer;
|
|
|
|
using Hurricane::DataBase;
|
|
|
|
using Hurricane::Technology;
|
|
|
|
using Hurricane::Component;
|
|
|
|
using Hurricane::Contact;
|
|
|
|
using Hurricane::Horizontal;
|
|
|
|
using Hurricane::Vertical;
|
|
|
|
using Hurricane::RoutingPad;
|
|
|
|
using Hurricane::Cell;
|
|
|
|
using Hurricane::Plug;
|
|
|
|
using Hurricane::Instance;
|
|
|
|
using Hurricane::Transformation;
|
|
|
|
using Hurricane::Occurrence;
|
|
|
|
|
|
|
|
|
|
|
|
// -------------------------------------------------------------------
|
|
|
|
// Class : "Tutorial::TutorialEngine".
|
|
|
|
|
|
|
|
Name TutorialEngine::_toolName = "Tutorial";
|
|
|
|
|
|
|
|
|
|
|
|
const Name& TutorialEngine::staticGetName ()
|
|
|
|
{ return _toolName; }
|
|
|
|
|
|
|
|
|
|
|
|
TutorialEngine* TutorialEngine::get ( const Cell* cell )
|
|
|
|
{ return static_cast<TutorialEngine*>(ToolEngine::get(cell,staticGetName())); }
|
|
|
|
|
|
|
|
|
|
|
|
TutorialEngine::TutorialEngine ( Cell* cell )
|
|
|
|
: Super (cell)
|
|
|
|
, _viewer (NULL)
|
|
|
|
{ }
|
|
|
|
|
|
|
|
|
|
|
|
void TutorialEngine::_postCreate ()
|
|
|
|
{
|
|
|
|
Super::_postCreate ();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TutorialEngine* TutorialEngine::create ( Cell* cell )
|
|
|
|
{
|
|
|
|
TutorialEngine* tutorial = new TutorialEngine ( cell );
|
|
|
|
|
|
|
|
tutorial->_postCreate();
|
|
|
|
|
|
|
|
return tutorial;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void TutorialEngine::_preDestroy ()
|
|
|
|
{ }
|
|
|
|
|
|
|
|
|
|
|
|
TutorialEngine::~TutorialEngine ()
|
|
|
|
{ }
|
|
|
|
|
|
|
|
|
|
|
|
const Name& TutorialEngine::getName () const
|
|
|
|
{ return _toolName; }
|
|
|
|
|
|
|
|
|
|
|
|
Cell* TutorialEngine::runDemoPart1 ()
|
|
|
|
{
|
|
|
|
cerr << "TutorialEngine::runDemoPart1() has been called." << endl;
|
|
|
|
|
|
|
|
CRL::AllianceFramework* framework = CRL::AllianceFramework::get();
|
|
|
|
|
|
|
|
UpdateSession::open();
|
|
|
|
|
|
|
|
Cell* demo = framework->createCell( "demo_cell_2" );
|
|
|
|
demo->setAbutmentBox( Box( DbU::fromLambda( 0.0)
|
|
|
|
, DbU::fromLambda( 0.0)
|
|
|
|
, DbU::fromLambda(135.0)
|
|
|
|
, DbU::fromLambda(110.0)
|
|
|
|
) );
|
|
|
|
|
|
|
|
// Instanciation & placement of "i1_xr2".
|
|
|
|
Cell* model = framework->getCell( "xr2_x1", CRL::Catalog::State::Views );
|
|
|
|
Instance* i1_xr2 = Instance::create( demo, "i1_xr2", model );
|
|
|
|
i1_xr2->setTransformation( Transformation( DbU::fromLambda( 0.0 )
|
|
|
|
, DbU::fromLambda( 0.0 )
|
|
|
|
, Transformation::Orientation::ID
|
|
|
|
) );
|
|
|
|
i1_xr2->setPlacementStatus( Instance::PlacementStatus::PLACED );
|
|
|
|
|
|
|
|
// Instanciation & placement of "i2_xr2".
|
|
|
|
model = framework->getCell( "xr2_x1", CRL::Catalog::State::Views );
|
|
|
|
Instance* i2_xr2 = Instance::create( demo, "i2_xr2", model );
|
|
|
|
i2_xr2->setTransformation( Transformation( DbU::fromLambda( 55.0 )
|
|
|
|
, DbU::fromLambda( 0.0 )
|
|
|
|
, Transformation::Orientation::ID
|
|
|
|
) );
|
|
|
|
i2_xr2->setPlacementStatus( Instance::PlacementStatus::PLACED );
|
|
|
|
|
|
|
|
// Instanciation & placement of "i3_a2".
|
|
|
|
model = framework->getCell( "a2_x2", CRL::Catalog::State::Views );
|
|
|
|
Instance* i3_a2 = Instance::create( demo, "i3_a2", model );
|
|
|
|
i3_a2->setTransformation( Transformation( DbU::fromLambda( 0.0 )
|
|
|
|
, DbU::fromLambda( 100.0 )
|
|
|
|
, Transformation::Orientation::MY
|
|
|
|
) );
|
|
|
|
i3_a2->setPlacementStatus( Instance::PlacementStatus::PLACED );
|
|
|
|
|
|
|
|
// Instanciation & placement of "i4_a2".
|
|
|
|
model = framework->getCell( "a2_x2", CRL::Catalog::State::Views );
|
|
|
|
Instance* i4_a2 = Instance::create( demo, "i4_a2", model );
|
|
|
|
i4_a2->setTransformation( Transformation( DbU::fromLambda( 55.0 )
|
|
|
|
, DbU::fromLambda( 100.0 )
|
|
|
|
, Transformation::Orientation::MY
|
|
|
|
) );
|
|
|
|
i4_a2->setPlacementStatus( Instance::PlacementStatus::PLACED );
|
|
|
|
|
|
|
|
// Instanciation & placement of "i1_xr2".
|
|
|
|
model = framework->getCell( "o2_x2", CRL::Catalog::State::Views );
|
|
|
|
Instance* i5_o2 = Instance::create( demo, "i5_o2", model );
|
|
|
|
i5_o2->setTransformation( Transformation( DbU::fromLambda( 110.0 )
|
|
|
|
, DbU::fromLambda( 0.0 )
|
|
|
|
, Transformation::Orientation::ID
|
|
|
|
) );
|
|
|
|
i5_o2->setPlacementStatus( Instance::PlacementStatus::PLACED );
|
|
|
|
|
|
|
|
UpdateSession::close();
|
|
|
|
|
|
|
|
return demo;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void TutorialEngine::runDemoPart2 ()
|
|
|
|
{
|
|
|
|
cerr << "TutorialEngine::runDemoPart2() has been called." << endl;
|
|
|
|
|
|
|
|
Cell* cell = getCell();
|
|
|
|
|
|
|
|
UpdateSession::open();
|
|
|
|
|
|
|
|
Net* net = Net::create( cell, "demo" );
|
|
|
|
Instance* i1_xr2 = cell->getInstance( "i1_xr2" );
|
|
|
|
Plug* plug = i1_xr2->getPlug( i1_xr2->getMasterCell()->getNet("q") );
|
|
|
|
plug->setNet( net );
|
|
|
|
|
|
|
|
RoutingPad* rp1 = RoutingPad::create( net, Occurrence(plug) );
|
|
|
|
rp1->setOnBestComponent( RoutingPad::BiggestArea );
|
|
|
|
|
|
|
|
Instance* i2_xr2 = cell->getInstance( "i2_xr2" );
|
|
|
|
plug = i2_xr2->getPlug( i2_xr2->getMasterCell()->getNet("i0") );
|
|
|
|
plug->setNet( net );
|
|
|
|
|
|
|
|
RoutingPad* rp2 = RoutingPad::create( net, Occurrence(plug) );
|
|
|
|
rp2->setOnBestComponent( RoutingPad::BiggestArea );
|
|
|
|
|
|
|
|
Instance* i4_a2 = cell->getInstance( "i4_a2" );
|
|
|
|
plug = i4_a2->getPlug( i4_a2->getMasterCell()->getNet("i0") );
|
|
|
|
plug->setNet( net );
|
|
|
|
|
|
|
|
RoutingPad* rp3 = RoutingPad::create( net, Occurrence(plug) );
|
|
|
|
rp3->setOnBestComponent( RoutingPad::BiggestArea );
|
|
|
|
|
|
|
|
UpdateSession::close();
|
|
|
|
Breakpoint::stop( 1, "RoutingPad createds" );
|
|
|
|
UpdateSession::open();
|
|
|
|
|
|
|
|
Technology* technology = DataBase::getDB()->getTechnology();
|
|
|
|
Layer* metal2 = technology->getLayer( "METAL2" );
|
|
|
|
Layer* metal3 = technology->getLayer( "METAL3" );
|
|
|
|
Layer* via1 = technology->getLayer( "VIA12" );
|
|
|
|
Layer* via2 = technology->getLayer( "VIA23" );
|
|
|
|
|
|
|
|
Contact* contact1 = Contact::create( rp1, via1, DbU::fromLambda( 0.0), DbU::fromLambda( 0.0) );
|
|
|
|
Contact* contact2 = Contact::create( rp2, via1, DbU::fromLambda( 0.0), DbU::fromLambda(-5.0) );
|
|
|
|
Contact* contact3 = Contact::create( rp3, via1, DbU::fromLambda( 0.0), DbU::fromLambda( 0.0) );
|
|
|
|
Contact* contact4 = Contact::create( net, via2, DbU::fromLambda(50.0), DbU::fromLambda(20.0) );
|
|
|
|
Contact* contact5 = Contact::create( net, via2, DbU::fromLambda(50.0), DbU::fromLambda(75.0) );
|
|
|
|
|
|
|
|
Horizontal::create( contact1, contact4, metal2, DbU::fromLambda(20.0), DbU::fromLambda(2.0) );
|
|
|
|
Horizontal::create( contact4, contact2, metal2, DbU::fromLambda(20.0), DbU::fromLambda(2.0) );
|
|
|
|
Horizontal::create( contact5, contact3, metal2, DbU::fromLambda(75.0), DbU::fromLambda(2.0) );
|
|
|
|
Vertical::create ( contact4, contact5, metal3, DbU::fromLambda(50.0), DbU::fromLambda(2.0) );
|
|
|
|
|
|
|
|
UpdateSession::close();
|
|
|
|
|
|
|
|
cout << "All components of " << net << endl;
|
|
|
|
for ( Component* component : net->getComponents() ) {
|
|
|
|
cout << "| " << component << endl;
|
|
|
|
}
|
|
|
|
Breakpoint::stop( 1, "Contacts and wires createds" );
|
|
|
|
UpdateSession::open();
|
|
|
|
|
|
|
|
contact5->destroy();
|
|
|
|
|
|
|
|
UpdateSession::close();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
string TutorialEngine::_getTypeName () const
|
|
|
|
{ return "Tutorial::TutorialEngine"; }
|
|
|
|
|
|
|
|
|
|
|
|
string TutorialEngine::_getString () const
|
|
|
|
{
|
|
|
|
ostringstream os;
|
|
|
|
os << "<" << "TutorialEngine " << _cell->getName () << ">";
|
|
|
|
return os.str();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Record* TutorialEngine::_getRecord () const
|
|
|
|
{
|
|
|
|
Record* record = Super::_getRecord ();
|
|
|
|
|
|
|
|
if (record) {
|
|
|
|
// Add new records here.
|
|
|
|
}
|
|
|
|
return record;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
} // Tutorial namespace.
|