move device to devicebackup

This commit is contained in:
Christophe Alexandre 2008-07-03 13:15:22 +00:00
parent af659752dc
commit 686b97f1ec
18 changed files with 1520 additions and 15 deletions

View File

@ -98,7 +98,7 @@ Transistor::Transistor(Library* library, const Name& name,
_source20(NULL), _source22(NULL),
_drain40(NULL), _drain42(NULL),
_grid00(NULL), _grid01(NULL), _grid30(NULL), _grid31(NULL),
_anonymous10(NULL), _anonymous11(NULL), _anonymous12(NULL)
_anonymous10(NULL), _anonymous11(NULL), _anonymous12(NULL), _anonymous50(NULL)
{}
@ -145,6 +145,24 @@ void Transistor::_postCreate() {
setTerminal(false);
}
void Transistor::setPolarity(const Polarity& polarity) {
UpdateSession::open();
if (polarity != _polarity) {
_polarity = polarity;
DataBase* db = DataBase::getDB();
Technology* technology = db->getTechnology();
if (_polarity == Polarity::N) {
_anonymous11->setLayer(getLayer(technology, "nImplant"));
_anonymous12->setLayer(getLayer(technology, "nImplant"));
} else {
_anonymous11->setLayer(getLayer(technology, "pImplant"));
_anonymous12->setLayer(getLayer(technology, "pImplant"));
}
createLayout();
}
UpdateSession::close();
}
void Transistor::createLayout() {
DataBase* db = DataBase::getDB();
if (!db) {
@ -168,10 +186,12 @@ void Transistor::createLayout() {
getLayer(techno, "cut0"), getLayer(techno, "active"))->getValue();
DbU::Unit spacingActivePoly = atechno->getPhysicalRule("minSpacing",
getLayer(techno, "active"), getLayer(techno, "poly"))->getValue();
DbU::Unit sourceDrainWidth = atechno->getPhysicalRule("minSourceDrainWidth",
DbU::Unit sourceDrainWidth = atechno->getPhysicalRule("minExtension",
getLayer(techno, "active"), getLayer(techno, "poly"))->getValue();
DbU::Unit extActiveCut0 = atechno->getPhysicalRule("minExtension",
getLayer(techno, "active"), getLayer(techno, "cut0"))->getValue();
DbU::Unit enclosurePPlusActive = atechno->getPhysicalRule("minEnclosure",
getLayer(techno, "nWell"), getLayer(techno, "active"))->getValue();
DbU::Unit enclosureImplantPoly = 0;
DbU::Unit enclosureGateImplant = 0;
DbU::Unit extImplantActive = 0;
@ -289,6 +309,7 @@ void Transistor::createLayout() {
DbU::Unit dx23 = x10;
DbU::Unit dy23 = _w;
//_anonymous11
DbU::Unit extension11_1 = enclosureGateImplant;
DbU::Unit extension11_2 = extImplantCut0 - x20;
@ -296,7 +317,7 @@ void Transistor::createLayout() {
DbU::Unit extension11_4 = max(max(extension11_1, extension11_2), extension11_3);
DbU::Unit x11 = extension11_4;
DbU::Unit x11 = -extension11_4;
extension11_1 = enclosureGateImplant + x00 + dx00;
extension11_2 = extImplantCut0 + x40 + dx40;
@ -312,9 +333,24 @@ void Transistor::createLayout() {
Box box11(x11, y11, x11 + dx11, y11 + dy11);
_anonymous11->setBoundingBox(box11);
#if 0
if (_polarity == Polarity::P) {
DbU::Unit x50 = x10 - enclosurePPlusActive;
DbU::Unit y50 = y10 - enclosurePPlusActive;
DbU::Unit dx50 = dx10 + 2 * enclosurePPlusActive;
DbU::Unit dy50 = dy10 + 2 * enclosurePPlusActive;
Box box50(x50, y50, x50 + dx50, y50 + dy50);
if (!_anonymous50) {
_anonymous50 = createPad(techno, _anonymous, "nWell");
}
_anonymous50->setBoundingBox(box50);
} else {
if (_anonymous50) {
_anonymous50->destroy();
_anonymous50 = NULL;
}
}
//setAbutmentBox(getAbutmentBox());
#endif
UpdateSession::close();
}

View File

@ -57,6 +57,10 @@ class Transistor : public Cell {
bool isRight() const { return _abutmentType == AbutmentType::RIGHT; };
bool isSingle() const { return _abutmentType == AbutmentType::SINGLE; };
void setW(DbU::Unit value) { _w = value; createLayout(); }
void setL(DbU::Unit value) { _l = value; createLayout(); }
void setPolarity(const Polarity& polarity);
virtual Record* _getRecord() const;
protected:
@ -75,7 +79,7 @@ class Transistor : public Cell {
Pad *_source20, *_source22;
Pad *_drain40, *_drain42;
Pad *_grid00, *_grid01, *_grid30, *_grid31;
Pad *_anonymous10, *_anonymous11, *_anonymous12;
Pad *_anonymous10, *_anonymous11, *_anonymous12, *_anonymous50;
Transistor(Library* library, const Name& name,
const Polarity& polarity,

View File

@ -0,0 +1,8 @@
INCLUDE_DIRECTORIES(${CHAMSIN_SOURCE_DIR}/src/dtr ${CHAMSIN_SOURCE_DIR}/src/analogic
${HURRICANE_INCLUDE_DIR})
#ADD_LIBRARY(device SHARED Device.cpp TrMos.cpp TrMos_PlaceRoute.cpp)
#
#TARGET_LINK_LIBRARIES(device analogic dtr hurricane)
#
#INSTALL(TARGETS device DESTINATION /lib)

View File

@ -0,0 +1,161 @@
// ****************************************************************************************************
// File: Device.cpp
// Authors: Wu YiFei
// Date : 21/12/2006
// ****************************************************************************************************
#include "Device.h"
#include "Transformation.h"
#include "Point.h"
#include "Instance.h"
#include "Box.h"
#include "Error.h"
#include "Cells.h"
#include "DtrAccess.h"
using namespace Hurricane;
// ****************************************************************************************************
// Static data function
// ****************************************************************************************************
static Instance * refins = NULL;
static set<Cell*> cellSet;
static void getAllCells(Cell* cell)
// ********************************
{
cellSet.insert(cell);
if(!(cell->isLeaf())){
for_each_instance(instance, cell->getInstances())
Cell * mastercell = instance->getMasterCell();
getAllCells(mastercell);
end_for
}
}
namespace DEVICE {
// ****************************************************************************************************
// Device implementation
// ****************************************************************************************************
Device::Device(Library* library, const Name& name)
// **************************************************************************
: Inherit(library, name)
{
}
void Device::_postCreate() {
Inherit::_postCreate();
//CDataBase* database = getCDataBase();
//CCatal* ccatal = database->getCCatal();
//CCatal::State* state = ccatal->getState(getName(), true);
//state->SetFlags(CCatal::State::LOGICAL|CCatal::State::PHYSICAL|CCatal::State::IN_MEMORY|CCatal::State::GDS, true);
//state->SetCell(this);
//state->SetLibrary(getLibrary());
}
void Device::SaveLogicalView()
// ***************************
{
cellSet.clear();
getAllCells(this);
//CDataBase * db = getCDataBase();
// set<Cell*>::iterator i = cellSet.begin(), j = cellSet.end();
//
// while(i!=j) {
// db->SaveCell(*i, CCatal::State::LOGICAL );
// i++;
// }
}
void Device::_Place(Instance* ins, const Transformation::Orientation& orientation, const Point& point)
// **************************************************************************************************
{
if(!ins) {
throw Error("Can't Place Instance : ins is NULL");
}
if(ins->isPlaced()) {
throw Error("Can't Place " + getString(ins) + " : it has already been placed");
}
Transformation transformation(Point(0,0), orientation);
Box orientedmastercellbox = transformation.getBox(ins->getMasterCell()->getAbutmentBox());
Point translation( point.getX() - orientedmastercellbox.getXMin()
, point.getY() - orientedmastercellbox.getYMin() );
Transformation transformation_ins = Transformation(translation, orientation);
ins->setTransformation(transformation_ins);
ins->setPlacementStatus(Instance::PlacementStatus::PLACED);
}
void Device::_setRefIns(Instance* ins) const
// *****************************************
{
if(!ins) {
throw Error("Can't SetRefIns : ref instance is NULL");
}
if(ins->isUnplaced()) {
throw Error("Can't SetRefIns : ref instance has't been placed");
}
refins = ins;
}
void Device::_PlaceRight(Instance* ins, const Transformation::Orientation& orientation, const Point& offset)
// ********************************************************************************************************
{
if(!ins) {
throw Error("Can't PlaceRight Instance : ins is NULL");
}
if(ins->isPlaced()) {
throw Error("Can't PlaceRight " + getString(ins) + " : it has already been placed");
}
if(!refins) {
throw Error("Can't Place Right " + getString(ins) + " : can't find refins");
}
Box refinsbox = refins->getAbutmentBox();
Transformation transformation(Point(0,0), orientation);
Box orientedmastercellbox = transformation.getBox(ins->getMasterCell()->getAbutmentBox());
Point translation( refinsbox.getXMax() - orientedmastercellbox.getXMin() + offset.getX()
, refinsbox.getYMin() - orientedmastercellbox.getYMin() + offset.getY() );
Transformation transformation_ins = Transformation(translation, orientation);
ins->setTransformation(transformation_ins);
ins->setPlacementStatus(Instance::PlacementStatus::PLACED);
refins = ins;
}
} // end namespace Device

View File

@ -0,0 +1,71 @@
// ****************************************************************************************************
// File: Device.h
// Authors: Wu YiFei
// Date : 21/12/2006
// ****************************************************************************************************
#ifndef DEVICE_H
#define DEVICE_H
#include "Cell.h"
using namespace Hurricane;
namespace DEVICE {
class Device : public Cell {
#if !defined(__DOXYGEN_PROCESSOR__)
// Types
// *****
public : typedef Cell Inherit;
// Attributes
// **********
// Constructors
// ************
protected : Device(Library* library, const Name& name);
protected : virtual void _postCreate();
#endif
// Operations
// **********
// public : virtual void Create(const char, const bool) = 0;
public : virtual void dses() = 0;
public : virtual void shape() = 0;
// public : virtual void Generate() = 0;
# if !defined(__DOXYGEN_PROCESSOR__)
public : virtual void SaveLogicalView();
public : virtual void SavePhysicalView() {};
// Accessors
// *********
// Updators
// ********
// Others
// ******
public : virtual void _Flush() = 0;
// Description of Layout
// **********************
public: void _Place(Instance* ins, const Transformation::Orientation& orientation, const Point& point);
public: void _setRefIns(Instance*) const;
public: void _PlaceRight(Instance* ins, const Transformation::Orientation& orientation, const Point& offset=Point());
#endif
};
}
#endif // DEVICE_H

View File

@ -0,0 +1,417 @@
// ****************************************************************************************************
// 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

View File

@ -0,0 +1,126 @@
// ****************************************************************************************************
// File: TrMos.h
// Authors: Wu YiFei
// Date : 21/12/2006
// ****************************************************************************************************
#ifndef TRMOS_H
#define TRMOS_H
#include "Net.h"
using namespace Hurricane;
#include "Transistor.h"
//#include "MetaTransistor.h"
#include "Device.h"
namespace DEVICE {
class TrMos : public Device {
public : enum PinName { D, G, S, B };
// Attributes
// *******************
// Structural parameter.
// ********************
private : Transistor::Polarity _polarity;
private : bool _isBsConnected;
private : unsigned _m;
// Parameter of the electric synthesis.
// ***********************************
/* to do */
// Physical parameter of realization.
// **********************************
/* Placement. */
private : bool _sourceIsFirst;
private : bool _hasDummy;
private : bool _hasRing;
/* Routing. */
private : vector<PinName> _lowPinOrder; // relative position of the connectors on the basis of the top.
private : vector<PinName> _highPinOrder;
private : map<Net*, Pin*> _mapNetToPinBoxInLeftSide;
private : map<Net*, Pin*> _mapNetToPinBoxInRightSide;
private : double _widthOfSourceWire; // by defect, minWidth, unit of valeur is Micro
private : double _widthOfDrainWire; // by defect, minWidth, unit of valeur is Micro
/* Others */
private : MetaTransistor * _tr1;
private : double _capaRouting;
private : list<Transistor*> _transistorList;
// Constructors
// ************
protected : TrMos(Library* library, const Name& name);
protected : virtual void _postCreate();
public : static TrMos* create(Library* library, const Name & name);
// Operations
// **********
public : virtual void dses() { /* to do */};
public : virtual void shape() { /* to do */};
public : void create(const Transistor::Polarity& polarity, const bool isbsconnected);
public : void generate(const unsigned m, const bool sourceisfirst, const bool hasring,
const unsigned nbsourcecolumn, const unsigned nbdraincolumn);
// Accessors
// *********
public : const Transistor::Polarity& getPolarity() const { return _polarity; };
public : unsigned getM() const { return _m; };
public : const double getWidthOfSourceWire() const { return _widthOfSourceWire; };
public : const double getWidthOfDrainWire() const { return _widthOfDrainWire; };
public : MetaTransistor* getTr1() const { return _tr1; };
// Updators
// ********
public : void setMosLength(const double length) { if(_tr1) _tr1->setLe(length); }
public : void setMosWidth(const double width) { if(_tr1) _tr1->setWe(width); }
public : void setWidthOfSourceWire(const double width) { _widthOfSourceWire = width; };
public : void setWidthOfDrainWire(const double width) { _widthOfDrainWire=width; };
public : void setLowPinOrder(const PinName, const PinName) ;
public : void setHighPinOrder(const PinName, const PinName) ;
// Predicats
// *********
public : bool isBsConnected() const { return _isBsConnected; };
public : bool sourceIsFirst() const { return _sourceIsFirst; };
public : bool hasRing() const { return _hasRing; };
# if !defined(__DOXYGEN_PROCESSOR__)
// Others
// ******
public: virtual string _getTypeName() const {return _TName("TrMos"); };
public: virtual string _getString() const;
public: virtual Record* _getRecord() const;
public: vector<PinName>& getLowPinOrder() { return _lowPinOrder; };
public: vector<PinName>& getHighPinOrder() { return _highPinOrder; };
public: map<Net*, Pin*>& getMapNetToPinBoxInLeftSide() { return _mapNetToPinBoxInLeftSide; };
public: map<Net*, Pin*>& getMapNetToPinBoxInRightSide() { return _mapNetToPinBoxInRightSide; };
public : virtual void _Flush();
protected : void _PlaceAndRoute();
#endif
};
}
#endif // TRMOS_H

View File

@ -0,0 +1,685 @@
// ****************************************************************************************************
// File: TrMos.cpp
// Authors: Wu YiFei
// Date : 21/12/2006
// ****************************************************************************************************
#include "TrMos.h"
#include "Instances.h"
#include "MetaTransistor.h"
#include "Net.h"
#include "Transistors.h"
#include "Box.h"
#include "UpdateSession.h"
#include "HyperNet.h"
#include "DataBase.h"
#include "Technology.h"
#include "Vertical.h"
#include "Horizontal.h"
#include "Pin.h"
#include "RdsUnit.h"
#include "Transistor.h"
#include "DtrAccess.h"
using namespace Hurricane;
#include "DeviceUtil.h"
namespace DEVICE{
// ****************************************************************************************************
// TrMos implementation
// ****************************************************************************************************
void TrMos::_PlaceAndRoute()
// *************************
{
// get Dtr Rules And Calculate the Size of AbutmentBox of Device.
// **************************************************************
DtrAccess * dtraccess = DtrAccess::getDtrAccess();
Transistor::Polarity polarity;
if(_polarity == Transistor::Polarity::P) polarity = Transistor::Polarity::N;
else polarity = Transistor::Polarity::P;
long minImpWidth = dtraccess->getSingleRdsRuleByLabel("RW_", getString(polarity), "IMP");
long minContWidth = dtraccess->getSingleRdsRuleByLabel(string("RW_CONT"));
long minAlu1Width = dtraccess->getSingleRdsRuleByLabel(string("RW_ALU1"));
long minVia1Width = dtraccess->getSingleRdsRuleByLabel(string("RW_VIA1"));
long rdImp = dtraccess->getSingleRdsRuleByLabel(string("RD_NIMP"));
long rdActive = dtraccess->getSingleRdsRuleByLabel(string("RD_ACTI"));
long rdAlu2 = dtraccess->getSingleRdsRuleByLabel(string("RD_ALU1"));
long reImpActi = dtraccess->getSingleRdsRuleByLabel("RE_", getString(polarity), "IMP_CONT");
long reActiContact = dtraccess->getSingleRdsRuleByLabel("RE_ACTI_CONT");
long reAlu1Contact = dtraccess->getSingleRdsRuleByLabel("RE_ALU1_CONT");
long reAlu1Via1 = dtraccess->getSingleRdsRuleByLabel("RE_ALU1_VIA1");
long minActiWidth = 2*reActiContact + minContWidth;
long widthOfSourceWire = ConvertRealToRdsUnit(_widthOfSourceWire);
long widthOfDrainWire = ConvertRealToRdsUnit(_widthOfDrainWire);
long widthOfActive = MAX_INTEGER(minActiWidth, minContWidth + 2*reActiContact);
long widthOfImp = MAX_INTEGER(widthOfActive + 2*reImpActi, minImpWidth);
// **************************************************************
// Placing .
// **************************************************************
Transformation::Orientation::Code internalTransCode = Transformation::Orientation::ID;
Unit horizontalMargin = 0; // the horizontal margin of trmos.
Unit verticalLowMargin = 0; // the vertical low margin of trmos.
Unit verticalHighMargin = 0; // the vertical high margin of trmos.
Unit fingerHeight = 0; // the height of trmos.
Instance * leftins = NULL;
Instance * rightins = NULL;
OccurrenceLocator locator = getLeafInstanceOccurrences().getLocator();
Instance * instance = dynamic_cast<Instance*>(locator.getElement().getEntity());;
fingerHeight = instance->getCell()->getBoundingBox().getHeight();
horizontalMargin = getUnit(RETURN_EVEN((long)(getValue(fingerHeight))/4));
verticalLowMargin = getUnit(RETURN_EVEN((long)(getValue(fingerHeight))/2));
verticalHighMargin = getUnit(RETURN_EVEN((long)(getValue(fingerHeight))/2));
verticalLowMargin = MAX_INTEGER(verticalLowMargin, getUnit(RETURN_EVEN(rdImp + widthOfImp/2 + widthOfSourceWire
+ rdAlu2 + widthOfActive + rdActive)) );
verticalHighMargin = MAX_INTEGER(verticalHighMargin, horizontalMargin + getUnit(2*rdAlu2 + 2*widthOfDrainWire) );
horizontalMargin = MAX_INTEGER(horizontalMargin, getUnit(RETURN_EVEN(rdImp + widthOfImp/2)) );
UpdateSession::open();
if(_m == 1 ) { // If there is only one finger.
_Place( instance, Transformation::Orientation::ID, Point( horizontalMargin, verticalLowMargin ) );
} else {
// get instance who's model's abutment type is Left or Right.
// ************************************************************
for_each_occurrence(occurrence, getLeafInstanceOccurrences())
instance = dynamic_cast<Instance*>(occurrence.getEntity());
Transistor * trans = dynamic_cast<Transistor*>(instance->getMasterCell());
if ( _sourceIsFirst ) {
if(trans->isLeft() && !leftins)
leftins = instance;
else if ( trans->isLeft() && leftins)
rightins = instance;
else if ( trans->isRight())
rightins = instance;
} else {
if(trans->isRight() && !leftins)
leftins = instance;
else if (trans->isRight() && leftins )
rightins = instance;
else if (trans->isLeft())
rightins = instance;
}
end_for
// You must place this first instance who's model is left finger in a point who's
// x, y are all pair.
// Because if you do this, you can be sure that all rectangle of this instance are
// correctly in the grille of fondor.
// ***********************************************************************************
if(_sourceIsFirst)
_Place( leftins, Transformation::Orientation::ID, Point(horizontalMargin, verticalLowMargin) );
else
_Place( leftins, Transformation::Orientation::MX, Point(horizontalMargin, verticalLowMargin) );
_setRefIns(leftins);
if(_sourceIsFirst) // internal Finger's transformation.
internalTransCode = Transformation::Orientation::MX;
else
internalTransCode = Transformation::Orientation::ID;
// Place internal finger.
// *********************
for_each_occurrence(occurrence, getLeafInstanceOccurrences())
Instance * instance = dynamic_cast<Instance*>(occurrence.getEntity());
if(instance==leftins || instance==rightins )
continue;
_PlaceRight( instance, internalTransCode);
if(internalTransCode == Transformation::Orientation::MX)
internalTransCode = Transformation::Orientation::ID;
else
internalTransCode = Transformation::Orientation::MX;
end_for
// Place the last finger.
// **********************
Transistor * trans = dynamic_cast<Transistor*>(rightins->getMasterCell());
if( trans->isRight())
_PlaceRight( rightins, Transformation::Orientation::ID);
else
_PlaceRight( rightins, Transformation::Orientation::MX);
}
UpdateSession::close();
// Set AbutmentBox.
// ****************
for_each_instance(instance, getInstances())
instance->unmaterialize();
instance->materialize();
end_for
UpdateSession::open();
cout <<"Bounding box of TrMos is "<<getString(getBoundingBox())<<endl;
setAbutmentBox(Box(0, 0,
getBoundingBox().getWidth() + 2*horizontalMargin,
getBoundingBox().getHeight() + verticalLowMargin + verticalHighMargin
)
);
// **************************************************************
// Routing .
// **************************************************************
Unit expectedInterval = getUnit(RETURN_EVEN((long)(getValue(horizontalMargin))/2));
Unit interval = 0;
Unit initialPosition = verticalLowMargin + fingerHeight + getUnit(rdAlu2 + widthOfDrainWire/2);
map<string, Unit> netName2PositionOfConnectorMap;
list<Box> routingZoneList;
list<Unit> sourcePositionList;
list<Unit> drainPositionList;
Unit sourceRoutingZoneWidth;
Unit drainRoutingZoneWidth;
DataBase * db = getDataBase();
if(!db) throw Error("Can't launch Trmos::PlaceAndRoute for " + getString(this) + " : can't find DataBase");
Layer * layerAlu1 = db->getTechnology()->getLayer(Name("ALU1"));
Layer * layerAlu2 = db->getTechnology()->getLayer(Name("ALU2"));
Layer * layerVia1 = db->getTechnology()->getLayer(Name("VIA1"));
Layer * layerActive = db->getTechnology()->getLayer(Name("ACTIVE"));
Layer * layerVia01 = db->getTechnology()->getLayer(Name("via01"));
Layer * layerVia12 = db->getTechnology()->getLayer(Name("via12"));
Layer * layerPoly = db->getTechnology()->getLayer(Name("POLY"));
Layer * layerNwell = db->getTechnology()->getLayer(Name("NWELL"));
Layer * layerCont = db->getTechnology()->getLayer(Name("CONT"));
Layer * layerImp = NULL;
if(_polarity == Transistor::Polarity::P)
layerImp = db->getTechnology()->getLayer(Name("NIMP"));
else
layerImp = db->getTechnology()->getLayer(Name("PIMP"));
Pin * pin = NULL; // For get the adresse of Created Pins.
long connectorPosition = 0;
cout << " Begin routage " << endl;
// Set position of four connectors.
// ********************************
vector<PinName>::iterator i = _highPinOrder.begin(),
j = _highPinOrder.end();
while(i!=j) {
if(*i == D)
netName2PositionOfConnectorMap[string("drain")] = initialPosition;
if(*i == G)
netName2PositionOfConnectorMap[string("grid")] = initialPosition;
interval = MAX_INTEGER(expectedInterval, getUnit(widthOfDrainWire + rdAlu2));
// initialPosition += horizontalMargin/2;
initialPosition += interval;
i++;
}
vector<PinName>::iterator m = _lowPinOrder.begin(),
n = _lowPinOrder.end();
//initialPosition = verticalMargin - horizontalMargin/2;
//initialPosition = verticalLowMargin - MAX_INTEGER(expectedInterval, getUnit(rdImp + widthOfImp/2));
initialPosition = verticalLowMargin - getUnit(rdImp + widthOfImp/2);
while(m!=n) {
if(*m == S)
netName2PositionOfConnectorMap[string("source")] = initialPosition;
if(*m == B)
netName2PositionOfConnectorMap[string("bulk")] = initialPosition;
interval = MAX_INTEGER(expectedInterval, getUnit(rdAlu2 + widthOfSourceWire));
initialPosition -= interval;
m++;
}
cout << " Main loop "<< endl;
// Main Routing Algorithm.
// ***********************
// Main Loop.
// **********
for_each_net(net, getNets()) // For all hypernets.
if(getString(net->getName())=="bulk" || getString(net->getName())=="BULK" )
continue;
// get Routing Zone.
// *****************
HyperNet hyperNet(Occurrence(net, Path()));
for_each_occurrence(occurrence, hyperNet.getNetOccurrences()) // For all net occurrences.
Net * net = dynamic_cast<Net*>(occurrence.getEntity());
Box routingZone;
if(net->getCell()->isLeaf()) {
Transistor * trans = dynamic_cast<Transistor*>(net->getCell());
if ( !trans )
throw Error("Can't launch Trmos::PlaceAndRoute for " + getString(this)
+ ", it is not a Transistor");
cout << getString(occurrence) << endl;
cout << getString(occurrence.getPath().getTransformation()) <<endl;
cout << getString((*(trans->_getMapNet2Box()))[net]) << endl;
// get Routing Zone.
// *****************
routingZone = occurrence.getPath().getTransformation().getBox((*(trans->_getMapNet2Box()))[net]);
routingZoneList.push_back(routingZone);
if(getString(net->getName())=="SOURCE") {
sourcePositionList.push_back(routingZone.getXCenter());
sourceRoutingZoneWidth = routingZone.getWidth();
}
else if (getString(net->getName())=="DRAIN") {
drainPositionList.push_back(routingZone.getXCenter());
drainRoutingZoneWidth = routingZone.getWidth();
}
}
end_for
cout <<"Print routing zone for " <<getString(net)<<endl;
list<Box>::iterator it_begin_listbox = routingZoneList.begin(),
it_end_listbox = routingZoneList.end();
while(it_begin_listbox != it_end_listbox)
{
cout<< getString(*it_begin_listbox) <<endl;
it_begin_listbox++;
}
cout <<"End Print Routing Zone for "<<getString(net)<<endl;
// Create routing line.
// ********************
list<Box>::iterator routingzonelist_begin_it = routingZoneList.begin(),
routingzonelist_end_it = routingZoneList.end();
connectorPosition = netName2PositionOfConnectorMap[getString(net->getName())];
cout << "Connector Position is " << netName2PositionOfConnectorMap[getString(net)] << endl;
while(routingzonelist_begin_it!=routingzonelist_end_it) {
Box routingZoneBox = *routingzonelist_begin_it;
// Create vertical line and Contact.
// ********************************
if(connectorPosition > routingZoneBox.getYMin()) {
Vertical::create(net, layerAlu1, routingZoneBox.getXCenter()
, routingZoneBox.getWidth() + getUnit(2*reAlu1Contact)
, routingZoneBox.getYMin() - getUnit(reAlu1Contact)
, connectorPosition);
}
else {
Vertical::create(net, layerAlu1, routingZoneBox.getXCenter()
, routingZoneBox.getWidth() + getUnit(2*reAlu1Contact)
, connectorPosition
, routingZoneBox.getYMax() + getUnit(reAlu1Contact) ) ;
}
Contact::create(net, layerVia12, routingZoneBox.getXCenter()
, connectorPosition
, getUnit(minVia1Width)
, getUnit(minVia1Width)
);
routingzonelist_begin_it ++ ;
}
// Create horizontal line.
// ***********************
long widthOfWire = 0;
if(getString(net->getName())=="source")
widthOfWire = widthOfSourceWire;
else if(getString(net->getName())=="drain")
widthOfWire = widthOfDrainWire;
else
widthOfWire = widthOfDrainWire;
Horizontal::create(net, layerAlu2, connectorPosition
, getUnit(widthOfWire)
, 0
, getAbutmentBox().getXMax()
);
// Create Two Pins.
// ****************
pin = Pin::create(net
, Name(getString(net->getName())+"_west")
, Pin::AccessDirection(Pin::AccessDirection::WEST)
, Pin::PlacementStatus(Pin::PlacementStatus::PLACED)
, layerAlu2
, getAbutmentBox().getXMin()
, connectorPosition
, getUnit(widthOfWire)
, getUnit(widthOfWire)
);
_mapNetToPinBoxInLeftSide[net] = pin;
pin = Pin::create(net
, Name(getString(net->getName())+"_east")
, Pin::AccessDirection(Pin::AccessDirection::EAST)
, Pin::PlacementStatus(Pin::PlacementStatus::PLACED)
, layerAlu2
, getAbutmentBox().getXMax()
, connectorPosition
, getUnit(widthOfWire)
, getUnit(widthOfWire)
);
_mapNetToPinBoxInRightSide[net] = pin;
routingZoneList.clear();
// End Of Main Loop.
// *****************
end_for
// Route Net Bulk.
// ***************
connectorPosition = netName2PositionOfConnectorMap[string("bulk")];
Net * netBulk = getNet(Name("bulk"));
if(!netBulk) // bulk and source are connected.
netBulk = getNet(Name("source"));
// Calculate the width of Contact Alu1.
// ************************************
long widthOfAlu1 = MAX_INTEGER( MAX_INTEGER(minAlu1Width, 2*reAlu1Contact + minContWidth), 2*reAlu1Via1 + minVia1Width);
Unit bulkPosition = netName2PositionOfConnectorMap[string("bulk")];
Unit sourcePosition = netName2PositionOfConnectorMap[string("source")];
Horizontal::create( netBulk
, layerImp
, bulkPosition
, getUnit(widthOfImp)
, 0 - getUnit(reImpActi)
, getAbutmentBox().getXMax() + getUnit(reImpActi)
);
Horizontal::create( netBulk
, layerActive
, bulkPosition
, getUnit(widthOfActive)
, 0
, getAbutmentBox().getXMax()
);
Horizontal::create( netBulk
, layerAlu2
, bulkPosition
, getUnit(widthOfSourceWire)
, 0
, getAbutmentBox().getXMax()
);
// Create Two Pins For Net bulk.
// *****************************
if(!_isBsConnected) {
pin = Pin::create(netBulk
, Name(getString(netBulk->getName())+"_west")
, Pin::AccessDirection(Pin::AccessDirection::WEST)
, Pin::PlacementStatus(Pin::PlacementStatus::PLACED)
, layerAlu2
, getAbutmentBox().getXMin()
, bulkPosition
, getUnit(widthOfSourceWire)
, getUnit(widthOfSourceWire)
);
_mapNetToPinBoxInLeftSide[netBulk] = pin;
pin = Pin::create(netBulk
, Name(getString(netBulk->getName())+"_east")
, Pin::AccessDirection(Pin::AccessDirection::EAST)
, Pin::PlacementStatus(Pin::PlacementStatus::PLACED)
, layerAlu2
, getAbutmentBox().getXMax()
, bulkPosition
, getUnit(widthOfSourceWire)
, getUnit(widthOfSourceWire)
);
_mapNetToPinBoxInRightSide[netBulk] = pin;
}
if( netName2PositionOfConnectorMap[string("source")] > netName2PositionOfConnectorMap[string("bulk")] ) {
// Source Is Upper Than Bulk.
cout << " Source is Upper Than Bulk" << endl;
list<Unit>::iterator i = sourcePositionList.begin(), j = sourcePositionList.end();
while(i!=j) {
cout << " ######### Create Contact ###########" <<endl;
Contact::create(netBulk, layerVia01, *i
, bulkPosition
, getUnit(minContWidth)
, getUnit(minContWidth)
);
Contact::create(netBulk, layerAlu1, *i
, bulkPosition
, getUnit(widthOfAlu1)
, getUnit(widthOfAlu1)
);
Contact::create(netBulk, layerVia12, *i
, bulkPosition
, getUnit(minVia1Width)
, getUnit(minVia1Width)
);
if( _isBsConnected ) { // If bulk and Source are connected.
cout << " B S is connected in " << *i << endl;
Vertical::create(netBulk, layerAlu1, *i
, sourceRoutingZoneWidth
, bulkPosition
, sourcePosition);
}
i++;
}
} else {
list<Unit>::iterator i , j;
if( _isBsConnected ) { // If bulk and Source are connected.
i = sourcePositionList.begin();
j = sourcePositionList.end();
}
else {
i = drainPositionList.begin();
j = drainPositionList.end();
}
while(i!=j) {
cout << " ######### Create Contact ###########" <<endl;
Contact::create(netBulk, layerVia01, *i
, bulkPosition
, getUnit(minContWidth)
, getUnit(minContWidth)
);
Contact::create(netBulk, layerAlu1, *i
, bulkPosition
, getUnit(widthOfAlu1)
, getUnit(widthOfAlu1)
);
Contact::create(netBulk, layerVia12, *i
, bulkPosition
, getUnit(minVia1Width)
, getUnit(minVia1Width)
);
i++;
}
}
// Create Ring.
// ************
if( _hasRing ) {
widthOfImp = MAX_INTEGER(minImpWidth, minActiWidth + 2*reImpActi);
Net * netRing = Net::create(this, Name("RING"));
// Create rectangle in IMPLANT.
// ***************************
Horizontal::create( netRing
, layerImp
, getAbutmentBox().getYMax()
, getUnit(widthOfImp)
, getAbutmentBox().getXMin() - getUnit(widthOfImp/2)
, getAbutmentBox().getXMax() + getUnit(widthOfImp/2)
);
Horizontal::create( netRing
, layerImp
, getAbutmentBox().getYMin()
, getUnit(widthOfImp)
, getAbutmentBox().getXMin() - getUnit(widthOfImp/2)
, getAbutmentBox().getXMax() + getUnit(widthOfImp/2)
);
Vertical::create(netRing
, layerImp
, getAbutmentBox().getXMin()
, getUnit(widthOfImp)
, getAbutmentBox().getYMin()
, getAbutmentBox().getYMax()
);
Vertical::create(netRing
, layerImp
, getAbutmentBox().getXMax()
, getUnit(widthOfImp)
, getAbutmentBox().getYMin()
, getAbutmentBox().getYMax()
);
// Create rectangle in Active.
// ***************************
Horizontal::create( netRing
, layerActive
, getAbutmentBox().getYMax()
, getUnit(minActiWidth)
, getAbutmentBox().getXMin() - getUnit(minActiWidth/2)
, getAbutmentBox().getXMax() + getUnit(minActiWidth/2)
);
Horizontal::create( netRing
, layerActive
, getAbutmentBox().getYMin()
, getUnit(minActiWidth)
, getAbutmentBox().getXMin() - getUnit(minActiWidth/2)
, getAbutmentBox().getXMax() + getUnit(minActiWidth/2)
);
Vertical::create(netRing
, layerActive
, getAbutmentBox().getXMin()
, getUnit(minActiWidth)
, getAbutmentBox().getYMin()
, getAbutmentBox().getYMax()
);
Vertical::create(netRing
, layerActive
, getAbutmentBox().getXMax()
, getUnit(minActiWidth)
, getAbutmentBox().getYMin()
, getAbutmentBox().getYMax()
);
}
// Create Caission NWELL if this is a PMOS.
// ****************************************
if(_polarity == Transistor::Polarity::P) {
Net * netCaisson = Net::create(this, Name("CAISSON"));
Contact::create(netCaisson, layerNwell
, getAbutmentBox().getXCenter()
, getAbutmentBox().getYCenter()
, getAbutmentBox().getWidth()
, getAbutmentBox().getHeight()
);
}
UpdateSession::close();
}
} // END OF NAMESPACE DEVICE

View File

@ -2,6 +2,7 @@
#define ATECHNOLOGY_H_
#include "hurricane/Property.h"
#include "hurricane/DbU.h"
using namespace Hurricane;
namespace Hurricane {

View File

@ -13,6 +13,7 @@ using namespace Hurricane;
#include "AEnv.h"
#include "ATechnology.h"
#include "Transistor.h"
#include "AnalogicViewer.h"
int main(int argc, char* argv[]) {
@ -35,16 +36,9 @@ int main(int argc, char* argv[]) {
if (!aTechnology) {
exit(56);
}
aTechnology->print();
DbU::Unit transistorMinL = aTechnology->getPhysicalRule("transistorMinL")->getValue();
DbU::Unit transistorMinW = aTechnology->getPhysicalRule("transistorMinW")->getValue();
AnalogicViewer* viewer = new AnalogicViewer(userLibrary);
DbU::Unit L = transistorMinL;
DbU::Unit W = 2 * transistorMinW;
Transistor* trans = Transistor::create(userLibrary, Name("TEST"), Transistor::Polarity::N, L, W);
trans->createLayout();
CellViewer* viewer = new CellViewer ( trans );
viewer->show();
returnCode = qa->exec();

View File

@ -1,10 +1,12 @@
include(${QT_USE_FILE})
qt4_wrap_cpp(MOC_SRCS AnalogicViewer.h)
include_directories(${HURRICANE_INCLUDE_DIR} ${HURRICANE_GRAPHICAL_INCLUDE_DIR}
${CORIOLIS_INCLUDE_DIR} ${CHAMSIN_SOURCE_DIR}/src/technology
${CHAMSIN_SOURCE_DIR}/src/analogic ${CHAMSIN_SOURCE_DIR}/src/device)
add_executable(atest AnalogicTest.cpp)
add_executable(atest AnalogicViewer.cpp ${MOC_SRCS} AnalogicTest.cpp)
target_link_libraries(atest atechnology analogic ${HURRICANE_LIBRARIES} ${HURRICANE_GRAPHICAL_LIBRARIES} ${QT_LIBRARIES})