diff --git a/chamsin/src/analogic/CMakeLists.txt b/chamsin/src/analogic/CMakeLists.txt index a65b6ef2..f7bf4c52 100644 --- a/chamsin/src/analogic/CMakeLists.txt +++ b/chamsin/src/analogic/CMakeLists.txt @@ -1,6 +1,7 @@ INCLUDE_DIRECTORIES(${CHAMSIN_SOURCE_DIR}/src/technology ${HURRICANE_INCLUDE_DIR}) -ADD_LIBRARY(analogic SHARED Transistor.cpp Capacitor.cpp Resistor.cpp) +ADD_LIBRARY(analogic SHARED Transistor.cpp Capacitor.cpp Resistor.cpp Device.cpp + MetaTransistor.cpp) TARGET_LINK_LIBRARIES(analogic atechnology ${HURRICANE_LIBRARIES}) diff --git a/chamsin/src/analogic/Capacitor.cpp b/chamsin/src/analogic/Capacitor.cpp index 1a38ecab..a2794249 100644 --- a/chamsin/src/analogic/Capacitor.cpp +++ b/chamsin/src/analogic/Capacitor.cpp @@ -18,7 +18,4 @@ Capacitor* Capacitor::create(Library* library, const Name& name) { void Capacitor::_postCreate() { Inherit::_postCreate(); - UpdateSession::open(); - ///// - UpdateSession::close(); } diff --git a/chamsin/src/analogic/Device.cpp b/chamsin/src/analogic/Device.cpp new file mode 100644 index 00000000..fb297584 --- /dev/null +++ b/chamsin/src/analogic/Device.cpp @@ -0,0 +1,24 @@ +#include "hurricane/UpdateSession.h" +using namespace Hurricane; + +#include "Device.h" + +Device::Device(Library* library, const Name& name): + AnalogComponent(library, name) +{} + +Device* Device::create(Library* library, const Name& name) { + Device* device = new Device(library, name); + + device->_postCreate(); + + return device; +} + +void Device::_postCreate() { + Inherit::_postCreate(); + + UpdateSession::open(); + ///// + UpdateSession::close(); +} diff --git a/chamsin/src/analogic/Device.h b/chamsin/src/analogic/Device.h new file mode 100644 index 00000000..7105b2da --- /dev/null +++ b/chamsin/src/analogic/Device.h @@ -0,0 +1,19 @@ +#ifndef DEVICE_H +#define DEVICE_H + +#include "AnalogComponent.h" + +class Device : public AnalogComponent { + public: + static Device* create(Library* library, const Name& name); + + protected: + void _postCreate(); + + protected: + + Device(Library* library, const Name& name); +}; + + +#endif // DEVICE_H diff --git a/chamsin/src/analogic/MetaTransistor.cpp b/chamsin/src/analogic/MetaTransistor.cpp index 1255c18f..93a9ddf3 100644 --- a/chamsin/src/analogic/MetaTransistor.cpp +++ b/chamsin/src/analogic/MetaTransistor.cpp @@ -1,168 +1,165 @@ -// **************************************************************************************************** -// File: MetaTransistor.cpp -// Authors: Wu YiFei -// Date : 21/12/2006 -// **************************************************************************************************** - -#include "UpdateSession.h" +#include "hurricane/UpdateSession.h" using namespace Hurricane; #include "Transistor.h" #include "MetaTransistor.h" -namespace Hurricane { +namespace { -// **************************************************************************************************** -// MetaTransistor implementation -// **************************************************************************************************** - -MetaTransistor::MetaTransistor(Library* library, const Name& name, char type) -: Inherit(library, name), - _type(type), - _m(1), - _le(0.0), - _we(0.0) -{ +Transistor::Type metaTransistorTypeToTransistorType(const MetaTransistor::Type& type) { + switch (type) { + case MetaTransistor::Type::UNDEFINED: + return Transistor::Type::UNDEFINED; + case MetaTransistor::Type::NMOS: + return Transistor::Type::NMOS; + case MetaTransistor::Type::PMOS: + return Transistor::Type::PMOS; + default: + throw Error("Unknown MetaTransistor Type"); + } } - -MetaTransistor* MetaTransistor::create(Library* library, const Name& name, char type) { - MetaTransistor* metatransistor = new MetaTransistor(library, name, type); - - metatransistor->_postCreate(); - - return metatransistor; } +const Name MetaTransistor::DrainName("DRAIN"); +const Name MetaTransistor::SourceName("SOURCE"); +const Name MetaTransistor::GridName("GRID"); +const Name MetaTransistor::BulkName("BULK"); +const Name MetaTransistor::AnonymousName("ANONYMOUS"); -void MetaTransistor::_preDestroy() { - // do something - // ************ - - Inherit::_preDestroy(); +MetaTransistor::Type::Type(const Code& code): + _code(code) +{} + +MetaTransistor::Type::Type(const Type& type): + _code(type._code) +{} + +MetaTransistor::Type& MetaTransistor::Type::operator=(const Type& type) { + _code = type._code; + return *this; } +MetaTransistor::MetaTransistor(Library* library, const Name& name): + Device(library, name), + _drain(NULL), + _source(NULL), + _grid(NULL), + _bulk(NULL), + _anonymous(NULL), + _type(), + _m(0), _l(0.0), _w(0.0), + _transistors() +{} + +MetaTransistor* MetaTransistor::create(Library* library, const Name& name) { + MetaTransistor* mTransistor = new MetaTransistor(library, name); + + mTransistor->_postCreate(); + + return mTransistor; +} void MetaTransistor::_postCreate() { - Inherit::_postCreate(); + Inherit::_postCreate(); - (Net::create(this, Name("DRAIN")))->setExternal(true); - (Net::create(this, Name("SOURCE")))->setExternal(true); - (Net::create(this, Name("GRID")))->setExternal(true); - (Net::create(this, Name("BULK")))->setExternal(true); + _drain = Net::create(this, DrainName); + _drain->setExternal(true); + _source = Net::create(this, SourceName); + _source->setExternal(true); + _grid = Net::create(this, GridName); + _grid->setExternal(true); + _bulk = Net::create(this, BulkName); + _bulk->setExternal(true); + _anonymous = Net::create(this, AnonymousName); + + setTerminal(false); +} + +void MetaTransistor::setType(Type type) { + if (type != _type) { + UpdateSession::open(); + _type = type; + Transistor::Type ttype = metaTransistorTypeToTransistorType(_type); + for (Transistors::iterator tit = _transistors.begin(); + tit != _transistors.end(); + tit++) { + (*tit)->setType(ttype); + } + UpdateSession::close(); + } } -void MetaTransistor::createConnection() -// *********************************** -{ - for_each_instance(instance, this->getInstances()) - Cell * mastercell = instance->getMasterCell(); - - // Assurance of unique instanciation - // ********************************* - if(mastercell->_getSlaveInstanceSet()._getSize()!=1) { - string err_msg = "Can't create connection : " + getString(mastercell) + " hasn't only one slave instance"; - assert(err_msg.c_str()); - } - - instance->getPlug(mastercell->getNet(Name("DRAIN")))->setNet(getNet(Name("DRAIN"))); - instance->getPlug(mastercell->getNet(Name("SOURCE")))->setNet(getNet(Name("SOURCE"))); - instance->getPlug(mastercell->getNet(Name("GRID")))->setNet(getNet(Name("GRID"))); - instance->getPlug(mastercell->getNet(Name("BULK")))->setNet(getNet(Name("BULK"))); - end_for -} - - -void MetaTransistor::createLayout() { - - if((_le == 0.0) || (_we == 0.0)) { - throw Error("Can't generate layout : " + getString(this) + " hasn't been dimensionned"); - } - - setTerminal(false); - - Transistor* internal_ref = NULL; - Transistor* left_ref = NULL; - Transistor* right_ref = NULL; - - for_each_instance(instance, this->getInstances()) - Cell * mastercell = instance->getMasterCell(); - - // Assurance of unique instanciation - // ********************************* - if(mastercell->_getSlaveInstanceSet()._getSize()!=1) { - string err_msg = "Can't generate layout : " + getString(mastercell) + " hasn't only one slave instance"; - assert(err_msg.c_str()); - } - - Transistor * trans = dynamic_cast(mastercell); - if(!trans){ - string err_msg = "Can't genrate layout : " + getString(mastercell) + " isn't a Transistor"; - } - - if(trans->isInternal()) { - if(!internal_ref) { - cerr << "akecoucou" << endl; - trans->createLayout(); - internal_ref = trans; - } else { - trans->duplicateLayout(internal_ref); - } - } else if(trans->isLeft()) { - if(!left_ref) { - trans->createLayout(); - left_ref=trans; - } else { - trans->duplicateLayout(left_ref); - } - } else if(trans->isRight()) { - if(!right_ref) { - trans->createLayout(); - right_ref=trans; - } else { - trans->duplicateLayout(right_ref); - } - } else { - trans->createLayout(); - } - end_for - - - materialize(); - +void MetaTransistor::setM(unsigned m) { + assert(_transistors.size() == _m); + assert(getInstances().getSize() == _m); + if (_m != m) { + UpdateSession::open(); + if (m > _m) { + Library* library = getLibrary(); + Transformation transformation; + for (unsigned i=_m; isetType(metaTransistorTypeToTransistorType(_type)); + transistor->setL(_l); + transistor->setW(_w); + _transistors.push_back(transistor); + Instance* instance = Instance::create(this, transistorName, + transistor, transformation, Instance::PlacementStatus::FIXED); + instance->getPlug(transistor->getNet(GridName))->setNet(_grid); + instance->getPlug(transistor->getNet(SourceName))->setNet(_source); + instance->getPlug(transistor->getNet(DrainName))->setNet(_drain); + instance->getPlug(transistor->getNet(BulkName))->setNet(_bulk); + } + } else { + for (unsigned i=m; i<_m; i++) { + Transistor* transistor = _transistors.back(); + transistor->destroy(); + _transistors.pop_back(); + } + } + UpdateSession::close(); + _m = m; + } } - -void MetaTransistor::Flush() -// ************************* -{ - UpdateSession::open(); - for_each_instance(instance, this->getInstances()) { - Cell * mastercell = instance->getMasterCell(); - instance->destroy(); - mastercell->destroy(); - end_for - } - UpdateSession::close(); -} - - - -string MetaTransistor::_getString() const -// *************************************** -{ - string s= Inherit::_getString(); - s.insert(s.length()-1, " " + getString(getType()) ); - s.insert(s.length()-1, " " + getString(getM()) ); - return s; +void MetaTransistor::setW(DbU::Unit value) { + _w = value; + for (Transistors::iterator tit = _transistors.begin(); + tit != _transistors.end(); + tit++) { + (*tit)->setW(_w); + } } -Record* MetaTransistor::_getRecord() const -// *************************************** -{ - Record* record = Inherit::_getRecord(); - return record; +void MetaTransistor::setL(DbU::Unit value) { + _l = value; + for (Transistors::iterator tit = _transistors.begin(); + tit != _transistors.end(); + tit++) { + (*tit)->setL(_l); + } + updateLayout(); } +void MetaTransistor::updateLayout() { + if (_m > 0) { + assert(_transistors.size() == _m); + assert(getInstances().getSize() == _m); + + Transformation transformation(0, 0); + + UpdateSession::open(); + for_each_instance(instance, getInstances()) { + instance->setTransformation(transformation); + Box abox = instance->getAbutmentBox(); + transformation = Transformation(transformation.getTx() + abox.getWidth(), 0); + end_for; + } + UpdateSession::close(); + } } diff --git a/chamsin/src/analogic/MetaTransistor.h b/chamsin/src/analogic/MetaTransistor.h index 4d3ee6a0..716d0c13 100644 --- a/chamsin/src/analogic/MetaTransistor.h +++ b/chamsin/src/analogic/MetaTransistor.h @@ -1,55 +1,61 @@ #ifndef METATRANSISTOR_H #define METATRANSISTOR_H -#include "AnalogComponent.h" +#include "Device.h" -class MetaTransistor: public AnalogComponent { - private : char _type; - private : unsigned _m; - private : Micro _le, _we; // length and width expected - private : Micro _lr, _wr; // real length and real width - private : unsigned _nSex, _nDex, nSin, _nDin, _nSsh, _nDsh; - private : Micro _dgg, _de; - private : MicroPower2 _as, _ad; - private : Micro _ps, _pd; - private : double _capaDrain, _capaGate, _capaSource; - private : double _cgb, _cgs, _cdb, _cds, _csb, _cgd; +class Transistor; +class MetaTransistor : public Device { + public: + class Type { + public: + enum Code {UNDEFINED=0, NMOS=1, PMOS=2}; - protected : MetaTransistor(Library* library, const Name& name, char type); + Type(const Code& code = UNDEFINED); + Type(const Type& type); - public : static MetaTransistor* create(Library* library, const Name& name, char type); - - protected : virtual void _postCreate(); + Type& operator=(const Type& type); + operator const Code&() const {return _code;}; + const Code& getCode() const {return _code;}; - // ******************************************** - public : void createConnection(); - - // Create the layout of all motifs in this metatransistor. - // ******************************************************* - public : void createLayout(); + private: + Code _code; + }; + typedef deque Transistors; -// Accessors -// ********* - public : const Micro& getLe() const { return _le; }; - public : const Micro& getWe() const { return _we; }; - public : const char getType() const { return _type; }; - public : const unsigned getM() const { return _m; }; + static const Name DrainName; + static const Name SourceName; + static const Name GridName; + static const Name BulkName; + static const Name AnonymousName; + static MetaTransistor* create(Library* library, const Name& name); + void updateLayout(); -// Updators -// ******** - public : void setLe (const Micro le) { _le=le; }; - public : void setWe (const Micro we) { _we=we; }; - public : void setType(const char type) { _type=type; }; - public : void setM (const unsigned m) { _m=m; }; + void setType(Type type); + void setM(unsigned m); + void setW(DbU::Unit value); + void setL(DbU::Unit value); + protected: + void _postCreate(); + private: + Net* _drain; + Net* _source; + Net* _grid; + Net* _bulk; + Net* _anonymous; + Type _type; + unsigned _m; + DbU::Unit _l; + DbU::Unit _w; + Transistors _transistors; + + MetaTransistor(Library* library, const Name& name); }; -} - -#endif // HURRICANE_METATRANSISTOR +#endif // METATRANSISTOR_H diff --git a/chamsin/src/analogic/Resistor.cpp b/chamsin/src/analogic/Resistor.cpp index 1f073870..49587698 100644 --- a/chamsin/src/analogic/Resistor.cpp +++ b/chamsin/src/analogic/Resistor.cpp @@ -18,7 +18,4 @@ Resistor* Resistor::create(Library* library, const Name& name) { void Resistor::_postCreate() { Inherit::_postCreate(); - UpdateSession::open(); - ///// - UpdateSession::close(); } diff --git a/chamsin/src/analogic/Transistor.h b/chamsin/src/analogic/Transistor.h index 79dc6529..92ab87f2 100644 --- a/chamsin/src/analogic/Transistor.h +++ b/chamsin/src/analogic/Transistor.h @@ -29,8 +29,8 @@ class Transistor : public AnalogComponent { static Transistor* create(Library* library, const Name& name); void updateLayout(); - void setType(Type type); + void setType(Type type); void setW(DbU::Unit value) { _w = value; updateLayout(); } void setL(DbU::Unit value) { _l = value; updateLayout(); }