diff --git a/chamsin/src/analogic/Transistor.cpp b/chamsin/src/analogic/Transistor.cpp index c01e2fa7..2fbd0b61 100644 --- a/chamsin/src/analogic/Transistor.cpp +++ b/chamsin/src/analogic/Transistor.cpp @@ -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(); } diff --git a/chamsin/src/analogic/Transistor.h b/chamsin/src/analogic/Transistor.h index 65f07637..36a099c3 100644 --- a/chamsin/src/analogic/Transistor.h +++ b/chamsin/src/analogic/Transistor.h @@ -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, diff --git a/chamsin/src/device/CMakeLists.txt b/chamsin/src/device_backup/CMakeLists.txt similarity index 100% rename from chamsin/src/device/CMakeLists.txt rename to chamsin/src/device_backup/CMakeLists.txt diff --git a/chamsin/src/device/Device.cpp b/chamsin/src/device_backup/Device.cpp similarity index 100% rename from chamsin/src/device/Device.cpp rename to chamsin/src/device_backup/Device.cpp diff --git a/chamsin/src/device/Device.h b/chamsin/src/device_backup/Device.h similarity index 100% rename from chamsin/src/device/Device.h rename to chamsin/src/device_backup/Device.h diff --git a/chamsin/src/device/TrMos.cpp b/chamsin/src/device_backup/TrMos.cpp similarity index 100% rename from chamsin/src/device/TrMos.cpp rename to chamsin/src/device_backup/TrMos.cpp diff --git a/chamsin/src/device/TrMos.h b/chamsin/src/device_backup/TrMos.h similarity index 100% rename from chamsin/src/device/TrMos.h rename to chamsin/src/device_backup/TrMos.h diff --git a/chamsin/src/device/TrMos_PlaceRoute.cpp b/chamsin/src/device_backup/TrMos_PlaceRoute.cpp similarity index 100% rename from chamsin/src/device/TrMos_PlaceRoute.cpp rename to chamsin/src/device_backup/TrMos_PlaceRoute.cpp diff --git a/chamsin/src/device_backup/device/CMakeLists.txt b/chamsin/src/device_backup/device/CMakeLists.txt new file mode 100644 index 00000000..9ae18f6b --- /dev/null +++ b/chamsin/src/device_backup/device/CMakeLists.txt @@ -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) diff --git a/chamsin/src/device_backup/device/Device.cpp b/chamsin/src/device_backup/device/Device.cpp new file mode 100644 index 00000000..e4208e20 --- /dev/null +++ b/chamsin/src/device_backup/device/Device.cpp @@ -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 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::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 diff --git a/chamsin/src/device_backup/device/Device.h b/chamsin/src/device_backup/device/Device.h new file mode 100644 index 00000000..79a47f96 --- /dev/null +++ b/chamsin/src/device_backup/device/Device.h @@ -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 diff --git a/chamsin/src/device/DeviceUtil.h b/chamsin/src/device_backup/device/DeviceUtil.h similarity index 100% rename from chamsin/src/device/DeviceUtil.h rename to chamsin/src/device_backup/device/DeviceUtil.h diff --git a/chamsin/src/device_backup/device/TrMos.cpp b/chamsin/src/device_backup/device/TrMos.cpp new file mode 100644 index 00000000..8eb6496c --- /dev/null +++ b/chamsin/src/device_backup/device/TrMos.cpp @@ -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 ***" <setM(_m); + + for(unsigned i=0; igetName()) + "_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 ***" <getM()) + ".\n" + << getString(_m) + " Transistors are created.\n" <createConnection(); + + //IF_DEBUG_HUR_ANALOG + cout << "*** Stage 2 : CreateLayout of " + getString(this) + " finish ***" <setLe(10); +// _tr1->setWe(11); + +/* (3) */ + //IF_DEBUG_HUR_ANALOG + cout << "*** Stage 3 : CreateLayout of " + getString(this) + " Begin ***" <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::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 ***" <_le) + "." << endl +// << "Real w of " << (long)_tr1 << getString(_tr1) + " is " + getString(_tr1->_we) + "." << endl +// <createLayout(); + + //IF_DEBUG_HUR_ANALOG + cout << "*** Stage 4 : CreateLayout of " + getString(this) + " finish ***"<setTransformation(instance->getTransformation()); + instance->unmaterialize(); + instance->materialize(); + +//IF_DEBUG_HUR_ANALOG + cout << getString(instance) <<" 's boundingBox is " << getString(instance->getBoundingBox())<::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::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 diff --git a/chamsin/src/device_backup/device/TrMos.h b/chamsin/src/device_backup/device/TrMos.h new file mode 100644 index 00000000..929811b4 --- /dev/null +++ b/chamsin/src/device_backup/device/TrMos.h @@ -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 _lowPinOrder; // relative position of the connectors on the basis of the top. + private : vector _highPinOrder; + + private : map _mapNetToPinBoxInLeftSide; + private : map _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 _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& getLowPinOrder() { return _lowPinOrder; }; + public: vector& getHighPinOrder() { return _highPinOrder; }; + + public: map& getMapNetToPinBoxInLeftSide() { return _mapNetToPinBoxInLeftSide; }; + public: map& getMapNetToPinBoxInRightSide() { return _mapNetToPinBoxInRightSide; }; + + public : virtual void _Flush(); + protected : void _PlaceAndRoute(); +#endif + +}; + +} + +#endif // TRMOS_H diff --git a/chamsin/src/device_backup/device/TrMos_PlaceRoute.cpp b/chamsin/src/device_backup/device/TrMos_PlaceRoute.cpp new file mode 100644 index 00000000..76ecb557 --- /dev/null +++ b/chamsin/src/device_backup/device/TrMos_PlaceRoute.cpp @@ -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(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(occurrence.getEntity()); + Transistor * trans = dynamic_cast(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(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(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 "< netName2PositionOfConnectorMap; + list routingZoneList; + list sourcePositionList; + list 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::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::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(occurrence.getEntity()); + Box routingZone; + + if(net->getCell()->isLeaf()) { + Transistor * trans = dynamic_cast(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()) <_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 " <::iterator it_begin_listbox = routingZoneList.begin(), + it_end_listbox = routingZoneList.end(); + + while(it_begin_listbox != it_end_listbox) + { + cout<< getString(*it_begin_listbox) <::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::iterator i = sourcePositionList.begin(), j = sourcePositionList.end(); + + while(i!=j) { + + cout << " ######### Create Contact ###########" <::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 ###########" <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(); diff --git a/chamsin/src/tests/CMakeLists.txt b/chamsin/src/tests/CMakeLists.txt index bf74e6a5..81e24db9 100644 --- a/chamsin/src/tests/CMakeLists.txt +++ b/chamsin/src/tests/CMakeLists.txt @@ -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})