MetaTransistor Layout in progress
This commit is contained in:
parent
1688959886
commit
60f05e0e57
|
@ -1,6 +1,7 @@
|
||||||
INCLUDE_DIRECTORIES(${CHAMSIN_SOURCE_DIR}/src/technology ${HURRICANE_INCLUDE_DIR})
|
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})
|
TARGET_LINK_LIBRARIES(analogic atechnology ${HURRICANE_LIBRARIES})
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,4 @@ Capacitor* Capacitor::create(Library* library, const Name& name) {
|
||||||
void Capacitor::_postCreate() {
|
void Capacitor::_postCreate() {
|
||||||
Inherit::_postCreate();
|
Inherit::_postCreate();
|
||||||
|
|
||||||
UpdateSession::open();
|
|
||||||
/////
|
|
||||||
UpdateSession::close();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
|
@ -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
|
|
@ -1,168 +1,165 @@
|
||||||
// ****************************************************************************************************
|
#include "hurricane/UpdateSession.h"
|
||||||
// File: MetaTransistor.cpp
|
|
||||||
// Authors: Wu YiFei
|
|
||||||
// Date : 21/12/2006
|
|
||||||
// ****************************************************************************************************
|
|
||||||
|
|
||||||
#include "UpdateSession.h"
|
|
||||||
using namespace Hurricane;
|
using namespace Hurricane;
|
||||||
|
|
||||||
#include "Transistor.h"
|
#include "Transistor.h"
|
||||||
#include "MetaTransistor.h"
|
#include "MetaTransistor.h"
|
||||||
|
|
||||||
namespace Hurricane {
|
namespace {
|
||||||
|
|
||||||
// ****************************************************************************************************
|
Transistor::Type metaTransistorTypeToTransistorType(const MetaTransistor::Type& type) {
|
||||||
// MetaTransistor implementation
|
switch (type) {
|
||||||
// ****************************************************************************************************
|
case MetaTransistor::Type::UNDEFINED:
|
||||||
|
return Transistor::Type::UNDEFINED;
|
||||||
MetaTransistor::MetaTransistor(Library* library, const Name& name, char type)
|
case MetaTransistor::Type::NMOS:
|
||||||
: Inherit(library, name),
|
return Transistor::Type::NMOS;
|
||||||
_type(type),
|
case MetaTransistor::Type::PMOS:
|
||||||
_m(1),
|
return Transistor::Type::PMOS;
|
||||||
_le(0.0),
|
default:
|
||||||
_we(0.0)
|
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() {
|
MetaTransistor::Type::Type(const Code& code):
|
||||||
// do something
|
_code(code)
|
||||||
// ************
|
{}
|
||||||
|
|
||||||
Inherit::_preDestroy();
|
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() {
|
void MetaTransistor::_postCreate() {
|
||||||
Inherit::_postCreate();
|
Inherit::_postCreate();
|
||||||
|
|
||||||
(Net::create(this, Name("DRAIN")))->setExternal(true);
|
_drain = Net::create(this, DrainName);
|
||||||
(Net::create(this, Name("SOURCE")))->setExternal(true);
|
_drain->setExternal(true);
|
||||||
(Net::create(this, Name("GRID")))->setExternal(true);
|
_source = Net::create(this, SourceName);
|
||||||
(Net::create(this, Name("BULK")))->setExternal(true);
|
_source->setExternal(true);
|
||||||
}
|
_grid = Net::create(this, GridName);
|
||||||
|
_grid->setExternal(true);
|
||||||
|
_bulk = Net::create(this, BulkName);
|
||||||
void MetaTransistor::createConnection()
|
_bulk->setExternal(true);
|
||||||
// ***********************************
|
_anonymous = Net::create(this, AnonymousName);
|
||||||
{
|
|
||||||
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);
|
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<Transistor*>(mastercell);
|
void MetaTransistor::setType(Type type) {
|
||||||
if(!trans){
|
if (type != _type) {
|
||||||
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::Flush()
|
|
||||||
// *************************
|
|
||||||
{
|
|
||||||
UpdateSession::open();
|
UpdateSession::open();
|
||||||
for_each_instance(instance, this->getInstances()) {
|
_type = type;
|
||||||
Cell * mastercell = instance->getMasterCell();
|
Transistor::Type ttype = metaTransistorTypeToTransistorType(_type);
|
||||||
instance->destroy();
|
for (Transistors::iterator tit = _transistors.begin();
|
||||||
mastercell->destroy();
|
tit != _transistors.end();
|
||||||
end_for
|
tit++) {
|
||||||
|
(*tit)->setType(ttype);
|
||||||
}
|
}
|
||||||
UpdateSession::close();
|
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Record* MetaTransistor::_getRecord() const
|
|
||||||
// ***************************************
|
void MetaTransistor::setM(unsigned m) {
|
||||||
{
|
assert(_transistors.size() == _m);
|
||||||
Record* record = Inherit::_getRecord();
|
assert(getInstances().getSize() == _m);
|
||||||
return record;
|
if (_m != m) {
|
||||||
|
UpdateSession::open();
|
||||||
|
if (m > _m) {
|
||||||
|
Library* library = getLibrary();
|
||||||
|
Transformation transformation;
|
||||||
|
for (unsigned i=_m; i<m; i++) {
|
||||||
|
string transistorNameStr(getString(getName()));
|
||||||
|
transistorNameStr += "_Transistor_" + getString(i);
|
||||||
|
Name transistorName(transistorNameStr);
|
||||||
|
Transistor* transistor = Transistor::create(library, transistorName);
|
||||||
|
transistor->setType(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::setW(DbU::Unit value) {
|
||||||
|
_w = value;
|
||||||
|
for (Transistors::iterator tit = _transistors.begin();
|
||||||
|
tit != _transistors.end();
|
||||||
|
tit++) {
|
||||||
|
(*tit)->setW(_w);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,55 +1,61 @@
|
||||||
#ifndef METATRANSISTOR_H
|
#ifndef METATRANSISTOR_H
|
||||||
#define METATRANSISTOR_H
|
#define METATRANSISTOR_H
|
||||||
|
|
||||||
#include "AnalogComponent.h"
|
#include "Device.h"
|
||||||
|
|
||||||
class MetaTransistor: public AnalogComponent {
|
class Transistor;
|
||||||
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 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);
|
Type& operator=(const Type& type);
|
||||||
|
operator const Code&() const {return _code;};
|
||||||
|
|
||||||
protected : virtual void _postCreate();
|
const Code& getCode() const {return _code;};
|
||||||
|
|
||||||
|
private:
|
||||||
|
Code _code;
|
||||||
|
};
|
||||||
|
|
||||||
// ********************************************
|
typedef deque<Transistor*> Transistors;
|
||||||
public : void createConnection();
|
|
||||||
|
|
||||||
// Create the layout of all motifs in this metatransistor.
|
static const Name DrainName;
|
||||||
// *******************************************************
|
static const Name SourceName;
|
||||||
public : void createLayout();
|
static const Name GridName;
|
||||||
|
static const Name BulkName;
|
||||||
|
static const Name AnonymousName;
|
||||||
|
|
||||||
|
static MetaTransistor* create(Library* library, const Name& name);
|
||||||
|
void updateLayout();
|
||||||
|
|
||||||
// Accessors
|
void setType(Type type);
|
||||||
// *********
|
void setM(unsigned m);
|
||||||
public : const Micro& getLe() const { return _le; };
|
void setW(DbU::Unit value);
|
||||||
public : const Micro& getWe() const { return _we; };
|
void setL(DbU::Unit value);
|
||||||
public : const char getType() const { return _type; };
|
|
||||||
public : const unsigned getM() const { return _m; };
|
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void _postCreate();
|
||||||
|
|
||||||
// Updators
|
private:
|
||||||
// ********
|
Net* _drain;
|
||||||
public : void setLe (const Micro le) { _le=le; };
|
Net* _source;
|
||||||
public : void setWe (const Micro we) { _we=we; };
|
Net* _grid;
|
||||||
public : void setType(const char type) { _type=type; };
|
Net* _bulk;
|
||||||
public : void setM (const unsigned m) { _m=m; };
|
Net* _anonymous;
|
||||||
|
Type _type;
|
||||||
|
unsigned _m;
|
||||||
|
DbU::Unit _l;
|
||||||
|
DbU::Unit _w;
|
||||||
|
Transistors _transistors;
|
||||||
|
|
||||||
|
MetaTransistor(Library* library, const Name& name);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
}
|
#endif // METATRANSISTOR_H
|
||||||
|
|
||||||
#endif // HURRICANE_METATRANSISTOR
|
|
||||||
|
|
|
@ -18,7 +18,4 @@ Resistor* Resistor::create(Library* library, const Name& name) {
|
||||||
void Resistor::_postCreate() {
|
void Resistor::_postCreate() {
|
||||||
Inherit::_postCreate();
|
Inherit::_postCreate();
|
||||||
|
|
||||||
UpdateSession::open();
|
|
||||||
/////
|
|
||||||
UpdateSession::close();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,8 +29,8 @@ class Transistor : public AnalogComponent {
|
||||||
|
|
||||||
static Transistor* create(Library* library, const Name& name);
|
static Transistor* create(Library* library, const Name& name);
|
||||||
void updateLayout();
|
void updateLayout();
|
||||||
void setType(Type type);
|
|
||||||
|
|
||||||
|
void setType(Type type);
|
||||||
void setW(DbU::Unit value) { _w = value; updateLayout(); }
|
void setW(DbU::Unit value) { _w = value; updateLayout(); }
|
||||||
void setL(DbU::Unit value) { _l = value; updateLayout(); }
|
void setL(DbU::Unit value) { _l = value; updateLayout(); }
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue