coriolis/chamsin/src/device/TrMos.cpp

418 lines
12 KiB
C++

// ****************************************************************************************************
// File: TrMos.cpp
// Authors: Wu YiFei
// Date : 21/12/2006
// ****************************************************************************************************
#include "Instance.h"
#include "MetaTransistor.h"
#include "Net.h"
#include "Transistor.h"
#include "Transistors.h"
#include "UpdateSession.h"
#include "DtrAccess.h"
#include "TrMos.h"
using namespace Hurricane;
namespace DEVICE {
// ****************************************************************************************************
// TrMos implementation
// ****************************************************************************************************
TrMos::TrMos(Library* library, const Name& name):
Device(library, name),
_polarity(Transistor::N),
_isBsConnected(false),
_m(1),
_sourceIsFirst(true),
_hasDummy(false),
_hasRing(true),
_tr1(NULL),
_capaRouting(0)
{}
TrMos* TrMos::create(Library* library, const Name & name) {
TrMos* trmos= new TrMos(library, name);
trmos->_postCreate();
return trmos;
}
void TrMos::_postCreate() {
Inherit::_postCreate();
// do something.
// Initialize pin order list and other attributes.
// **********************************************
// _lowPinOrder[0]=D;
// _lowPinOrder[1]=G;
// _highPinOrder[0]=S;
// _highPinOrder[1]=B;
_highPinOrder.push_back(D);
_highPinOrder.push_back(G);
_lowPinOrder.push_back(S);
_lowPinOrder.push_back(B);
double minWidth = (DtrAccess::getDtrAccess())->getSingleRealRuleByLabel(string("RW_ALU1"));
_widthOfSourceWire = minWidth;
_widthOfDrainWire = minWidth;
}
void TrMos::create(const Transistor::Polarity& polarity, const bool isbsconnected)
{
if( _tr1 ) {
throw Error("Can't Create Logical View of TrMos " + getString(getName()) +
" : " + "it has already been created");
}
_polarity = polarity;
_isBsConnected = isbsconnected;
// MetaTransistor is in the same library than Trmos
// ************************************************
Library * library = getLibrary();
// Create signals
// **************
Net * drain = NULL;
Net * source = NULL;
Net * grid = NULL;
Net * bulk = NULL;
(drain = Net::create(this, Name("drain")))->setExternal(true);
(source = Net::create(this, Name("source")))->setExternal(true);
(grid = Net::create(this, Name("grid")))->setExternal(true);
if(!isbsconnected) {
(bulk = Net::create(this, Name("bulk")))->setExternal(true);
}
// Instancier a MetaTransistor and create the connection
// The name of MetaTransistor is nameoftrmos_tr1
// ****************************************************
_tr1 = MetaTransistor::create(library, Name( getString(getName())+"_Mos1" ), _polarity);
Instance * instance = Instance::create(this,
Name("Ins_" + getString(_tr1->getName())),
_tr1);
instance->getPlug(_tr1->getNet(Name("DRAIN")))->setNet(drain);
instance->getPlug(_tr1->getNet(Name("SOURCE")))->setNet(source);
instance->getPlug(_tr1->getNet(Name("GRID")))->setNet(grid);
if(!isbsconnected)
instance->getPlug(_tr1->getNet(Name("BULK")))->setNet(bulk);
else
instance->getPlug(_tr1->getNet(Name("BULK")))->setNet(source);
}
void TrMos::generate(const unsigned m, const bool sourceisfirst, const bool hasring
, const unsigned nbsourcecolumn, const unsigned nbdraincolumn)
// *********************************************************************************
{
if( !_tr1 ) {
throw Error("Can't Create Physical View for " + getString(this) +
" : " + "Logical view has't been created yet.");
}
// if( !(_transistorList.empty()) ) {
// throw Error("Can't Create Physical View of TrMos " + getString(getName()) + " : "
// + "it has already been created");
// }
// Check out param of realization.
// *******************************
if( m <= 0 )
throw Error("Can't generate for " + getString(this) + " : m "
+ getString(m) + " is invalid.");
if(nbsourcecolumn<1)
throw Error("Can't generate for " + getString(this)
+ " : nbsourcecolumn " + getString(nbsourcecolumn) + " is invalid.");
if(nbdraincolumn<1)
throw Error("Can't generate for" + getString(this) + " : nbdraincolumn "
+ getString(nbdraincolumn) + " is invalid.");
if(!(_transistorList.empty())) {
_Flush();
}
_m = m;
_sourceIsFirst = sourceisfirst;
_hasRing = hasring;
// Motifs are in the same library than Trmos
// *****************************************
Library * library = getLibrary();
cout << "################################################################" << endl <<
"#### BEGIN AUTOGENERATON FOR " + _getTypeName() + " " + getString(getName()) + " #####" << endl <<
"################################################################" << endl << endl;
// OpenUpdateSession();
/* (1) */
//IF_DEBUG_HUR_ANALOG
cout << "*** Stage 1 : CreateLayout of " + getString(this) + " Begin ***" <<endl;
//END_IF
// Create Motifs according to m, and instance the Motifs according
// to the Meta-Transistor .
// Set m of MetaTransistor.
// The name of motif is nameofDevice_nameofMetaTrans_finger_index
// ****************************************************************
_tr1->setM(_m);
for(unsigned i=0; i<m; i++){
Transistor* finger = Transistor::create(library,
getString(_tr1->getName()) + "_Finger_" + getString(i),
_polarity);
_transistorList.push_back(finger);
Instance::create(_tr1, Name("Ins_" + getString(finger->getName())), finger);
}
//IF_DEBUG_HUR_ANALOG
cout << "*** Stage 1 : CreateLayout of " + getString(this) + " finish ***" <<endl;
cout << getString(_tr1) + " 's M is " + getString(_tr1->getM()) + ".\n"
<< getString(_m) + " Transistors are created.\n" <<endl;
//END_IF
/* (2) */
//IF_DEBUG_HUR_ANALOG
cout << "*** Stage 2 : CreateLayout of " + getString(this) + " Begin ***" <<endl;
//END_IF
// Create connexion for each MetaTransistor.
// *****************************************
_tr1->createConnection();
//IF_DEBUG_HUR_ANALOG
cout << "*** Stage 2 : CreateLayout of " + getString(this) + " finish ***" <<endl;
cout << " The connection in " + getString(_tr1) + " is created.\n"
<<endl;
//END_IF
// Pseudo dimensionnement of metatransistor.
// In the futur, this will be the work of auto-dimensionnement tool (DSES).
// ************************************************************************
// _tr1->setLe(10);
// _tr1->setWe(11);
/* (3) */
//IF_DEBUG_HUR_ANALOG
cout << "*** Stage 3 : CreateLayout of " + getString(this) + " Begin ***" <<endl;
//END_IF
// Set dessin Parameter of generation for each finger.
// ***************************************************
double l_finger = _tr1->getLe() ;
double w_finger = (_tr1->getWe()) / (double)(_tr1->getM()) ;
unsigned count = 0;
Transistor::MaskV1Info * masqueinfo = new Transistor::MaskV1Info(l_finger, w_finger);
masqueinfo->setNbSourceColumn(nbsourcecolumn);
masqueinfo->setNbDrainColumn(nbdraincolumn);
list<Transistor*>::iterator i = _transistorList.begin()
, j = _transistorList.end();
if(_m == 1) {
masqueinfo->setType(Transistor::Type::SINGLE);
(*(_transistorList.begin()))->setMaskInfo(masqueinfo);
} else if(_m%2==0) { // if m is pair, create two left fingers if is source first.
// and create two right fingers if is drain first.
while(i!=j) {
if(++count>2)
masqueinfo->setType(Transistor::Type::INTERNAL);
else {
if ( _sourceIsFirst )
masqueinfo->setType(Transistor::Type::LEFT);
else
masqueinfo->setType(Transistor::Type::RIGHT);
}
(*i)->setMaskInfo(masqueinfo);
i++;
}
} else if(_m%2==1) { // if m is impair, create one left finger, one right finger.
while(i!=j){
++ count ;
if (count == 1)
masqueinfo-> setType(Transistor::Type::LEFT);
else if (count == 2)
masqueinfo-> setType(Transistor::Type::RIGHT);
else
masqueinfo-> setType(Transistor::Type::INTERNAL);
(*i)->setMaskInfo(masqueinfo);
i++;
}
}
delete masqueinfo;
//IF_DEBUG_HUR_ANALOG
cout << "*** Stage 3 : CreateLayout of " + getString(this) + " finish ***" <<endl;
cout << "Real l_finger is " + getString(l_finger) + "." << endl
<< "Real w_finger is " + getString(w_finger) + "." << endl
<<endl;
//END_IF
/* (4) */
//IF_DEBUG_HUR_ANALOG
cout << "*** Stage 4 : CreateLayout of " + getString(this) + " Begin ***" <<endl;
cout << "Call GenerateLayout for " + getString(_tr1)
+ " who will launch the generator of its fingers" << ".\n"
<<endl;
//END_IF
// Call function CreateLayout of MetaTransistor to launch the generator of finger.
// *******************************************************************************
setTerminal(false);
//
// IF_DEBUG_HUR_ANALOG
// cout << endl;
// cout << "Real l of " << (long)_tr1 << getString(_tr1) + " is " + getString(_tr1->_le) + "." << endl
// << "Real w of " << (long)_tr1 << getString(_tr1) + " is " + getString(_tr1->_we) + "." << endl
// <<endl;
// END_IF
//
_tr1->createLayout();
//IF_DEBUG_HUR_ANALOG
cout << "*** Stage 4 : CreateLayout of " + getString(this) + " finish ***"<<endl
<< endl;
//END_IF
/* (5) */
// Lauch Algo of Placement and routage selected.
// *********************************************
/* to do */
_PlaceAndRoute();
cout << " Place And Route " <<endl;
for_each_instance(instance, getInstances())
//instance->setTransformation(instance->getTransformation());
instance->unmaterialize();
instance->materialize();
//IF_DEBUG_HUR_ANALOG
cout << getString(instance) <<" 's boundingBox is " << getString(instance->getBoundingBox())<<endl;
//END_IF
end_for
// CloseUpdateSession();
//IF_DEBUG_HUR_ANALOG
cout << getString(this) << " 's primary (without wire) boundingBox is " << getString(getBoundingBox()) <<endl;
//END_IF
materialize();
//IF_DEBUG_HUR_ANALOG
cout << getString(this) << " 's boundingBox is " << getString(getBoundingBox()) <<endl;
//END_IF
cout << endl
<< "################################################################" <<endl
<< "#### END AUTOGENERATON FOR " + _getTypeName() + " " + getString(getName()) + " #####" <<endl
<< "################################################################" <<endl
<< endl;
}
void TrMos::setLowPinOrder(const PinName pin1, const PinName pin2)
// ***************************************************************
{
_lowPinOrder[0]=pin1;
_lowPinOrder[1]=pin2;
vector<PinName>::iterator i = _lowPinOrder.begin(), j = _lowPinOrder.end();
cout << " Low Pin Order " << endl;
while(i!=j) {
cout << *i << endl;
i++;
}
}
void TrMos::setHighPinOrder(const PinName pin1, const PinName pin2)
// *****************************************************************
{
_highPinOrder[0]=pin1;
_highPinOrder[1]=pin2;
vector<PinName>::iterator i = _highPinOrder.begin(), j = _highPinOrder.end();
cout << " High Pin Order " << endl;
while(i!=j) {
cout << *i << endl;
i++;
}
}
void TrMos::_Flush()
// ****************
{
if(_transistorList.empty()) {
throw Error("Can't delete Physical View of TrMos " + getString(getName()) + " : " + "il doesn't exist");
}
_tr1->Flush();
_transistorList.clear();
// Delete all segments of TrMos
// ****************************
/* to do */
}
string TrMos::_getString() const
// ***************************************
{
string s= Inherit::_getString();
return s;
}
Record* TrMos::_getRecord() const
// *********************************
{
Record* record = Inherit::_getRecord();
return record;
}
} // end of namespace Device