move device to devicebackup
This commit is contained in:
parent
af659752dc
commit
686b97f1ec
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -2,6 +2,7 @@
|
|||
#define ATECHNOLOGY_H_
|
||||
|
||||
#include "hurricane/Property.h"
|
||||
#include "hurricane/DbU.h"
|
||||
using namespace Hurricane;
|
||||
|
||||
namespace Hurricane {
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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})
|
||||
|
||||
|
|
Loading…
Reference in New Issue