Import project Chamsin
This commit is contained in:
parent
9e9ad197d5
commit
be5efacffd
|
@ -0,0 +1,15 @@
|
||||||
|
PROJECT(CHAMSIN)
|
||||||
|
|
||||||
|
CMAKE_MINIMUM_REQUIRED(VERSION 2.4.0)
|
||||||
|
|
||||||
|
SET(CMAKE_MODULE_PATH "$ENV{HURRICANE_TOP}/share/cmake_modules/")
|
||||||
|
|
||||||
|
FIND_PACKAGE(BISON REQUIRED)
|
||||||
|
FIND_PACKAGE(FLEX REQUIRED)
|
||||||
|
find_package(HURRICANE REQUIRED)
|
||||||
|
#FIND_PACKAGE(Doxygen)
|
||||||
|
|
||||||
|
ADD_SUBDIRECTORY(src)
|
||||||
|
#IF(DOXYGEN_FOUND)
|
||||||
|
# ADD_SUBDIRECTORY(doc)
|
||||||
|
#ENDIF(DOXYGEN_FOUND)
|
|
@ -0,0 +1,4 @@
|
||||||
|
ADD_SUBDIRECTORY(analogic)
|
||||||
|
ADD_SUBDIRECTORY(dtr)
|
||||||
|
ADD_SUBDIRECTORY(device)
|
||||||
|
ADD_SUBDIRECTORY(tests)
|
|
@ -0,0 +1,45 @@
|
||||||
|
// ****************************************************************************************************
|
||||||
|
// File: AnalogicalCommons.h
|
||||||
|
// Authors: Wu YiFei
|
||||||
|
// Date : 21/12/2006
|
||||||
|
// ****************************************************************************************************
|
||||||
|
|
||||||
|
#ifndef HURRICANE_ANALOGICALCOMMONS
|
||||||
|
#define HURRICANE_ANALOGICALCOMMONS
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// *********************************************************************
|
||||||
|
// Macros Declaration.
|
||||||
|
// *********************************************************************
|
||||||
|
|
||||||
|
# define TRANSN 'N'
|
||||||
|
# define TRANSP 'P'
|
||||||
|
|
||||||
|
|
||||||
|
# define MAXNBCONTACT 8
|
||||||
|
|
||||||
|
# define IF_DEBUG_HUR_ANALOG \
|
||||||
|
if(getenv("DEBUG_HUR_ANALOG")) {
|
||||||
|
|
||||||
|
# ifndef END_IF
|
||||||
|
# define END_IF \
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
|
||||||
|
|
||||||
|
// *********************************************************************
|
||||||
|
// Analogical Unit declaration.
|
||||||
|
// *********************************************************************
|
||||||
|
# if !defined(__DOXYGEN_PROCESSOR__)
|
||||||
|
|
||||||
|
typedef double Micro;
|
||||||
|
typedef double MicroPower2;
|
||||||
|
typedef long Nano;
|
||||||
|
|
||||||
|
# endif
|
||||||
|
|
||||||
|
#include "TwoSpaces.h"
|
||||||
|
|
||||||
|
|
||||||
|
#endif // HURRICANE_ANALOGICALCOMMONS
|
|
@ -0,0 +1,12 @@
|
||||||
|
INCLUDE_DIRECTORIES(${CHAMSIN_SOURCE_DIR}/src/dtr ${HURRICANE_INCLUDE_DIR} ${source_dir})
|
||||||
|
|
||||||
|
ADD_LIBRARY(analogic SHARED
|
||||||
|
GenV1Trans.cpp
|
||||||
|
MetaTransistor.cpp
|
||||||
|
RdsUnit.cpp
|
||||||
|
Transistor.cpp
|
||||||
|
TwoSpaces.cpp)
|
||||||
|
|
||||||
|
TARGET_LINK_LIBRARIES(analogic ${HURRICANE_LIBRARIES})
|
||||||
|
|
||||||
|
INSTALL(TARGETS analogic DESTINATION /lib)
|
|
@ -0,0 +1,220 @@
|
||||||
|
// ****************************************************************************************************
|
||||||
|
// File: GenTrans.h
|
||||||
|
// Authors: Wu YiFei
|
||||||
|
// Date : 04/04/2007
|
||||||
|
// ****************************************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef HURRICANE_GENTRANS
|
||||||
|
#define HURRICANE_GENTRANS
|
||||||
|
|
||||||
|
|
||||||
|
#include "Transistor.h"
|
||||||
|
#include "Box.h"
|
||||||
|
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------
|
||||||
|
// Macro Method : "MAXLONG(a,b), MINLONG(a,b)"
|
||||||
|
// Comparaison Method Macro For Calculate Rectangles.
|
||||||
|
|
||||||
|
#define MAXLONG(a,b) (a>b?a:b)
|
||||||
|
#define MINLONG(a,b) (a>b?b:a)
|
||||||
|
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------
|
||||||
|
// Macro Method : "GET_RULE(s)"
|
||||||
|
// This Method Macro is For Geting The Value in RdsUnit of a DRM Rule.
|
||||||
|
// To Use This Macro, you must predefine Pointeur dtraccess.
|
||||||
|
|
||||||
|
#define GET_RULE(s) \
|
||||||
|
dtraccess->GetSingleRdsRuleByLabel(string(s))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------
|
||||||
|
// Macro Method "GET_RULE_BYNP(prefix, type, suffix)"
|
||||||
|
// This Method Macro is For Geting The Value in RdsUnit of a DRM Rule
|
||||||
|
// selected by string type which is mostype .
|
||||||
|
|
||||||
|
/* \prefix must be a chain character.
|
||||||
|
* \type mos type('N'/'P'), must be a string.
|
||||||
|
* \suffix must be a chain character.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// To Use This Macro, you must Predefine Pointeur dtraccess.
|
||||||
|
|
||||||
|
#define GET_RULE_BYNP(prefix, type, suffix) \
|
||||||
|
dtraccess->GetSingleRdsRuleByLabel(prefix, type, suffix)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------
|
||||||
|
// Macro Method : "Get_LAYER_BYNP(prefix, type, suffix)"
|
||||||
|
// This Method Macro is For Geting the Layer of a Layer Rule Selected
|
||||||
|
// by string type which is mostype. To Use This Macro, you must predefine
|
||||||
|
// Pointeur dtraccess.
|
||||||
|
|
||||||
|
/* \prefix must be a chain of character.
|
||||||
|
* \type mos type('N'/'P'), must be a string.
|
||||||
|
* \suffix must be a string.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// To Use This Macro, you must Predefine Pointeur dtraccess.
|
||||||
|
|
||||||
|
#define GET_LAYER_BYNP(prefix, type, suffix) \
|
||||||
|
dtraccess->GetSingleLayerByLabel(prefix, type, suffix)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------
|
||||||
|
// Macro Method : "SAVE_RECTANGLE(S, x, y, dx, dy)"
|
||||||
|
// This Method Macro is For Saving A Rectangle in a map .
|
||||||
|
|
||||||
|
/* \s name of rectangle, must be a chain of character.
|
||||||
|
* \x xmin, must be a long.
|
||||||
|
* \y ymin, must be a long.
|
||||||
|
* \dx width, must be a long.
|
||||||
|
* \dy height, must be a long.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// This Method Macro must be used in Membre Function Calculate.
|
||||||
|
|
||||||
|
#define SAVE_RECTANGLE(s, x, y, dx, dy) \
|
||||||
|
_mapString2Box[string(s)] = Box(GetUnit(x), GetUnit(y), GetUnit(x+dx), GetUnit(y+dy)); \
|
||||||
|
xmin = MINLONG(xmin, GetUnit(x)); \
|
||||||
|
ymin = MINLONG(ymin, GetUnit(y));
|
||||||
|
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------
|
||||||
|
// Macro Method : "GET_BOX(s)"
|
||||||
|
// This Method Macro is For Get the box According to the its name.
|
||||||
|
|
||||||
|
/*
|
||||||
|
* \s name of rectangle, must be a string.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// This Method Macro must be used in member function of Class GenTrans.
|
||||||
|
//
|
||||||
|
|
||||||
|
#define GET_BOX(s) \
|
||||||
|
_mapString2Box[s]
|
||||||
|
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
// Macro Method : "CREATE_CONTACT_MATRIX_UNDER(boxname, nbcolumn, layer, net)"
|
||||||
|
// This Method Macro is For Create a matrix of Contact under a zone for
|
||||||
|
// a net specified.
|
||||||
|
|
||||||
|
/* \underbox A rectangle under which contacts will be placed, must be a objet Box.
|
||||||
|
* \nbcolumn the number of column, must be a integer.
|
||||||
|
* \layer the layer of contact, must be a pointer of type Layer*.
|
||||||
|
* \net the net to be hooked, must be a pointer of type Net*.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// To use this Macro Function. You Must also définir variable nbcontact,
|
||||||
|
// tmp_xcenter, tmp_ycenter, rw_cont, rd_cont.
|
||||||
|
//
|
||||||
|
|
||||||
|
#define CREATE_CONTACT_MATRIX_UNDER(underbox, nbcolumn, layer, net) \
|
||||||
|
\
|
||||||
|
if(underbox.getHeight()<rw_cont) \
|
||||||
|
nbcontact = 0; \
|
||||||
|
else \
|
||||||
|
nbcontact = (underbox.getHeight()-rw_cont)/(rw_cont + rd_cont) + 1 ;\
|
||||||
|
\
|
||||||
|
\
|
||||||
|
tmp_xcenter = underbox.getXMin() + (rw_cont/2); \
|
||||||
|
tmp_ycenter = underbox.getYMin() + (rw_cont/2); \
|
||||||
|
\
|
||||||
|
\
|
||||||
|
for(unsigned i=0; i<nbcolumn; i++) { \
|
||||||
|
\
|
||||||
|
for(unsigned j=0; j<nbcontact; j++) { \
|
||||||
|
Contact::Create(net, layer \
|
||||||
|
, tmp_xcenter \
|
||||||
|
, tmp_ycenter \
|
||||||
|
, rw_cont \
|
||||||
|
, rw_cont \
|
||||||
|
); \
|
||||||
|
\
|
||||||
|
tmp_ycenter += (rw_cont + rd_cont); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
tmp_xcenter += (rw_cont + rd_cont); \
|
||||||
|
tmp_ycenter = underbox.getYMin() + (rw_cont/2); \
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------
|
||||||
|
// Macro Function : "BOX_IS_VALID(box)"
|
||||||
|
// This Macro Function is for check if the box is correctly in the
|
||||||
|
// grille of fondor. It will check if the value of x,y,dx,dy are all
|
||||||
|
// pair.
|
||||||
|
|
||||||
|
/*
|
||||||
|
* box the box is to check. must be a objet Box.
|
||||||
|
*/
|
||||||
|
|
||||||
|
# define BOX_IS_VALID(box) \
|
||||||
|
( (long)(GetValue(box.getXMin()))%2==0 )&& \
|
||||||
|
( (long)(GetValue(box.getXMax()))%2==0 )&& \
|
||||||
|
( (long)(GetValue(box.getYMin()))%2==0 )&& \
|
||||||
|
( (long)(GetValue(box.getYMax()))%2==0 )
|
||||||
|
|
||||||
|
|
||||||
|
BEGIN_NAMESPACE_HURRICANE
|
||||||
|
|
||||||
|
|
||||||
|
class GenTrans {
|
||||||
|
// *************
|
||||||
|
|
||||||
|
// Attributes
|
||||||
|
// **********
|
||||||
|
protected : map<string, Box> _mapString2Box;
|
||||||
|
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
// *************
|
||||||
|
public : GenTrans() {};
|
||||||
|
|
||||||
|
// Destructors
|
||||||
|
// ***********
|
||||||
|
public : virtual ~GenTrans() {};
|
||||||
|
|
||||||
|
// Operators
|
||||||
|
// **********
|
||||||
|
public : virtual void Calculate(Transistor*) = 0;
|
||||||
|
public : virtual void Generate(Transistor*) = 0;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class GenV1Trans : public GenTrans {
|
||||||
|
// *********************************
|
||||||
|
|
||||||
|
// Types
|
||||||
|
// *****
|
||||||
|
public : typedef GenTrans Inherit;
|
||||||
|
|
||||||
|
// Attributs
|
||||||
|
// *********
|
||||||
|
public : const Transistor::MaskV1Info* _masqueV1Info;
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
// ************
|
||||||
|
public : GenV1Trans(Transistor::MaskV1Info*);
|
||||||
|
|
||||||
|
// Destructors
|
||||||
|
// ************
|
||||||
|
public : virtual ~GenV1Trans() {};
|
||||||
|
|
||||||
|
// Operators
|
||||||
|
// *********
|
||||||
|
public : virtual void Calculate(Transistor*) ;
|
||||||
|
public : virtual void Generate(Transistor*) ;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
END_NAMESPACE_HURRICANE
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,539 @@
|
||||||
|
// ****************************************************************************************************
|
||||||
|
// File: GenV1Trans.cpp
|
||||||
|
// Authors: Wu YiFei
|
||||||
|
// Date : 04/04/2007
|
||||||
|
// ****************************************************************************************************
|
||||||
|
|
||||||
|
#include "Collection.h"
|
||||||
|
#include "RdsUnit.h"
|
||||||
|
#include "GenTrans.h"
|
||||||
|
#include "DtrAccess.h"
|
||||||
|
#include "GenericDtrAccess.h"
|
||||||
|
|
||||||
|
#include "Technology.h"
|
||||||
|
#include "UpdateSession.h"
|
||||||
|
|
||||||
|
#include "DataBase.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
BEGIN_NAMESPACE_HURRICANE
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ****************************************************************************************************
|
||||||
|
// Globals Datas
|
||||||
|
// ****************************************************************************************************
|
||||||
|
string segsforsource[] = {string("20"), string("23")};
|
||||||
|
string segsfordrain[] = {string("40"), string("43")};
|
||||||
|
string segsforgrid[] = {string("00"), string("01"), string("30"), string("31")};
|
||||||
|
//string segsforgrid[] = {string("00"), string("30") };
|
||||||
|
string segsforanonym[] = {string("10"), string("11"), string("12"), string("50")};
|
||||||
|
|
||||||
|
|
||||||
|
// ****************************************************************************************************
|
||||||
|
// Class GetV1Trans implementation
|
||||||
|
// ****************************************************************************************************
|
||||||
|
GenV1Trans::GenV1Trans(Transistor::MaskV1Info* masqueinfo)
|
||||||
|
// *********************************************************
|
||||||
|
: _masqueV1Info(masqueinfo)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GenV1Trans::Calculate(Transistor* transistor)
|
||||||
|
// **********************************************
|
||||||
|
{
|
||||||
|
DtrAccess * dtraccess = DtrAccess::Instance();
|
||||||
|
|
||||||
|
// Check out mask param.
|
||||||
|
// *********************
|
||||||
|
if(_masqueV1Info->GetL() < dtraccess->GetSingleRealRuleByLabel("L_TRANS") ||
|
||||||
|
_masqueV1Info->GetL() > dtraccess->GetSingleRealRuleByLabel("L_TRANS_MAX") ||
|
||||||
|
_masqueV1Info->GetW() < dtraccess->GetSingleRealRuleByLabel("W_TRANS") ||
|
||||||
|
_masqueV1Info->GetW() > dtraccess->GetSingleRealRuleByLabel("W_TRANS_MAX") )
|
||||||
|
|
||||||
|
throw Error("Can't launch function GenV1Trans::Calculate for " + GetString(transistor)
|
||||||
|
+ " the L " + GetString(_masqueV1Info->GetL())
|
||||||
|
+ " or the W " + GetString(_masqueV1Info->GetW())
|
||||||
|
+ " of this transistor is invalid."
|
||||||
|
);
|
||||||
|
|
||||||
|
if(_masqueV1Info->GetNbSourceColumn() < 1 || _masqueV1Info->GetNbSourceColumn() > MAXNBCONTACT ||
|
||||||
|
_masqueV1Info->GetNbDrainColumn() < 1 || _masqueV1Info->GetNbDrainColumn() > MAXNBCONTACT )
|
||||||
|
|
||||||
|
throw Error("Can't launch function GenV1Trans::Calculate for " + GetString(transistor)
|
||||||
|
+ " the nbsourcecolumn " + GetString(_masqueV1Info->GetNbSourceColumn())
|
||||||
|
+ " or the nbdraincolumn " + GetString(_masqueV1Info->GetNbDrainColumn())
|
||||||
|
+ " of this transistor is invalid."
|
||||||
|
);
|
||||||
|
|
||||||
|
IF_DEBUG_HUR_ANALOG
|
||||||
|
cout << ts << GetString(transistor) + " 's masqueinfo is " + GetString(_masqueV1Info)
|
||||||
|
<< endl;
|
||||||
|
END_IF
|
||||||
|
|
||||||
|
|
||||||
|
// Tempory Variable.
|
||||||
|
// **************************
|
||||||
|
long x00, y00, dx00, dy00;
|
||||||
|
long x10, y10, dx10, dy10;
|
||||||
|
long x11, y11, dx11, dy11;
|
||||||
|
long x12, y12, dx12, dy12;
|
||||||
|
long x20, y20, dx20, dy20;
|
||||||
|
long x23, y23, dx23, dy23;
|
||||||
|
long x30, y30, dx30, dy30;
|
||||||
|
long x31, y31, dx31, dy31;
|
||||||
|
long x01, y01, dx01, dy01;
|
||||||
|
long x40, y40, dx40, dy40;
|
||||||
|
long x43, y43, dx43, dy43;
|
||||||
|
long x50, y50, dx50, dy50;
|
||||||
|
|
||||||
|
long xmin = 999999L, ymin = 999999L;
|
||||||
|
long realw = 0;
|
||||||
|
|
||||||
|
// Tempory Variable.
|
||||||
|
// **************************
|
||||||
|
long extension1 = 0;
|
||||||
|
long extension2 = 0;
|
||||||
|
long extension3 = 0;
|
||||||
|
long extension4 = 0;
|
||||||
|
long ymax = 0;
|
||||||
|
string mostype; // Get Mos Type (N/P).
|
||||||
|
|
||||||
|
if(transistor->IsNmos())
|
||||||
|
mostype='N';
|
||||||
|
else
|
||||||
|
mostype='P';
|
||||||
|
|
||||||
|
//string mostype; // Get Mos Type (N/P).
|
||||||
|
//mostype=transistor->GetType();
|
||||||
|
|
||||||
|
// -------------------------------------------------------------
|
||||||
|
// Begin Calculate.
|
||||||
|
|
||||||
|
//long re_imp_acti = GET_RULE_BYNP("RE_", mostype, "IMP_ACTI");
|
||||||
|
long re_imp_acti = GET_RULE_BYNP("RE_", mostype, "IMP_ACTI");
|
||||||
|
long re_imp_poly = GET_RULE_BYNP("RE_", mostype, "IMP_POLY");
|
||||||
|
long re_imp_cont = GET_RULE_BYNP("RE_", mostype, "IMP_CONT");
|
||||||
|
long re_imp_gate = GET_RULE_BYNP("RE_", mostype, "IMP_GATE");
|
||||||
|
//long re_well_acti = GET_RULE_BYNP("RE_", mostype, "WELL_ACTI");
|
||||||
|
|
||||||
|
// Calculate Rectangle 00
|
||||||
|
// **********************
|
||||||
|
x00 = 0;
|
||||||
|
y00 = -( GET_RULE("RE_GATE_ACTI") );
|
||||||
|
|
||||||
|
dx00 = ConvertRealToRdsUnit(_masqueV1Info->GetL());
|
||||||
|
realw = ConvertRealToRdsUnit(_masqueV1Info->GetW());
|
||||||
|
|
||||||
|
dy00 = realw + 2*(-y00);
|
||||||
|
|
||||||
|
SAVE_RECTANGLE("00", x00, y00, dx00, dy00)
|
||||||
|
|
||||||
|
|
||||||
|
// Calculate Rectangle 30
|
||||||
|
// **********************
|
||||||
|
|
||||||
|
// cout << "RD_ACTI_CONT is " << GET_RULE("RD_ACTI_CONT")<<endl;
|
||||||
|
// cout << "RD_ACTI_POLY is " << GET_RULE("RD_ACTI_POLY")<<endl;
|
||||||
|
// cout << "RE_POLY_CONT is " << GET_RULE("RE_POLY_CONT")<<endl;
|
||||||
|
// cout << "MAX RD_ACTI_POLY is " << (MAXLONG(GET_RULE("RD_ACTI_CONT"), GET_RULE("RD_ACTI_POLY") + GET_RULE("RE_POLY_CONT"))) <<endl;
|
||||||
|
//
|
||||||
|
|
||||||
|
dx31 = GET_RULE("RW_CONT") + 2*GET_RULE("RE_POLY_CONT");
|
||||||
|
if (dx31 >= dx00) {
|
||||||
|
dx30 = GET_RULE("RW_CONT");
|
||||||
|
dy30 = dx30;
|
||||||
|
y30 = 0 + realw + MAXLONG(GET_RULE("RD_ACTI_CONT"), GET_RULE("RD_ACTI_POLY") + GET_RULE("RE_POLY_CONT"));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
dx30 = dx00 - 2*GET_RULE("RE_POLY_CONT");
|
||||||
|
dy30 = GET_RULE("RW_CONT");
|
||||||
|
y30 = 0 + realw + GET_RULE("RD_ACTI_CONT");
|
||||||
|
}
|
||||||
|
|
||||||
|
x30 = x00 + dx00/2 - dx30/2;
|
||||||
|
|
||||||
|
SAVE_RECTANGLE("30", x30, y30, dx30, dy30)
|
||||||
|
|
||||||
|
|
||||||
|
// Calculate Rectangle 31
|
||||||
|
// **********************
|
||||||
|
dx31 = dx30 + 2*GET_RULE("RE_POLY_CONT");
|
||||||
|
dy31 = dy30 + 2*GET_RULE("RE_POLY_CONT");
|
||||||
|
x31 = x30 - GET_RULE("RE_POLY_CONT");
|
||||||
|
y31 = y30 - GET_RULE("RE_POLY_CONT");
|
||||||
|
|
||||||
|
SAVE_RECTANGLE("31", x31, y31, dx31, dy31)
|
||||||
|
|
||||||
|
|
||||||
|
// Calculate Rectangle 01
|
||||||
|
// **********************
|
||||||
|
if ( y31 <= (y00+dy00) ) {
|
||||||
|
x01 = 0; y01 = 0; dx01 = 0; dy01 = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
x01 = x00;
|
||||||
|
y01 = y00 + dy00;
|
||||||
|
dx01 = dx00;
|
||||||
|
dy01 = y31 - (y00 + dy00);
|
||||||
|
}
|
||||||
|
|
||||||
|
SAVE_RECTANGLE("01", x01, y01, dx01, dy01)
|
||||||
|
|
||||||
|
|
||||||
|
// Calculate Rectangle 12
|
||||||
|
// **********************
|
||||||
|
x12 = MINLONG(x31, x00) - re_imp_poly;
|
||||||
|
y12 = MINLONG(0 - re_imp_acti, y00 - re_imp_poly);
|
||||||
|
dx12 = MAXLONG(dx31, dx00) + 2 * re_imp_poly;
|
||||||
|
|
||||||
|
ymax = MAXLONG( MAXLONG( y30 + dy30 + re_imp_cont
|
||||||
|
, MAXLONG(y31 + dy31, y00 + dy00) + re_imp_poly )
|
||||||
|
, realw + re_imp_acti );
|
||||||
|
|
||||||
|
dy12 = ymax - y12 ;
|
||||||
|
|
||||||
|
SAVE_RECTANGLE("12", x12, y12, dx12, dy12)
|
||||||
|
|
||||||
|
|
||||||
|
// Calculate Rectangle 20
|
||||||
|
// **********************
|
||||||
|
y20 = 0 + GET_RULE("RE_ACTI_CONT");
|
||||||
|
dy20 = realw - 2 * GET_RULE("RE_ACTI_CONT");
|
||||||
|
dx20 = (_masqueV1Info->GetNbSourceColumn()) * GET_RULE("RW_CONT") +
|
||||||
|
((_masqueV1Info->GetNbSourceColumn()) - 1) * GET_RULE("RD_CONT");
|
||||||
|
x20 = 0 - ( dx20 + GET_RULE("RD_CONT_GATE") );
|
||||||
|
|
||||||
|
SAVE_RECTANGLE("20", x20, y20, dx20, dy20)
|
||||||
|
|
||||||
|
|
||||||
|
// Calculate Rectangle 40
|
||||||
|
// **********************
|
||||||
|
y40 = y20;
|
||||||
|
x40 = x00 + dx00 + GET_RULE("RD_CONT_GATE");
|
||||||
|
dx40 = (_masqueV1Info->GetNbDrainColumn()) * GET_RULE("RW_CONT") +
|
||||||
|
((_masqueV1Info->GetNbDrainColumn()) - 1) * GET_RULE("RD_CONT");
|
||||||
|
dy40 = dy20;
|
||||||
|
|
||||||
|
SAVE_RECTANGLE("40", x40, y40, dx40, dy40)
|
||||||
|
|
||||||
|
// Calculate Rectangle 10
|
||||||
|
// **********************
|
||||||
|
y10 = 0;
|
||||||
|
x10 = MINLONG(x20 - GET_RULE("RE_ACTI_CONT"), 0 - GET_RULE("RE_ACTI_GATE"));
|
||||||
|
dy10 = realw;
|
||||||
|
|
||||||
|
extension1 = MAXLONG(0 + x40 + dx40 + GET_RULE("RE_ACTI_CONT"), dx00 + GET_RULE("RE_ACTI_GATE"));
|
||||||
|
|
||||||
|
dx10 = 0 - x10 + extension1;
|
||||||
|
|
||||||
|
SAVE_RECTANGLE("10", x10, y10, dx10, dy10)
|
||||||
|
|
||||||
|
|
||||||
|
// Calculate Rectangle 23
|
||||||
|
// ***********************
|
||||||
|
x23 = x10;
|
||||||
|
y23 = y10;
|
||||||
|
dx23 = 0 - x10;
|
||||||
|
dy23 = realw;
|
||||||
|
|
||||||
|
SAVE_RECTANGLE("23", x23, y23, dx23, dy23)
|
||||||
|
|
||||||
|
|
||||||
|
// Calculate Rectangle 43
|
||||||
|
// **********************
|
||||||
|
x43 = x00 + dx00 ;
|
||||||
|
y43 = y10;
|
||||||
|
dx43 = x10 + dx10 - (x00 + dx00);
|
||||||
|
dy43 = realw;
|
||||||
|
|
||||||
|
SAVE_RECTANGLE("43", x43, y43, dx43, dy43)
|
||||||
|
|
||||||
|
|
||||||
|
// Calculate Rectangle 11
|
||||||
|
// **********************
|
||||||
|
extension1 = re_imp_gate;
|
||||||
|
extension2 = re_imp_cont + 0 - x20;
|
||||||
|
extension3 = re_imp_acti + 0 - x10;
|
||||||
|
|
||||||
|
extension4 = MAXLONG(MAXLONG(extension1, extension2), extension3);
|
||||||
|
|
||||||
|
x11 = 0 - extension4;
|
||||||
|
|
||||||
|
extension1 = re_imp_gate + x00 + dx00;
|
||||||
|
extension2 = re_imp_cont + x40 + dx40;
|
||||||
|
extension3 = re_imp_acti + x10 + dx10;
|
||||||
|
|
||||||
|
extension4 = MAXLONG(MAXLONG(extension1, extension2), extension3);
|
||||||
|
|
||||||
|
dx11 = 0 - x11 + extension4;
|
||||||
|
|
||||||
|
y11 = MINLONG(y20 - re_imp_cont, y23 - re_imp_acti);
|
||||||
|
|
||||||
|
ymax = MAXLONG(y20 + dy20 + re_imp_cont, y23 + dy23 + re_imp_acti);
|
||||||
|
|
||||||
|
dy11 = ymax - y11;
|
||||||
|
|
||||||
|
SAVE_RECTANGLE("11", x11, y11, dx11, dy11);
|
||||||
|
|
||||||
|
|
||||||
|
// Calculate Rectangle 50 just for PMOS.
|
||||||
|
// -------------------------------------------------------------
|
||||||
|
if (transistor->IsPmos()) { // Calculate Rectangle 50 for PMos.
|
||||||
|
x50 = x10 - GET_RULE("RE_NWELL_ACTI");
|
||||||
|
y50 = y10 - GET_RULE("RE_NWELL_ACTI");
|
||||||
|
dx50 = dx10 + 2 * GET_RULE("RE_NWELL_ACTI");
|
||||||
|
dy50 = dy10 + 2 * GET_RULE("RE_NWELL_ACTI");
|
||||||
|
|
||||||
|
SAVE_RECTANGLE("50", x50, y50, dx50, dy50);
|
||||||
|
}
|
||||||
|
|
||||||
|
// End Calculate.
|
||||||
|
// -------------------------------------------------------------
|
||||||
|
|
||||||
|
// Translate rectangles.
|
||||||
|
// *********************
|
||||||
|
map<string, Box>::iterator i = _mapString2Box.begin(),
|
||||||
|
j = _mapString2Box.end();
|
||||||
|
|
||||||
|
while(i!=j) {
|
||||||
|
_mapString2Box[(*i).first] = (*i).second.translate(-xmin, -ymin);
|
||||||
|
|
||||||
|
IF_DEBUG_HUR_ANALOG
|
||||||
|
cout << ts << (*i).first <<" " << GetString((*i).second) << endl;
|
||||||
|
END_IF
|
||||||
|
|
||||||
|
assert(BOX_IS_VALID((*i).second));
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GenV1Trans::Generate(Transistor* transistor)
|
||||||
|
// *********************************************
|
||||||
|
{
|
||||||
|
OpenUpdateSession();
|
||||||
|
|
||||||
|
Net* source = transistor->GetNet(Name(transistor->GetSourceName()));
|
||||||
|
Net* drain = transistor->GetNet(Name(transistor->GetDrainName()) );
|
||||||
|
Net* grid = transistor->GetNet(Name(transistor->GetGridName()) );
|
||||||
|
|
||||||
|
DtrAccess * dtraccess = DtrAccess::Instance();
|
||||||
|
//string mostype(1, transistor->GetType()); // Get Mos Type (N/P).
|
||||||
|
|
||||||
|
string mostype; // Get Mos Type (N/P).
|
||||||
|
|
||||||
|
if(transistor->IsNmos())
|
||||||
|
mostype='N';
|
||||||
|
else
|
||||||
|
mostype='P';
|
||||||
|
|
||||||
|
long rw_cont = GetUnit(GET_RULE("RW_CONT"));
|
||||||
|
long rd_cont = GetUnit(GET_RULE("RD_CONT"));
|
||||||
|
unsigned nbcontact = 0;
|
||||||
|
long tmp_xcenter = 0;
|
||||||
|
long tmp_ycenter = 0;
|
||||||
|
|
||||||
|
DataBase * db = GetDataBase();
|
||||||
|
|
||||||
|
if(!db) throw Error("In GetV1Trans::Generate : can't find DataBase");
|
||||||
|
|
||||||
|
//Technology * tech = db->GetTechnology();
|
||||||
|
|
||||||
|
Layer * layer_20 = GET_LAYER_BYNP("TRANS_",mostype,"_LAYER_20");
|
||||||
|
Layer * layer_30 = GET_LAYER_BYNP("TRANS_",mostype,"_LAYER_30");
|
||||||
|
Layer * layer_40 = GET_LAYER_BYNP("TRANS_",mostype,"_LAYER_40");
|
||||||
|
|
||||||
|
|
||||||
|
// -------------------------------------------------------------
|
||||||
|
// Begin Generation.
|
||||||
|
|
||||||
|
// Cenerate Components For Net Source.
|
||||||
|
// ***********************************
|
||||||
|
IF_DEBUG_HUR_ANALOG
|
||||||
|
cout << ts << "Begin for create components for net Source of " << GetString(transistor) << endl;
|
||||||
|
END_IF
|
||||||
|
|
||||||
|
for(size_t i=0; i<sizeof(segsforsource)/sizeof(string); i++) {
|
||||||
|
|
||||||
|
if(segsforsource[i]=="20") {
|
||||||
|
//cout << ts << " Begin create contact for source , Under Box is " << GetString(GET_BOX(segsforsource[i])) <<endl;
|
||||||
|
Box underbox = GET_BOX(segsforsource[i]);
|
||||||
|
CREATE_CONTACT_MATRIX_UNDER(underbox, transistor->GetNbSourceColumn(), layer_20, source)
|
||||||
|
//cout << ts << " Finish create contact for source " <<endl;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Contact::Create(source, GET_LAYER_BYNP("TRANS_",mostype,"_LAYER_"+segsforsource[i])
|
||||||
|
, GET_BOX(segsforsource[i]).getXCenter()
|
||||||
|
, GET_BOX(segsforsource[i]).getYCenter()
|
||||||
|
, GET_BOX(segsforsource[i]).getWidth()
|
||||||
|
, GET_BOX(segsforsource[i]).getHeight()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
IF_DEBUG_HUR_ANALOG
|
||||||
|
cout << ts << "End for create components for net Source of " << GetString(transistor) << endl;
|
||||||
|
END_IF
|
||||||
|
|
||||||
|
|
||||||
|
// Generate Components For Net Grid.
|
||||||
|
// *********************************
|
||||||
|
IF_DEBUG_HUR_ANALOG
|
||||||
|
cout << ts << "Begin for create components for net Grid of " << GetString(transistor) << endl;
|
||||||
|
END_IF
|
||||||
|
for(size_t i=0; i<sizeof(segsforgrid)/sizeof(string); i++) {
|
||||||
|
if(segsforgrid[i]=="30"){
|
||||||
|
if( GET_BOX(segsforgrid[i]).getWidth()==GET_RULE("RW_CONT") ) {
|
||||||
|
Contact::Create(grid, GET_LAYER_BYNP("TRANS_",mostype,"_LAYER_"+segsforgrid[i])
|
||||||
|
, GET_BOX(segsforgrid[i]).getXCenter()
|
||||||
|
, GET_BOX(segsforgrid[i]).getYCenter()
|
||||||
|
, GET_BOX(segsforgrid[i]).getWidth()
|
||||||
|
, GET_BOX(segsforgrid[i]).getHeight()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
unsigned int nbcolumn = (GET_BOX(segsforgrid[i]).getWidth()-rw_cont)/(rw_cont + rd_cont) + 1;
|
||||||
|
|
||||||
|
IF_DEBUG_HUR_ANALOG
|
||||||
|
cout << ts << "nbcolumn in rectangle 30 is " << nbcolumn <<endl;
|
||||||
|
END_IF
|
||||||
|
|
||||||
|
Box underbox = GET_BOX(segsforgrid[i]);
|
||||||
|
CREATE_CONTACT_MATRIX_UNDER(underbox, nbcolumn, layer_30, grid)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if(GET_BOX(segsforgrid[i]).getXMin() < GET_BOX(segsforgrid[i]).getXMax()) {
|
||||||
|
Contact::Create(grid, GET_LAYER_BYNP("TRANS_",mostype,"_LAYER_"+segsforgrid[i])
|
||||||
|
, GET_BOX(segsforgrid[i]).getXCenter()
|
||||||
|
, GET_BOX(segsforgrid[i]).getYCenter()
|
||||||
|
, GET_BOX(segsforgrid[i]).getWidth()
|
||||||
|
, GET_BOX(segsforgrid[i]).getHeight()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
IF_DEBUG_HUR_ANALOG
|
||||||
|
cout << ts << "End for create components for net Grid of " << GetString(transistor) << endl;
|
||||||
|
END_IF
|
||||||
|
|
||||||
|
|
||||||
|
// Generate Components For Net Drain.
|
||||||
|
// **********************************
|
||||||
|
IF_DEBUG_HUR_ANALOG
|
||||||
|
cout << ts << "Begin for create components for net Drain of " << GetString(transistor) << endl;
|
||||||
|
END_IF
|
||||||
|
for(size_t i=0; i<sizeof(segsfordrain)/sizeof(string); i++) {
|
||||||
|
|
||||||
|
if(segsfordrain[i]=="40") {
|
||||||
|
//cout << ts << " Begin create contact for drain, Under Box is " << GetString(GET_BOX(segsforsource[i])) <<endl;
|
||||||
|
Box underbox = GET_BOX(segsfordrain[i]);
|
||||||
|
CREATE_CONTACT_MATRIX_UNDER(underbox, transistor->GetNbDrainColumn(), layer_40, drain)
|
||||||
|
//cout << ts << " Finish create contact for drain" <<endl;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Contact::Create(drain, GET_LAYER_BYNP("TRANS_",mostype,"_LAYER_"+segsfordrain[i])
|
||||||
|
, GET_BOX(segsfordrain[i]).getXCenter()
|
||||||
|
, GET_BOX(segsfordrain[i]).getYCenter()
|
||||||
|
, GET_BOX(segsfordrain[i]).getWidth()
|
||||||
|
, GET_BOX(segsfordrain[i]).getHeight()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
IF_DEBUG_HUR_ANALOG
|
||||||
|
cout << ts << "End for create components for net Drain of " << GetString(transistor) << endl;
|
||||||
|
END_IF
|
||||||
|
|
||||||
|
// Generate Components For Anonyms Nets.
|
||||||
|
// *************************************
|
||||||
|
IF_DEBUG_HUR_ANALOG
|
||||||
|
cout << ts << "Begin for create components for net Anonyme of " << GetString(transistor) << endl;
|
||||||
|
END_IF
|
||||||
|
Net * anonym = Net::Create(transistor, Name("anonym"));
|
||||||
|
for(size_t i=0; i<sizeof(segsforanonym)/sizeof(string);i++) {
|
||||||
|
if(transistor->IsNmos() && segsforanonym[i]=="50")
|
||||||
|
continue;
|
||||||
|
|
||||||
|
Contact::Create(anonym, GET_LAYER_BYNP("TRANS_",mostype,"_LAYER_"+segsforanonym[i])
|
||||||
|
, GET_BOX(segsforanonym[i]).getXCenter()
|
||||||
|
, GET_BOX(segsforanonym[i]).getYCenter()
|
||||||
|
, GET_BOX(segsforanonym[i]).getWidth()
|
||||||
|
, GET_BOX(segsforanonym[i]).getHeight()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
IF_DEBUG_HUR_ANALOG
|
||||||
|
cout << ts << "End for create components for net Anonyme of " << GetString(transistor) << endl;
|
||||||
|
END_IF
|
||||||
|
|
||||||
|
// End Generation.
|
||||||
|
// -------------------------------------------------------------
|
||||||
|
|
||||||
|
CloseUpdateSession();
|
||||||
|
|
||||||
|
// Set Transistor::_mapNet2Box.
|
||||||
|
// ****************************
|
||||||
|
(*(transistor->_GetMapNet2Box()))[grid] = _mapString2Box[string("30")];
|
||||||
|
(*(transistor->_GetMapNet2Box()))[source] = _mapString2Box[string("20")];
|
||||||
|
(*(transistor->_GetMapNet2Box()))[drain] = _mapString2Box[string("40")];
|
||||||
|
|
||||||
|
cout<< GetString(_mapString2Box[string("30")]) <<endl;
|
||||||
|
cout<< GetString(_mapString2Box[string("20")]) <<endl;
|
||||||
|
cout<< GetString(_mapString2Box[string("40")]) <<endl;
|
||||||
|
|
||||||
|
// Set Abutment Box.
|
||||||
|
// *****************
|
||||||
|
switch(transistor->GetAbutmentType().GetCode()) {
|
||||||
|
|
||||||
|
case Transistor::Type::INTERNAL :
|
||||||
|
transistor->SetAbutmentBox( Box(GET_BOX(string("20")).getXCenter()
|
||||||
|
, transistor->GetBoundingBox().getYMin()
|
||||||
|
, GET_BOX(string("40")).getXCenter()
|
||||||
|
, transistor->GetBoundingBox().getYMax()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Transistor::Type::LEFT:
|
||||||
|
transistor->SetAbutmentBox( Box(GET_BOX(string("11")).getXMin()
|
||||||
|
, transistor->GetBoundingBox().getYMin()
|
||||||
|
, GET_BOX(string("40")).getXCenter()
|
||||||
|
, transistor->GetBoundingBox().getYMax()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
break ;
|
||||||
|
|
||||||
|
case Transistor::Type::RIGHT:
|
||||||
|
transistor->SetAbutmentBox( Box(GET_BOX(string("20")).getXCenter()
|
||||||
|
, transistor->GetBoundingBox().getYMin()
|
||||||
|
, GET_BOX(string("11")).getXMax()
|
||||||
|
, transistor->GetBoundingBox().getYMax()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
break ;
|
||||||
|
|
||||||
|
case Transistor::Type::SINGLE:
|
||||||
|
transistor->SetAbutmentBox( Box(GET_BOX(string("11")).getXMin()
|
||||||
|
, transistor->GetBoundingBox().getYMin()
|
||||||
|
, GET_BOX(string("11")).getXMax()
|
||||||
|
, transistor->GetBoundingBox().getYMax()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
break ;
|
||||||
|
|
||||||
|
default :
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
END_NAMESPACE_HURRICANE
|
|
@ -0,0 +1,184 @@
|
||||||
|
// ****************************************************************************************************
|
||||||
|
// File: MetaTransistor.cpp
|
||||||
|
// Authors: Wu YiFei
|
||||||
|
// Date : 21/12/2006
|
||||||
|
// ****************************************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
#include "MetaTransistor.h"
|
||||||
|
#include "Transistor.h"
|
||||||
|
#include "Instances.h"
|
||||||
|
#include "UpdateSession.h"
|
||||||
|
#include "Vertical.h"
|
||||||
|
|
||||||
|
|
||||||
|
BEGIN_NAMESPACE_HURRICANE
|
||||||
|
|
||||||
|
// ****************************************************************************************************
|
||||||
|
// MetaTransistor implementation
|
||||||
|
// ****************************************************************************************************
|
||||||
|
|
||||||
|
MetaTransistor::MetaTransistor(Library* library, const Name& name, char type)
|
||||||
|
// **************************************************************************
|
||||||
|
: Inherit(library, name),
|
||||||
|
_type(type),
|
||||||
|
_m(1),
|
||||||
|
_le(0.0),
|
||||||
|
_we(0.0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
MetaTransistor* MetaTransistor::Create(Library* library, const Name& name, char type)
|
||||||
|
// **********************************************************************************
|
||||||
|
{
|
||||||
|
MetaTransistor* metatransistor = new MetaTransistor(library, name, type);
|
||||||
|
|
||||||
|
metatransistor->_PostCreate();
|
||||||
|
|
||||||
|
return metatransistor;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MetaTransistor::_PreDelete()
|
||||||
|
// ******************************
|
||||||
|
{
|
||||||
|
// do something
|
||||||
|
// ************
|
||||||
|
|
||||||
|
Inherit::_PreDelete();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MetaTransistor::_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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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()
|
||||||
|
// ********************************
|
||||||
|
{
|
||||||
|
// OpenUpdateSession();
|
||||||
|
|
||||||
|
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<Transistor*>(mastercell);
|
||||||
|
if(!trans){
|
||||||
|
string err_msg = "Can't genrate layout : " + GetString(mastercell) + " isn't a Transistor";
|
||||||
|
}
|
||||||
|
|
||||||
|
if(trans->IsInternal()) {
|
||||||
|
if(!internal_ref) {
|
||||||
|
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();
|
||||||
|
// CloseUpdateSession();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MetaTransistor::Flush()
|
||||||
|
// *************************
|
||||||
|
{
|
||||||
|
OpenUpdateSession();
|
||||||
|
for_each_instance(instance, this->GetInstances())
|
||||||
|
Cell * mastercell = instance->GetMasterCell();
|
||||||
|
instance->Delete();
|
||||||
|
mastercell->Delete();
|
||||||
|
end_for
|
||||||
|
CloseUpdateSession();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
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
|
||||||
|
// ***************************************
|
||||||
|
{
|
||||||
|
Record* record = Inherit::_GetRecord();
|
||||||
|
return record;
|
||||||
|
}
|
||||||
|
|
||||||
|
END_NAMESPACE_HURRICANE
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,133 @@
|
||||||
|
// ****************************************************************************************************
|
||||||
|
// File: MetaTransistor.h
|
||||||
|
// Authors: Wu YiFei
|
||||||
|
// Date : 21/12/2006
|
||||||
|
// ****************************************************************************************************
|
||||||
|
|
||||||
|
#ifndef HURRICANE_METATRANSISTOR
|
||||||
|
#define HURRICANE_METATRANSISTOR
|
||||||
|
|
||||||
|
#include "Cell.h"
|
||||||
|
#include "AnalogicalCommons.h"
|
||||||
|
|
||||||
|
|
||||||
|
//BEGIN_NAMESPACE_HURRICANE
|
||||||
|
|
||||||
|
namespace Hurricane {
|
||||||
|
|
||||||
|
class Library;
|
||||||
|
class Name;
|
||||||
|
class Symbol;
|
||||||
|
class Record;
|
||||||
|
|
||||||
|
class MetaTransistor: public Cell {
|
||||||
|
// ********************************
|
||||||
|
|
||||||
|
|
||||||
|
// Types
|
||||||
|
// *****
|
||||||
|
public : typedef Cell Inherit;
|
||||||
|
|
||||||
|
# if !defined(__DOXYGEN_PROCESSOR__)
|
||||||
|
|
||||||
|
// Logicals Attributes
|
||||||
|
// *******************
|
||||||
|
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;
|
||||||
|
|
||||||
|
|
||||||
|
// Behaviorals attributes
|
||||||
|
// **********************
|
||||||
|
private : double _temp, _vds, _vgs; // DC
|
||||||
|
private : double _vg, _vd, _vs, _vb;
|
||||||
|
private : char _region;
|
||||||
|
private : double _ids;
|
||||||
|
private : double _vth, _vdsat; // AC
|
||||||
|
|
||||||
|
# endif
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
// ************
|
||||||
|
# if !defined(__DOXYGEN_PROCESSOR__)
|
||||||
|
protected : MetaTransistor(Library* library, const Name& name, char type);
|
||||||
|
# endif
|
||||||
|
|
||||||
|
public : static MetaTransistor* Create(Library* library, const Name& name, char type);
|
||||||
|
|
||||||
|
# if !defined(__DOXYGEN_PROCESSOR__)
|
||||||
|
protected : virtual void _PostCreate();
|
||||||
|
|
||||||
|
|
||||||
|
// Destructors
|
||||||
|
// ***********
|
||||||
|
protected : ~MetaTransistor() {};
|
||||||
|
protected : virtual void _PreDelete();
|
||||||
|
# endif
|
||||||
|
|
||||||
|
// Operations
|
||||||
|
// **********
|
||||||
|
|
||||||
|
// Create the connection between all instances.
|
||||||
|
// ********************************************
|
||||||
|
public : void CreateConnection();
|
||||||
|
|
||||||
|
// Create the layout of all motifs in this metatransistor.
|
||||||
|
// *******************************************************
|
||||||
|
public : void CreateLayout();
|
||||||
|
|
||||||
|
|
||||||
|
# if !defined(__DOXYGEN_PROCESSOR__)
|
||||||
|
// Get all paramters after generation of Layout (capa..).
|
||||||
|
// *****************************************************
|
||||||
|
public : void GetParameterOfGeneration() { /* to do */};
|
||||||
|
|
||||||
|
// Delete all instances and all motifs in this metatransistor.
|
||||||
|
// ***********************************************************
|
||||||
|
public : void Flush();
|
||||||
|
# endif
|
||||||
|
|
||||||
|
|
||||||
|
// 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; };
|
||||||
|
|
||||||
|
|
||||||
|
// 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; };
|
||||||
|
|
||||||
|
|
||||||
|
//#endif
|
||||||
|
|
||||||
|
# if !defined(__DOXYGEN_PROCESSOR__)
|
||||||
|
// Others
|
||||||
|
// ******
|
||||||
|
public: virtual string _GetTypeName() const {return _TName("MetaTransistor");};
|
||||||
|
public: virtual string _GetString() const;
|
||||||
|
public: virtual Record* _GetRecord() const;
|
||||||
|
# endif
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//END_NAMESPACE_HURRICANE
|
||||||
|
|
||||||
|
#endif // HURRICANE_METATRANSISTOR
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,59 @@
|
||||||
|
|
||||||
|
// ****************************************************************************************************
|
||||||
|
// File: MetaTransistors.h
|
||||||
|
// Authors: YIFEI WU
|
||||||
|
// Date : 21/12/2006
|
||||||
|
// ****************************************************************************************************
|
||||||
|
|
||||||
|
#ifndef HURRICANE_METATRANSISTORS
|
||||||
|
#define HURRICANE_METATRANSISTORS
|
||||||
|
|
||||||
|
#include "Collection.h"
|
||||||
|
|
||||||
|
BEGIN_NAMESPACE_HURRICANE
|
||||||
|
|
||||||
|
class MetaTransistor;
|
||||||
|
|
||||||
|
|
||||||
|
// ****************************************************************************************************
|
||||||
|
// MetaTransistors declaration
|
||||||
|
// ****************************************************************************************************
|
||||||
|
|
||||||
|
typedef GenericCollection<MetaTransistor*> MetaTransistors;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ****************************************************************************************************
|
||||||
|
// MetaTransistorLocator declaration
|
||||||
|
// ****************************************************************************************************
|
||||||
|
|
||||||
|
typedef GenericLocator<MetaTransistor*> MetaTransistorLocator;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ****************************************************************************************************
|
||||||
|
// MetaTransistorFilter declaration
|
||||||
|
// ****************************************************************************************************
|
||||||
|
|
||||||
|
typedef GenericFilter<MetaTransistor*> MetaTransistorFilter;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ****************************************************************************************************
|
||||||
|
// for_each_metatransistor declaration
|
||||||
|
// ****************************************************************************************************
|
||||||
|
|
||||||
|
#define for_each_metatransistor(metatransistor, metatransistors)\
|
||||||
|
/******************************/\
|
||||||
|
{\
|
||||||
|
MetaTransistorLocator _locator = metatransistors.GetLocator();\
|
||||||
|
while (_locator.IsValid()) {\
|
||||||
|
MetaTransistor* metatransistor = _locator.GetElement();\
|
||||||
|
_locator.Progress();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
END_NAMESPACE_HURRICANE
|
||||||
|
|
||||||
|
#endif // HURRICANE_METATRANSISTORS
|
||||||
|
|
|
@ -0,0 +1,260 @@
|
||||||
|
// ****************************************************************************************************
|
||||||
|
// File: RdsUnit.cpp
|
||||||
|
// Authors: Wu YiFei
|
||||||
|
// Date : 21/12/2006
|
||||||
|
// ****************************************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
#include "Error.h"
|
||||||
|
#include "stdio.h"
|
||||||
|
#include "regex.h"
|
||||||
|
#include "math.h"
|
||||||
|
#include "Commons.h"
|
||||||
|
#include "RdsUnit.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ****************************************************************************************************
|
||||||
|
// Static data&function
|
||||||
|
// ****************************************************************************************************
|
||||||
|
|
||||||
|
static long RDS_UNIT = -1;
|
||||||
|
|
||||||
|
static long RDS_PHYSICAL_GRID = 2;
|
||||||
|
|
||||||
|
static long RDS_LAMBDA = -1;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------
|
||||||
|
// Function : "GetPattern()".
|
||||||
|
|
||||||
|
/* \static char * GetPattern (const string& str, const char* pattern)
|
||||||
|
* \param str the string to check for regex.
|
||||||
|
* \param pattern the pattern to find.
|
||||||
|
*
|
||||||
|
* Get and return the march substring from str according to the pattern.
|
||||||
|
*
|
||||||
|
* \return NULL if Failure.
|
||||||
|
* \return the according substring if Success.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static char* GetPattern(const string& str, const char* pattern)
|
||||||
|
// ************************************************************
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
regex_t preg;
|
||||||
|
const char *str_request = str.c_str();
|
||||||
|
const char *str_regex = pattern;
|
||||||
|
|
||||||
|
/* (1) */
|
||||||
|
err = regcomp (&preg, str_regex, REG_EXTENDED);
|
||||||
|
|
||||||
|
if (err == 0)
|
||||||
|
{
|
||||||
|
int match;
|
||||||
|
size_t nmatch = 0;
|
||||||
|
regmatch_t *pmatch = NULL;
|
||||||
|
|
||||||
|
nmatch= 1;
|
||||||
|
pmatch = (regmatch_t*)malloc (sizeof (*pmatch) * nmatch);
|
||||||
|
|
||||||
|
if (pmatch)
|
||||||
|
{
|
||||||
|
/* (2) */
|
||||||
|
match = regexec (&preg, str_request, nmatch, pmatch, 0);
|
||||||
|
|
||||||
|
/* (3) */
|
||||||
|
regfree (&preg);
|
||||||
|
|
||||||
|
/* (4) */
|
||||||
|
if (match == 0)
|
||||||
|
{
|
||||||
|
char *site = NULL;
|
||||||
|
int start = pmatch[0].rm_so;
|
||||||
|
int end = pmatch[0].rm_eo;
|
||||||
|
size_t size = end - start;
|
||||||
|
|
||||||
|
site = (char*)malloc (sizeof (*site) * (size + 1));
|
||||||
|
if (site)
|
||||||
|
{
|
||||||
|
strncpy (site, &str_request[start], size);
|
||||||
|
site[size] = '\0';
|
||||||
|
|
||||||
|
return site;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
fprintf (stderr, "Memoire insuffisante\n");
|
||||||
|
exit (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* (5) */
|
||||||
|
else if (match == REG_NOMATCH)
|
||||||
|
{
|
||||||
|
printf ("%s doesn't accord to %s\n", str_request, str_regex);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
/* (6) */
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char *text;
|
||||||
|
size_t size;
|
||||||
|
|
||||||
|
/* (7) */
|
||||||
|
size = regerror (err, &preg, NULL, 0);
|
||||||
|
text = (char*)malloc (sizeof (*text) * size);
|
||||||
|
if (text)
|
||||||
|
{
|
||||||
|
/* (8) */
|
||||||
|
regerror (err, &preg, text, size);
|
||||||
|
fprintf (stderr, "%s\n", text);
|
||||||
|
free (text);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Memoire insuffisante\n");
|
||||||
|
}
|
||||||
|
exit (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Memoire insuffisante\n");
|
||||||
|
exit (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
fprintf (stderr, "Regcomp fail\n");
|
||||||
|
exit (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
// Function : "CalculateRdsUnit()".
|
||||||
|
|
||||||
|
/* static void CalculateRdsUnit()
|
||||||
|
*
|
||||||
|
* Open rds techno file who's name is MACRO RDS_TECHNO_FILE,
|
||||||
|
* and get values technology : rds_physical_grid, rds_lambda.
|
||||||
|
* Calculate the RDS_UNIT according to these values.
|
||||||
|
*
|
||||||
|
* If RDS_TECHNO_FILE is invalid or operaton of reading values technologys
|
||||||
|
* fail, a Hurricane Error will be throwed to explain the reason of failure.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
static void CalculateRdsUnit()
|
||||||
|
// ***************************
|
||||||
|
{
|
||||||
|
using Hurricane::Error;
|
||||||
|
|
||||||
|
const char * rdsfilename = getenv("RDS_TECHNO_NAME");
|
||||||
|
FILE * rdstechnofile;
|
||||||
|
|
||||||
|
if(!rdsfilename) {
|
||||||
|
throw Error("Can't not find macro RDS_TECHNO_FILE");
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !(rdstechnofile = fopen(rdsfilename, "r")) ) {
|
||||||
|
throw Error("Can't not open rds techno file : " + GetString(rdsfilename));
|
||||||
|
}
|
||||||
|
|
||||||
|
char buffer[80]; // For stock a line of the rds techno file
|
||||||
|
double rds_physical_grid = -0.1; // For stock value of physical_grid
|
||||||
|
double rds_lambda = -0.1; // For stock value of lamba
|
||||||
|
|
||||||
|
while(fgets(buffer, 80, rdstechnofile )!=NULL){
|
||||||
|
string tmp = buffer;
|
||||||
|
|
||||||
|
if( tmp.find("define physical_grid")!=string::npos) { // Find the ligne begin with "define physical_grid"
|
||||||
|
|
||||||
|
string pattern;
|
||||||
|
|
||||||
|
if( (pattern = GetPattern(tmp, "[[:digit:]\\.]+")).size()==0 ) { // Get the value behind
|
||||||
|
throw Error("Can't get rds_physical_grid : GetPattern(string&, char*) return NULL");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!Scan(pattern, rds_physical_grid)){ // Convert from string to double
|
||||||
|
throw Error("Can't get rds_physical_grid " + pattern + " : Hurricane::Scan(string&, double&) return false");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if( tmp.find("define lambda")!=string::npos ) {
|
||||||
|
|
||||||
|
string pattern;
|
||||||
|
|
||||||
|
if( (pattern = GetPattern(tmp, "[[:digit:]\\.]+")).size()==0 ) {
|
||||||
|
throw Error("Can't get rds_lambda : GetPattern(string&, char*) return NULL");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!Scan(pattern, rds_lambda)){
|
||||||
|
throw Error("Can't get rds_lambda " + pattern + " : Hurricane::Scan(string&, double&) return false");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// if rds_physical_grid and rds_lambda are finded, break the loop
|
||||||
|
// **************************************************************
|
||||||
|
if( (rds_physical_grid!=-0.1) && (rds_lambda!=-0.1) )
|
||||||
|
break;
|
||||||
|
|
||||||
|
} // end of while
|
||||||
|
|
||||||
|
if( (rds_physical_grid==-0.1) && (rds_lambda==-0.1) ) {
|
||||||
|
throw Error("Can't get rds_physical_grid and rds_lambda from rds techno file : \n" + string(rdsfilename));
|
||||||
|
}
|
||||||
|
|
||||||
|
long rds_physical_grid_nano = (long)rint(rds_physical_grid*(double)1000);
|
||||||
|
|
||||||
|
rds_physical_grid_nano = (long)rint( (double)1000/(double)rds_physical_grid_nano );
|
||||||
|
|
||||||
|
RDS_UNIT = rds_physical_grid_nano << 1;
|
||||||
|
|
||||||
|
long rds_lambda_nano = (long)rint( rds_lambda*(double)1000 );
|
||||||
|
|
||||||
|
RDS_LAMBDA = rds_lambda_nano * RDS_UNIT / 1000 ;
|
||||||
|
|
||||||
|
fclose(rdstechnofile);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
BEGIN_NAMESPACE_HURRICANE
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ****************************************************************************************************
|
||||||
|
// Utilitarians
|
||||||
|
// ****************************************************************************************************
|
||||||
|
|
||||||
|
const long& GetRdsUnit()
|
||||||
|
// *********************
|
||||||
|
{
|
||||||
|
if ( RDS_UNIT == -1)
|
||||||
|
CalculateRdsUnit();
|
||||||
|
|
||||||
|
return RDS_UNIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
const long& GetRdsPhysicalGrid()
|
||||||
|
// *****************************
|
||||||
|
{
|
||||||
|
return RDS_PHYSICAL_GRID;
|
||||||
|
}
|
||||||
|
|
||||||
|
const long& GetRdsLambda()
|
||||||
|
// ***********************
|
||||||
|
{
|
||||||
|
if ( RDS_LAMBDA == -1)
|
||||||
|
CalculateRdsUnit();
|
||||||
|
|
||||||
|
return RDS_LAMBDA;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
END_NAMESPACE_HURRICANE
|
|
@ -0,0 +1,54 @@
|
||||||
|
// ****************************************************************************************************
|
||||||
|
// File: RdsUnit.h
|
||||||
|
// Authors: Wu YiFei
|
||||||
|
// Date : 21/12/2006
|
||||||
|
// ****************************************************************************************************
|
||||||
|
|
||||||
|
#ifndef HURRICANE_RDSUNIT
|
||||||
|
#define HURRICANE_RDSUNIT
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
//BEGIN_NAMESPACE_HURRICANE
|
||||||
|
|
||||||
|
|
||||||
|
namespace Hurricane {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ****************************************************************************************************
|
||||||
|
// Utilitarians
|
||||||
|
// ****************************************************************************************************
|
||||||
|
|
||||||
|
extern const long& GetRdsUnit();
|
||||||
|
|
||||||
|
extern const long& GetRdsPhysicalGrid();
|
||||||
|
|
||||||
|
extern const long& GetRdsLambda();
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// Function : "ConvertRealToRdsUnit(const double&)".
|
||||||
|
//
|
||||||
|
|
||||||
|
/* \inline long ConvertRealToRdsUnit(const double& value)
|
||||||
|
* \param value the value en Micro to convert to RdsUnit.
|
||||||
|
*
|
||||||
|
* Get and return the value en RdsUnit.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
inline long ConvertRealToRdsUnit(const double& value)
|
||||||
|
// *******************************************************
|
||||||
|
{
|
||||||
|
long tmp_value = (long)rint(value*GetRdsUnit());
|
||||||
|
return (tmp_value%2)==0?tmp_value:(tmp_value+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//END_NAMESPACE_HURRICANE
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // HURRICANE_RDSUNIT
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,505 @@
|
||||||
|
// ****************************************************************************************************
|
||||||
|
// File: Transistor.h
|
||||||
|
// Authors: Wu YiFei
|
||||||
|
// Date : 21/12/2006
|
||||||
|
// ****************************************************************************************************
|
||||||
|
|
||||||
|
#include "AnalogicalCommons.h"
|
||||||
|
#include "Transistor.h"
|
||||||
|
#include "GenTrans.h"
|
||||||
|
|
||||||
|
#include "Vertical.h"
|
||||||
|
#include "Horizontal.h"
|
||||||
|
|
||||||
|
#include "UpdateSession.h"
|
||||||
|
|
||||||
|
BEGIN_NAMESPACE_HURRICANE
|
||||||
|
|
||||||
|
|
||||||
|
// ****************************************************************************************************
|
||||||
|
// Transistor::MaskVersion implementation
|
||||||
|
// ****************************************************************************************************
|
||||||
|
Transistor::MaskVersion::MaskVersion(const Code& code)
|
||||||
|
// *******************************************************
|
||||||
|
:_code(code)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Transistor::MaskVersion::MaskVersion(const MaskVersion& version)
|
||||||
|
// *******************************************************************
|
||||||
|
:_code(version._code)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Transistor::MaskVersion& Transistor::MaskVersion::operator=(const MaskVersion& version)
|
||||||
|
// ******************************************************************************************
|
||||||
|
{
|
||||||
|
_code = version._code;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Transistor::MaskVersion::operator==(const MaskVersion& version) const
|
||||||
|
// ***************************************************************************
|
||||||
|
{
|
||||||
|
return _code==version._code;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
string Transistor::MaskVersion::_GetString() const
|
||||||
|
// *************************************************
|
||||||
|
{
|
||||||
|
switch(_code) {
|
||||||
|
case VERSION1 : return "VERSION1";
|
||||||
|
}
|
||||||
|
return "ABNORMAL";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Record* Transistor::MaskVersion::_GetRecord() const
|
||||||
|
// **************************************************
|
||||||
|
{
|
||||||
|
Record* record = new Record(GetString(this));
|
||||||
|
record->Add(GetSlot("Code", _code));
|
||||||
|
return record;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ****************************************************************************************************
|
||||||
|
// Transistor::Type implementation
|
||||||
|
// ****************************************************************************************************
|
||||||
|
Transistor::Type::Type(const Code& code)
|
||||||
|
// *************************************
|
||||||
|
:_code(code)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Transistor::Type::Type(const Type& type)
|
||||||
|
// *************************************
|
||||||
|
:_code(type._code)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Transistor::Type& Transistor::Type::operator=(const Type& type)
|
||||||
|
// ************************************************************
|
||||||
|
{
|
||||||
|
_code = type._code;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
string Transistor::Type::_GetString() const
|
||||||
|
// *****************************************
|
||||||
|
{
|
||||||
|
switch(_code) {
|
||||||
|
case INTERNAL : return "INTERNAL";
|
||||||
|
case LEFT : return "LEFT";
|
||||||
|
case RIGHT : return "RIGHT";
|
||||||
|
case SINGLE : return "SINGLE";
|
||||||
|
}
|
||||||
|
|
||||||
|
return "ABNORMAL";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Record* Transistor::Type::_GetRecord() const
|
||||||
|
// *****************************************
|
||||||
|
{
|
||||||
|
Record* record = new Record(GetString(this));
|
||||||
|
record->Add(GetSlot("Code", _code));
|
||||||
|
return record;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ****************************************************************************************************
|
||||||
|
// Transistor::MaskInfo implementation
|
||||||
|
// ****************************************************************************************************
|
||||||
|
Transistor::MaskInfo::MaskInfo(const double& l, const double& w, const Type::Code& type
|
||||||
|
, const unsigned& nbDrainColumn
|
||||||
|
, const unsigned& nbSourceColumn)
|
||||||
|
// ****************************************************************************************************
|
||||||
|
: _l(l)
|
||||||
|
, _w(w)
|
||||||
|
, _type(type)
|
||||||
|
, _nbDrainColumn(nbDrainColumn)
|
||||||
|
, _nbSourceColumn(nbSourceColumn)
|
||||||
|
{};
|
||||||
|
|
||||||
|
|
||||||
|
Transistor::MaskInfo& Transistor::MaskInfo::operator=(const MaskInfo& masqueinfo)
|
||||||
|
// ************************************************************************************
|
||||||
|
{
|
||||||
|
_l = masqueinfo.GetL();
|
||||||
|
_w = masqueinfo.GetW();
|
||||||
|
_type= masqueinfo.GetType();
|
||||||
|
_nbDrainColumn = masqueinfo.GetNbDrainColumn();
|
||||||
|
_nbSourceColumn = masqueinfo.GetNbSourceColumn();
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Transistor::MaskInfo::_PostCreate()
|
||||||
|
// ***************************************
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Transistor::MaskInfo::_PreDelete()
|
||||||
|
// **************************************
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Transistor::MaskInfo::Delete()
|
||||||
|
// **********************************
|
||||||
|
{
|
||||||
|
_PreDelete();
|
||||||
|
delete this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Transistor::MaskInfo::operator==(const MaskInfo& masqueinfo)
|
||||||
|
// ******************************************************************
|
||||||
|
{
|
||||||
|
if(_l == masqueinfo.GetL() &&
|
||||||
|
_w == masqueinfo.GetW() &&
|
||||||
|
_type== masqueinfo.GetType() &&
|
||||||
|
_nbDrainColumn == masqueinfo.GetNbDrainColumn() &&
|
||||||
|
_nbSourceColumn == masqueinfo.GetNbSourceColumn()
|
||||||
|
)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
string Transistor::MaskInfo::_GetString() const
|
||||||
|
// **********************************************
|
||||||
|
{
|
||||||
|
string s = "<" + _GetTypeName() + " "
|
||||||
|
+ GetString(_l) + " "
|
||||||
|
+ GetString(_w) + " "
|
||||||
|
+ _type._GetString() + " "
|
||||||
|
+ GetString(_nbSourceColumn) + " "
|
||||||
|
+ GetString(_nbDrainColumn)
|
||||||
|
+ ">";
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Record* Transistor::MaskInfo::_GetRecord() const
|
||||||
|
// ***********************************************
|
||||||
|
{
|
||||||
|
Record * record = new Record(_GetString());
|
||||||
|
return record;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ****************************************************************************************************
|
||||||
|
// Transistor::MaskV1Info implementation
|
||||||
|
// ****************************************************************************************************
|
||||||
|
Transistor::MaskV1Info::MaskV1Info(const double& l, const double& w, const Type::Code& type
|
||||||
|
, const unsigned& nbDrainColumn
|
||||||
|
, const unsigned& nbSourceColumn)
|
||||||
|
// ****************************************************************************************************
|
||||||
|
: Inherit(l
|
||||||
|
, w
|
||||||
|
, type
|
||||||
|
, nbDrainColumn
|
||||||
|
, nbSourceColumn
|
||||||
|
)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
Transistor::MaskV1Info* Transistor::MaskV1Info::Create(const double& l, const double& w
|
||||||
|
, const Type::Code& type
|
||||||
|
, const unsigned& nbDrainColumn
|
||||||
|
, const unsigned& nbSourceColumn)
|
||||||
|
// **********************************************************************************************
|
||||||
|
{
|
||||||
|
MaskV1Info* masquev1info = new MaskV1Info(l, w, type, nbDrainColumn, nbSourceColumn);
|
||||||
|
|
||||||
|
masquev1info->_PostCreate();
|
||||||
|
|
||||||
|
return masquev1info;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Transistor::MaskInfo& Transistor::MaskV1Info::operator=(const MaskInfo& masqueinfo)
|
||||||
|
// **************************************************************************************
|
||||||
|
{
|
||||||
|
// (*(static_cast<Inherit*>(this)))=masqueinfo;
|
||||||
|
Inherit::operator=(masqueinfo);
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Transistor::MaskV1Info::_PostCreate()
|
||||||
|
// *****************************************
|
||||||
|
{
|
||||||
|
Inherit::_PostCreate();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Transistor::MaskV1Info::_PreDelete()
|
||||||
|
// ****************************************
|
||||||
|
{
|
||||||
|
Inherit::_PreDelete();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Transistor::MaskV1Info::operator == (const MaskInfo& masqueinfo)
|
||||||
|
// **********************************************************************
|
||||||
|
{
|
||||||
|
//return (*(static_cast<Inherit*>(this)))==masqueinfo;
|
||||||
|
return Inherit::operator==(masqueinfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
string Transistor::MaskV1Info::_GetString() const
|
||||||
|
// ************************************************
|
||||||
|
{
|
||||||
|
string s = Inherit::_GetString();
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
Record* Transistor::MaskV1Info::_GetRecord() const
|
||||||
|
// *************************************************
|
||||||
|
{
|
||||||
|
Record* record = Inherit::_GetRecord();
|
||||||
|
return record;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ****************************************************************************************************
|
||||||
|
// Transistor implementation
|
||||||
|
// ****************************************************************************************************
|
||||||
|
|
||||||
|
Transistor::Transistor(Library* library, const Name& name, char type)
|
||||||
|
// *******************************************************************
|
||||||
|
: Inherit(library, name),
|
||||||
|
_type(type),
|
||||||
|
_masqueInfo(NULL),
|
||||||
|
_genTrans(NULL)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Transistor* Transistor::Create(Library* library, const Name& name, char type)
|
||||||
|
// **************************************************************************
|
||||||
|
{
|
||||||
|
Transistor* transistor = new Transistor(library, name, type);
|
||||||
|
|
||||||
|
transistor->_PostCreate();
|
||||||
|
|
||||||
|
return transistor;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void Transistor::_PreDelete()
|
||||||
|
// ******************************
|
||||||
|
{
|
||||||
|
// Delete aggregated objets.
|
||||||
|
// *************************
|
||||||
|
if(_masqueInfo)
|
||||||
|
_masqueInfo->Delete();
|
||||||
|
|
||||||
|
if(_genTrans)
|
||||||
|
delete _genTrans;
|
||||||
|
|
||||||
|
Inherit::_PreDelete();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Transistor::_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);
|
||||||
|
|
||||||
|
// By default, transistor's length and heigth is NULL, and is internal.
|
||||||
|
// ********************************************************************
|
||||||
|
_masqueInfo = new MaskV1Info(0.0, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
string Transistor::_GetString() const
|
||||||
|
// ***********************************
|
||||||
|
{
|
||||||
|
string s = Inherit::_GetString();
|
||||||
|
s.insert(s.length()-1, " " + GetString(_type));
|
||||||
|
s.insert(s.length()-1, " " + GetAbutmentType()._GetString());
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Record* Transistor::_GetRecord() const
|
||||||
|
// ************************************
|
||||||
|
{
|
||||||
|
Record* record = Inherit::_GetRecord();
|
||||||
|
return record;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Transistor::MaskVersion Transistor::_GetMaskInfoVersion(MaskInfo* masqueinfo)
|
||||||
|
// ***************************************************************************************
|
||||||
|
{
|
||||||
|
if(!masqueinfo)
|
||||||
|
throw Error("Error : In Transistor::_GetMaskInfoVersion, param masqueinfo is NULL");
|
||||||
|
|
||||||
|
if(dynamic_cast<MaskV1Info*>(masqueinfo))
|
||||||
|
return MaskVersion(MaskVersion::VERSION1);
|
||||||
|
|
||||||
|
throw Error("Error : In Transistor::_GetMaskInfoVersion, can't dynamic cast param masqueinfo");
|
||||||
|
return MaskVersion(MaskVersion::VERSION1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Transistor::MaskInfo* Transistor::_CreateMaskInfo(const MaskVersion& version)
|
||||||
|
// *******************************************************************************
|
||||||
|
{
|
||||||
|
switch((const MaskVersion::Code&)version) {
|
||||||
|
case MaskVersion::VERSION1 :
|
||||||
|
return MaskV1Info::Create(0.0, 0.0);
|
||||||
|
|
||||||
|
default :
|
||||||
|
throw Error ("Error : In Transistor::_CreateMaskInfoBy, unknown param version");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Transistor::SetMaskInfo(MaskInfo* masqueinfo)
|
||||||
|
// ***************************************************
|
||||||
|
{
|
||||||
|
if(!masqueinfo)
|
||||||
|
throw Error("Error : In Transistor::CreateLayout : masqueinfo is NULL");
|
||||||
|
|
||||||
|
// Set new Param.
|
||||||
|
// ***************
|
||||||
|
MaskVersion newversion = _GetMaskInfoVersion(masqueinfo);
|
||||||
|
MaskVersion oldversion = _GetMaskInfoVersion(_masqueInfo);
|
||||||
|
|
||||||
|
if(newversion == oldversion) { // If they are the same version.
|
||||||
|
if((*_masqueInfo)==(*masqueinfo)) // If they are identical.
|
||||||
|
return;
|
||||||
|
else
|
||||||
|
(*_masqueInfo)=(*masqueinfo);
|
||||||
|
}
|
||||||
|
else { // If change the version.
|
||||||
|
_masqueInfo->Delete();
|
||||||
|
_masqueInfo = _CreateMaskInfo(newversion);
|
||||||
|
(*_masqueInfo) == (*masqueinfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Transistor::CreateLayout()
|
||||||
|
// ****************************
|
||||||
|
{
|
||||||
|
MaskVersion version = _GetMaskInfoVersion(_masqueInfo);
|
||||||
|
MaskV1Info* masquev1info = NULL;
|
||||||
|
|
||||||
|
// Select algorithme with technology and masque version.
|
||||||
|
// *****************************************************
|
||||||
|
switch((const MaskVersion::Code&)version) {
|
||||||
|
|
||||||
|
case MaskVersion::VERSION1 :
|
||||||
|
masquev1info = dynamic_cast<MaskV1Info*>(_masqueInfo);
|
||||||
|
_genTrans = new GenV1Trans(masquev1info);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default :
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetTerminal(false);
|
||||||
|
|
||||||
|
// Launch the selected algorithme.
|
||||||
|
// ******************************
|
||||||
|
_genTrans->Calculate(this);
|
||||||
|
_genTrans->Generate(this);
|
||||||
|
|
||||||
|
Materialize();
|
||||||
|
|
||||||
|
delete _genTrans;
|
||||||
|
_genTrans = NULL;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Transistor::DuplicateLayout(Transistor* transistor)
|
||||||
|
// *****************************************************
|
||||||
|
{
|
||||||
|
OpenUpdateSession();
|
||||||
|
|
||||||
|
SetTerminal(false);
|
||||||
|
|
||||||
|
Net * tmp = NULL;
|
||||||
|
Contact * con = NULL;
|
||||||
|
Segment * seg = NULL;
|
||||||
|
|
||||||
|
for_each_net(net, transistor->GetNets())
|
||||||
|
if( !( tmp=GetNet(net->GetName()) ) ) { //
|
||||||
|
tmp = Net::Create(this, net->GetName());
|
||||||
|
tmp->SetExternal(net->IsExternal());
|
||||||
|
}
|
||||||
|
|
||||||
|
for_each_component(component, net->GetComponents())
|
||||||
|
if( (con=dynamic_cast<Contact*>(component)) ){
|
||||||
|
Contact::Create(tmp, component->GetLayer(), con->GetX(), con->GetY(), con->GetWidth(), con->GetHeight());
|
||||||
|
}
|
||||||
|
else if( (seg=dynamic_cast<Vertical*>(component)) ) {
|
||||||
|
Vertical::Create(tmp, component->GetLayer(), seg->GetSourceX(), seg->GetWidth(), seg->GetSourceY(),
|
||||||
|
seg->GetTargetY());
|
||||||
|
}
|
||||||
|
else if( (seg=dynamic_cast<Horizontal*>(component)) ){
|
||||||
|
Horizontal::Create(tmp, component->GetLayer(), seg->GetSourceY(), seg->GetWidth(), seg->GetSourceX(),
|
||||||
|
seg->GetTargetX());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw Error ("Error : In Transistor::DuplicateLayout, find illegal elem : " + GetString(component) +
|
||||||
|
"In Transistor, all component must be contact or segment" ) ;
|
||||||
|
end_for
|
||||||
|
end_for
|
||||||
|
|
||||||
|
SetAbutmentBox(transistor->GetAbutmentBox());
|
||||||
|
|
||||||
|
_mapNet2Box.clear();
|
||||||
|
|
||||||
|
map<Net*, Box>::iterator i = transistor->_GetMapNet2Box()->begin(),
|
||||||
|
j = transistor->_GetMapNet2Box()->end();
|
||||||
|
|
||||||
|
while(i!=j) {
|
||||||
|
_mapNet2Box[GetNet((*i).first->GetName())]=(*i).second;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
Materialize();
|
||||||
|
|
||||||
|
CloseUpdateSession();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
END_NAMESPACE_HURRICANE
|
||||||
|
|
||||||
|
|
||||||
|
// ****************************************************************************************************
|
||||||
|
// Generic functions
|
||||||
|
// ****************************************************************************************************
|
||||||
|
|
||||||
|
string GetString(const H::Transistor::MaskInfo& masqueinfo)
|
||||||
|
// **********************************************************
|
||||||
|
{
|
||||||
|
return masqueinfo._GetString();
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,344 @@
|
||||||
|
// ****************************************************************************************************
|
||||||
|
// File: Transistor.h
|
||||||
|
// Authors: Wu YiFei
|
||||||
|
// Date : 21/12/2006
|
||||||
|
// ****************************************************************************************************
|
||||||
|
|
||||||
|
#ifndef HURRICANE_TRANSISTOR
|
||||||
|
#define HURRICANE_TRANSISTOR
|
||||||
|
|
||||||
|
#include "Cell.h"
|
||||||
|
#include "AnalogicalCommons.h"
|
||||||
|
|
||||||
|
|
||||||
|
//BEGIN_NAMESPACE_HURRICANE
|
||||||
|
|
||||||
|
namespace Hurricane {
|
||||||
|
|
||||||
|
class Library;
|
||||||
|
class Name;
|
||||||
|
class Symbol;
|
||||||
|
class Record;
|
||||||
|
class GenTrans;
|
||||||
|
|
||||||
|
class Transistor : public Cell {
|
||||||
|
// ********************************
|
||||||
|
|
||||||
|
//# if !defined(__DOXYGEN_PROCESSOR__)
|
||||||
|
|
||||||
|
// Types
|
||||||
|
// *****
|
||||||
|
|
||||||
|
public : typedef Cell Inherit;
|
||||||
|
|
||||||
|
|
||||||
|
public : class MaskVersion {
|
||||||
|
// ******************
|
||||||
|
public : enum Code { VERSION1=0 };
|
||||||
|
|
||||||
|
private: Code _code;
|
||||||
|
|
||||||
|
public : explicit MaskVersion(const Code& code=VERSION1);
|
||||||
|
public : MaskVersion(const MaskVersion&);
|
||||||
|
public : MaskVersion& operator=(const MaskVersion&);
|
||||||
|
|
||||||
|
public : bool operator==(const MaskVersion&) const;
|
||||||
|
|
||||||
|
public : operator const Code& () const { return _code; };
|
||||||
|
public : const Code& GetCode() const { return _code; };
|
||||||
|
|
||||||
|
public : string _GetTypeName() const { return _TName("Transistor::MaskVersion"); };
|
||||||
|
public : string _GetString() const;
|
||||||
|
public : Record* _GetRecord() const;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
public : class Type {
|
||||||
|
// *********
|
||||||
|
|
||||||
|
public : enum Code { INTERNAL=0, LEFT=1, RIGHT=2, SINGLE=3};
|
||||||
|
|
||||||
|
private: Code _code;
|
||||||
|
|
||||||
|
public : explicit Type(const Code& code=INTERNAL);
|
||||||
|
public : Type(const Type& type);
|
||||||
|
public : Type& operator=(const Type& type);
|
||||||
|
public : operator const Code&() const { return _code; };
|
||||||
|
|
||||||
|
public : void SetCode(const Code& code) { _code = code; };
|
||||||
|
|
||||||
|
public : const Code& GetCode() const { return _code; };
|
||||||
|
|
||||||
|
public : string _GetTypeName() const { return _TName("Transistor::Type"); };
|
||||||
|
public : string _GetString() const;
|
||||||
|
public : Record* _GetRecord() const;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
public : class MaskInfo {
|
||||||
|
// ***************
|
||||||
|
|
||||||
|
// Attributs
|
||||||
|
// *********
|
||||||
|
private : double _l;
|
||||||
|
private : double _w ;
|
||||||
|
private : Type _type;
|
||||||
|
private : unsigned _nbDrainColumn;
|
||||||
|
private : unsigned _nbSourceColumn;
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
// ************
|
||||||
|
public : MaskInfo(const double& l, const double& w, const Type::Code& type=Type::INTERNAL
|
||||||
|
, const unsigned& nbDrainColumn=1
|
||||||
|
, const unsigned& nbSourceColumn=1);
|
||||||
|
|
||||||
|
public : virtual MaskInfo& operator=(const MaskInfo&);
|
||||||
|
|
||||||
|
private : MaskInfo(const MaskInfo& );
|
||||||
|
|
||||||
|
protected : virtual void _PostCreate();
|
||||||
|
|
||||||
|
// Destructors
|
||||||
|
// ***********
|
||||||
|
protected: virtual ~MaskInfo() {};
|
||||||
|
protected: virtual void _PreDelete();
|
||||||
|
public : virtual void Delete();
|
||||||
|
|
||||||
|
// Accessors
|
||||||
|
// *********
|
||||||
|
public : const double& GetL() const { return _l; };
|
||||||
|
public : const double& GetW() const { return _w; };
|
||||||
|
public : const unsigned & GetNbDrainColumn() const { return _nbDrainColumn; };
|
||||||
|
public : const unsigned & GetNbSourceColumn() const { return _nbSourceColumn; };
|
||||||
|
public : const Type& GetType() const { return _type; };
|
||||||
|
|
||||||
|
// Update
|
||||||
|
// ******
|
||||||
|
public : void SetL(const double& l) { _l=l;};
|
||||||
|
public : void SetW(const double& w) { _w=w;};
|
||||||
|
public : void SetNbDrainColumn(const unsigned& column) { _nbDrainColumn=column; };
|
||||||
|
public : void SetNbSourceColumn(const unsigned& column) { _nbSourceColumn=column; };
|
||||||
|
public : void SetType(const Type::Code& code) { _type.SetCode(code); };
|
||||||
|
public : void SetType(const Type& type) { _type = type; };
|
||||||
|
|
||||||
|
// Predicats
|
||||||
|
// *********
|
||||||
|
|
||||||
|
// Operators
|
||||||
|
// *********
|
||||||
|
public : virtual bool operator==(const MaskInfo&);
|
||||||
|
|
||||||
|
// Others
|
||||||
|
// ******
|
||||||
|
public : virtual string _GetTypeName() const =0;
|
||||||
|
public : virtual string _GetString() const;
|
||||||
|
public : virtual Record* _GetRecord() const;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
public : class MaskV1Info : public MaskInfo {
|
||||||
|
// *************************************
|
||||||
|
|
||||||
|
// type
|
||||||
|
// *****
|
||||||
|
public : typedef MaskInfo Inherit ;
|
||||||
|
|
||||||
|
// Attributs
|
||||||
|
// *********
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
// ************
|
||||||
|
public: MaskV1Info(const double& l, const double& w, const Type::Code& type=Type::INTERNAL
|
||||||
|
, const unsigned& nbDrainColumn = 1
|
||||||
|
, const unsigned& nbSourceColumn = 1);
|
||||||
|
|
||||||
|
public: static MaskV1Info* Create(const double& l, const double& w, const Type::Code& type=Type::INTERNAL
|
||||||
|
, const unsigned& nbDrainColumn = 1
|
||||||
|
, const unsigned& nbSourceColumn = 1);
|
||||||
|
|
||||||
|
public : MaskInfo& operator=(const MaskInfo&);
|
||||||
|
|
||||||
|
protected : void _PostCreate();
|
||||||
|
|
||||||
|
// Destructor
|
||||||
|
// ***********
|
||||||
|
public : virtual ~MaskV1Info() {};
|
||||||
|
protected: void _PreDelete();
|
||||||
|
|
||||||
|
// Operators
|
||||||
|
// *********
|
||||||
|
public : bool operator==(const MaskInfo&);
|
||||||
|
|
||||||
|
// Others
|
||||||
|
// *********
|
||||||
|
public : virtual string _GetTypeName() const { return _TName("Transistor::MaskV1Info"); };
|
||||||
|
public : virtual string _GetString() const;
|
||||||
|
public : virtual Record* _GetRecord() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
# if !defined(__DOXYGEN_PROCESSOR__)
|
||||||
|
|
||||||
|
// Attributes
|
||||||
|
// *******************
|
||||||
|
private : char _type;
|
||||||
|
private : MaskInfo* _masqueInfo;
|
||||||
|
private : GenTrans * _genTrans;
|
||||||
|
//public : RealInfo * _realInfo;
|
||||||
|
|
||||||
|
private : map<Net*, Box> _mapNet2Box; // This Map Is For localize The Position Of Routing.
|
||||||
|
|
||||||
|
# endif
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
// ************
|
||||||
|
# if !defined(__DOXYGEN_PROCESSOR__)
|
||||||
|
protected : Transistor(Library* library, const Name& name, char type);
|
||||||
|
# endif
|
||||||
|
|
||||||
|
public : static Transistor* Create(Library* library, const Name& name, char type);
|
||||||
|
|
||||||
|
# if !defined(__DOXYGEN_PROCESSOR__)
|
||||||
|
protected : virtual void _PostCreate();
|
||||||
|
|
||||||
|
|
||||||
|
// Destructors
|
||||||
|
// ***********
|
||||||
|
protected : ~Transistor() {};
|
||||||
|
protected : virtual void _PreDelete();
|
||||||
|
# endif
|
||||||
|
|
||||||
|
// Accessors
|
||||||
|
// *********
|
||||||
|
public : char GetType() const { return _type; };
|
||||||
|
public : MaskVersion GetMaskVersion() const { return _GetMaskInfoVersion(_masqueInfo); };
|
||||||
|
public : const MaskInfo* GetMaskInfo() const { return _masqueInfo; };
|
||||||
|
public : const double& GetL() const { return _masqueInfo->GetL(); };
|
||||||
|
public : const double& GetW() const { return _masqueInfo->GetW(); };
|
||||||
|
public : const unsigned& GetNbDrainColumn() const { return _masqueInfo->GetNbDrainColumn(); };
|
||||||
|
public : const unsigned& GetNbSourceColumn() const { return _masqueInfo->GetNbSourceColumn(); };
|
||||||
|
public : const char* GetDrainName() const { return "DRAIN"; };
|
||||||
|
public : const char* GetSourceName() const { return "SOURCE"; };
|
||||||
|
public : const char* GetGridName() const { return "GRID"; };
|
||||||
|
public : Net* GetDrain() const { return GetNet(GetDrainName()); };
|
||||||
|
public : Net* GetSource() const { return GetNet(GetSourceName()); };
|
||||||
|
public : Net* GetGrid() const { return GetNet(GetGridName()); };
|
||||||
|
public : const Type& GetAbutmentType() const { return _masqueInfo->GetType(); };
|
||||||
|
|
||||||
|
// Predicats
|
||||||
|
// *********
|
||||||
|
public : bool IsNmos() const { return _type==TRANSN; };
|
||||||
|
public : bool IsPmos() const { return _type==TRANSP; };
|
||||||
|
public : bool IsInternal() const { return GetAbutmentType().GetCode()==Type::INTERNAL; };
|
||||||
|
public : bool IsLeft() const { return GetAbutmentType().GetCode()==Type::LEFT; };
|
||||||
|
public : bool IsRight() const { return GetAbutmentType().GetCode()==Type::RIGHT; };
|
||||||
|
public : bool IsSingle() const { return GetAbutmentType().GetCode()==Type::SINGLE; };
|
||||||
|
|
||||||
|
// Updators
|
||||||
|
// ********
|
||||||
|
public : void SetL(const double& l) { _masqueInfo->SetL(l); };
|
||||||
|
public : void SetW(const double& w) { _masqueInfo->SetW(w); };
|
||||||
|
|
||||||
|
//# endif
|
||||||
|
|
||||||
|
# if !defined(__DOXYGEN_PROCESSOR__)
|
||||||
|
// Others
|
||||||
|
// ******
|
||||||
|
public : virtual string _GetTypeName() const {return _TName("Transistor");};
|
||||||
|
public : virtual string _GetString() const;
|
||||||
|
public : virtual Record* _GetRecord() const;
|
||||||
|
public : const GenTrans* _GetGenTrans() const {return _genTrans; };
|
||||||
|
public : static MaskVersion _GetMaskInfoVersion(MaskInfo*) ;
|
||||||
|
public : static MaskInfo* _CreateMaskInfo(const MaskVersion&) ;
|
||||||
|
public : map<Net*, Box>* _GetMapNet2Box() { return &_mapNet2Box; };
|
||||||
|
|
||||||
|
# endif
|
||||||
|
|
||||||
|
// Operators
|
||||||
|
// *********
|
||||||
|
public : void SetMaskInfo(MaskInfo*);
|
||||||
|
public : void CreateLayout();
|
||||||
|
public : void DuplicateLayout(Transistor* transistor) ;
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
# if !defined(__DOXYGEN_PROCESSOR__)
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
// Class : "Proxy...<const Transistor::MaskVersion::Code*>".
|
||||||
|
|
||||||
|
template<>
|
||||||
|
inline string ProxyTypeName<Transistor::MaskVersion::Code>
|
||||||
|
( const Transistor::MaskVersion::Code* object )
|
||||||
|
{ return "<PointerSlotAdapter<Transistor::MaskVersion::Code>>"; }
|
||||||
|
|
||||||
|
template<>
|
||||||
|
inline string ProxyString <Transistor::MaskVersion::Code>
|
||||||
|
( const Transistor::MaskVersion::Code* object )
|
||||||
|
{
|
||||||
|
switch ( *object ) {
|
||||||
|
case Transistor::MaskVersion::VERSION1: return "VERSION1";
|
||||||
|
}
|
||||||
|
return "ABNORMAL";
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
inline Record* ProxyRecord <Transistor::MaskVersion::Code>
|
||||||
|
( const Transistor::MaskVersion::Code* object )
|
||||||
|
{
|
||||||
|
Record* record = new Record(GetString(object));
|
||||||
|
record->Add(GetSlot("Code", (unsigned int*)object));
|
||||||
|
return record;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
// Class : "Proxy...<const Transistor::Type::Code*>".
|
||||||
|
|
||||||
|
template<>
|
||||||
|
inline string ProxyTypeName<Transistor::Type::Code>
|
||||||
|
( const Transistor::Type::Code* object )
|
||||||
|
{ return "<PointerSlotAdapter<Transistor::Type::Code>>"; }
|
||||||
|
|
||||||
|
template<>
|
||||||
|
inline string ProxyString <Transistor::Type::Code>
|
||||||
|
( const Transistor::Type::Code* object )
|
||||||
|
{
|
||||||
|
switch ( *object ) {
|
||||||
|
case Transistor::Type::LEFT : return "LEFT";
|
||||||
|
case Transistor::Type::SINGLE: return "SINGLE";
|
||||||
|
case Transistor::Type::RIGHT: return "RIGHT";
|
||||||
|
case Transistor::Type::INTERNAL: return "INTERNAL";
|
||||||
|
}
|
||||||
|
return "ABNORMAL";
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
inline Record* ProxyRecord <Transistor::Type::Code>
|
||||||
|
( const Transistor::Type::Code* object )
|
||||||
|
{
|
||||||
|
Record* record = new Record(GetString(object));
|
||||||
|
record->Add(GetSlot("Code", (unsigned int*)object));
|
||||||
|
return record;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//END_NAMESPACE_HURRICANE
|
||||||
|
|
||||||
|
|
||||||
|
// ****************************************************************************************************
|
||||||
|
// Generic functions
|
||||||
|
// ****************************************************************************************************
|
||||||
|
|
||||||
|
string GetString(const H::Transistor::MaskInfo&);
|
||||||
|
|
||||||
|
|
||||||
|
#endif // HURRICANE_TRANSISTOR
|
|
@ -0,0 +1,59 @@
|
||||||
|
|
||||||
|
// ****************************************************************************************************
|
||||||
|
// File: Transistors.h
|
||||||
|
// Authors: YIFEI WU
|
||||||
|
// Date : 21/12/2006
|
||||||
|
// ****************************************************************************************************
|
||||||
|
|
||||||
|
#ifndef HURRICANE_TRANSISTORS
|
||||||
|
#define HURRICANE_TRANSISTORS
|
||||||
|
|
||||||
|
#include "Collection.h"
|
||||||
|
|
||||||
|
BEGIN_NAMESPACE_HURRICANE
|
||||||
|
|
||||||
|
class Transistor;
|
||||||
|
|
||||||
|
|
||||||
|
// ****************************************************************************************************
|
||||||
|
// Transistors declaration
|
||||||
|
// ****************************************************************************************************
|
||||||
|
|
||||||
|
typedef GenericCollection<Transistor*> Transistors;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ****************************************************************************************************
|
||||||
|
// TransistorLocator declaration
|
||||||
|
// ****************************************************************************************************
|
||||||
|
|
||||||
|
typedef GenericLocator<Transistor*> TransistorLocator;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ****************************************************************************************************
|
||||||
|
// TransistorFilter declaration
|
||||||
|
// ****************************************************************************************************
|
||||||
|
|
||||||
|
typedef GenericFilter<Transistor*> TransistorFilter;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ****************************************************************************************************
|
||||||
|
// for_each_transistor declaration
|
||||||
|
// ****************************************************************************************************
|
||||||
|
|
||||||
|
#define for_each_transistor(transistor, transistors)\
|
||||||
|
/******************************/\
|
||||||
|
{\
|
||||||
|
TransistorLocator _locator = transistors.GetLocator();\
|
||||||
|
while (_locator.IsValid()) {\
|
||||||
|
Transistor* transistor = _locator.GetElement();\
|
||||||
|
_locator.Progress();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
END_NAMESPACE_HURRICANE
|
||||||
|
|
||||||
|
#endif // HURRICANE_TRANSISTORS
|
||||||
|
|
|
@ -0,0 +1,123 @@
|
||||||
|
// **************************************************************
|
||||||
|
// TwoSpaces.cpp
|
||||||
|
// Author : Wu YiFei
|
||||||
|
// Date : 12/04/2007
|
||||||
|
// ***************************************************************
|
||||||
|
|
||||||
|
#include "TwoSpaces.h"
|
||||||
|
|
||||||
|
|
||||||
|
BEGIN_NAMESPACE_HURRICANE
|
||||||
|
|
||||||
|
// ****************************************************************************************************
|
||||||
|
// Two Spaces definition.
|
||||||
|
// ****************************************************************************************************
|
||||||
|
TwoSpaces::TwoSpaces(const string& s)
|
||||||
|
// *********************************
|
||||||
|
: _s(s)
|
||||||
|
,_n(1)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TwoSpaces::TwoSpaces(const TwoSpaces& ts)
|
||||||
|
// **************************************
|
||||||
|
: _s(ts._s)
|
||||||
|
,_n(ts._n)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TwoSpaces& TwoSpaces::operator=(const TwoSpaces& ts)
|
||||||
|
// ************************************************
|
||||||
|
{
|
||||||
|
_s = ts._s;
|
||||||
|
_n = ts._n;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TwoSpaces& TwoSpaces::operator++()
|
||||||
|
// *******************************
|
||||||
|
{
|
||||||
|
if(_n<100) _n++;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
TwoSpaces TwoSpaces::operator++(int)
|
||||||
|
// *********************************
|
||||||
|
{
|
||||||
|
TwoSpaces ts = *this;
|
||||||
|
if(_n<100) _n++;
|
||||||
|
return ts;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TwoSpaces& TwoSpaces::operator--()
|
||||||
|
// *******************************
|
||||||
|
{
|
||||||
|
if(_n>1) _n--;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TwoSpaces TwoSpaces::operator--(int)
|
||||||
|
// *********************************
|
||||||
|
{
|
||||||
|
TwoSpaces ts = *this;
|
||||||
|
if(_n>1) _n--;
|
||||||
|
return ts;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TwoSpaces TwoSpaces::operator+(int count)
|
||||||
|
// **************************************
|
||||||
|
{
|
||||||
|
TwoSpaces ts = *this;
|
||||||
|
if( (_n+count) <= 100 ) ts._n = _n + count;
|
||||||
|
return ts;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TwoSpaces TwoSpaces::operator-(int count)
|
||||||
|
// **************************************
|
||||||
|
{
|
||||||
|
TwoSpaces ts = *this;
|
||||||
|
if ( (_n - count) >= 1 ) ts._n = _n - count;
|
||||||
|
return ts;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
string TwoSpaces::_GetString() const
|
||||||
|
// *********************************
|
||||||
|
{
|
||||||
|
string s;
|
||||||
|
unsigned n = _n;
|
||||||
|
|
||||||
|
while(n--) {
|
||||||
|
s += _s;
|
||||||
|
}
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ****************************************************************************************************
|
||||||
|
// Variables definition.
|
||||||
|
// ****************************************************************************************************
|
||||||
|
TwoSpaces ts(" ");
|
||||||
|
|
||||||
|
|
||||||
|
END_NAMESPACE_HURRICANE
|
||||||
|
|
||||||
|
|
||||||
|
// ****************************************************************************************************
|
||||||
|
// Generic functions
|
||||||
|
// ****************************************************************************************************
|
||||||
|
string GetString(const H::TwoSpaces& ts)
|
||||||
|
// ***********************************
|
||||||
|
{
|
||||||
|
return ts._GetString();
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,72 @@
|
||||||
|
// **************************************************************
|
||||||
|
// TwoSpaces.h
|
||||||
|
// Author : Wu YiFei
|
||||||
|
// Date : 12/04/2007
|
||||||
|
// ***************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
# ifndef HURRICANE_TWOSPACES
|
||||||
|
# define HURRICANE_TWOSPACES
|
||||||
|
|
||||||
|
# include "Commons.h"
|
||||||
|
|
||||||
|
|
||||||
|
BEGIN_NAMESPACE_HURRICANE
|
||||||
|
|
||||||
|
// ****************************************************************************************************
|
||||||
|
// TwoSpaces declaration.
|
||||||
|
// ****************************************************************************************************
|
||||||
|
class TwoSpaces {
|
||||||
|
// ***************
|
||||||
|
|
||||||
|
// Attributes
|
||||||
|
// **********
|
||||||
|
private : string _s;
|
||||||
|
private : unsigned _n;
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
// *************
|
||||||
|
public : TwoSpaces(const string& s = " ");
|
||||||
|
public : TwoSpaces(const TwoSpaces&);
|
||||||
|
|
||||||
|
// Destructors
|
||||||
|
// ***********
|
||||||
|
public : ~TwoSpaces(){};
|
||||||
|
|
||||||
|
// Operators
|
||||||
|
// *********
|
||||||
|
public : TwoSpaces& operator=(const TwoSpaces&);
|
||||||
|
public : TwoSpaces& operator++();
|
||||||
|
public : TwoSpaces operator++(int);
|
||||||
|
public : TwoSpaces& operator--();
|
||||||
|
public : TwoSpaces operator--(int);
|
||||||
|
public : TwoSpaces operator+(int);
|
||||||
|
public : TwoSpaces operator-(int);
|
||||||
|
|
||||||
|
// Others
|
||||||
|
// ******
|
||||||
|
public : string _GetString() const ;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// ****************************************************************************************************
|
||||||
|
// Variables declaration.
|
||||||
|
// ****************************************************************************************************
|
||||||
|
extern TwoSpaces ts;
|
||||||
|
|
||||||
|
END_NAMESPACE_HURRICANE
|
||||||
|
|
||||||
|
|
||||||
|
// ****************************************************************************************************
|
||||||
|
// Generic functions
|
||||||
|
// ****************************************************************************************************
|
||||||
|
string GetString(const H::TwoSpaces&);
|
||||||
|
|
||||||
|
inline ostream& operator<<(ostream& stream, const H::TwoSpaces& ts)
|
||||||
|
// ****************************************************************
|
||||||
|
{
|
||||||
|
return stream<< GetString(ts);
|
||||||
|
}
|
||||||
|
|
||||||
|
# endif // END HURRICANE_TWOSPACES
|
|
@ -0,0 +1,6 @@
|
||||||
|
INCLUDE_DIRECTORIES(${HURRICANE_INCLUDE_DIR} ${CHAMSIN_SOURCE_DIR}/src/dtr
|
||||||
|
${CHAMSIN_SOURCE_DIR}/src/analogic)
|
||||||
|
|
||||||
|
ADD_LIBRARY(device SHARED Device.cpp TrMos.cpp TrMos_PlaceRoute.cpp)
|
||||||
|
|
||||||
|
TARGET_LINK_LIBRARIES(device analogic dtr hurricane)
|
|
@ -0,0 +1,203 @@
|
||||||
|
// ****************************************************************************************************
|
||||||
|
// 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"
|
||||||
|
#include "GenericDtrAccess.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::Delete()
|
||||||
|
// **************************
|
||||||
|
{
|
||||||
|
_PreDelete();
|
||||||
|
delete this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Device::_PreDelete()
|
||||||
|
// ******************************
|
||||||
|
{
|
||||||
|
// do something
|
||||||
|
// ************
|
||||||
|
|
||||||
|
Inherit::_PreDelete();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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());
|
||||||
|
|
||||||
|
// Create GenericDtrAccess and DtrAccess
|
||||||
|
// *************************************
|
||||||
|
GenericDtrAccess::Instance(DtrAccess::Instance());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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++;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
string Device::_GetString() const
|
||||||
|
// ***************************************
|
||||||
|
{
|
||||||
|
string s= Inherit::_GetString();
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
Record* Device::_GetRecord() const
|
||||||
|
// *********************************
|
||||||
|
{
|
||||||
|
Record* record = Inherit::_GetRecord();
|
||||||
|
return record;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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,105 @@
|
||||||
|
|
||||||
|
// ****************************************************************************************************
|
||||||
|
// File: Device.h
|
||||||
|
// Authors: Wu YiFei
|
||||||
|
// Date : 21/12/2006
|
||||||
|
// ****************************************************************************************************
|
||||||
|
|
||||||
|
#ifndef DEVICE_DEVICE
|
||||||
|
#define DEVICE_DEVICE
|
||||||
|
|
||||||
|
|
||||||
|
#include "Cell.h"
|
||||||
|
using Hurricane::Cell;
|
||||||
|
using Hurricane::_TName;
|
||||||
|
|
||||||
|
|
||||||
|
namespace Hurricane {
|
||||||
|
|
||||||
|
class Library;
|
||||||
|
class Name;
|
||||||
|
class Record;
|
||||||
|
class Point;
|
||||||
|
class Transformation;
|
||||||
|
// class Transformation::Orientation;
|
||||||
|
class Instance;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
namespace DEVICE {
|
||||||
|
|
||||||
|
using Hurricane::Library;
|
||||||
|
using Hurricane::Name;
|
||||||
|
using Hurricane::Record;
|
||||||
|
using Hurricane::Point;
|
||||||
|
using Hurricane::Transformation;
|
||||||
|
//using Hurricane::Transformation::Orientation;
|
||||||
|
using Hurricane::Instance;
|
||||||
|
|
||||||
|
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();
|
||||||
|
|
||||||
|
|
||||||
|
// Destructors
|
||||||
|
// ***********
|
||||||
|
protected : ~Device() {};
|
||||||
|
public : virtual void Delete();
|
||||||
|
protected : virtual void _PreDelete();
|
||||||
|
# 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 string _GetTypeName() const {return _TName("Device"); };
|
||||||
|
public: virtual string _GetString() const;
|
||||||
|
public: virtual Record* _GetRecord() const;
|
||||||
|
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
|
||||||
|
|
||||||
|
} ;
|
||||||
|
|
||||||
|
|
||||||
|
} // end namespace Device
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,77 @@
|
||||||
|
// ****************************************************************************************************
|
||||||
|
// File: DeviceUtil.h
|
||||||
|
// Authors: Wu YiFei
|
||||||
|
// Date : 28/05/2006
|
||||||
|
// ****************************************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
# ifndef DEVICEUTIL_H
|
||||||
|
# define DEVICEUTIL_H
|
||||||
|
|
||||||
|
|
||||||
|
// ****************************************************************************************************
|
||||||
|
// Identifier Declaration.
|
||||||
|
// ****************************************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace DEVICE {
|
||||||
|
|
||||||
|
// ****************************************************************************************************
|
||||||
|
// Constants.
|
||||||
|
// ****************************************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
// ****************************************************************************************************
|
||||||
|
// Macros.
|
||||||
|
// ****************************************************************************************************
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------
|
||||||
|
// Macro Method "RETURN_EVEN(num)"
|
||||||
|
// This Method Macro is return a number even.
|
||||||
|
|
||||||
|
/* \num must be a integer.
|
||||||
|
*/
|
||||||
|
|
||||||
|
# define RETURN_EVEN(num) \
|
||||||
|
(num%2)==0?num:num+1
|
||||||
|
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------
|
||||||
|
// Macro Method "MAX_INTEGER(a, b)"
|
||||||
|
// This Method Macro is return the Max between a and b.
|
||||||
|
|
||||||
|
/* \a must be a integer.
|
||||||
|
* \b must be a integer.
|
||||||
|
*/
|
||||||
|
|
||||||
|
# define MAX_INTEGER(a, b) \
|
||||||
|
a>b?a:b
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ****************************************************************************************************
|
||||||
|
// Class.
|
||||||
|
// ****************************************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
// ****************************************************************************************************
|
||||||
|
// Variables.
|
||||||
|
// ****************************************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
// ****************************************************************************************************
|
||||||
|
// Utilitarians (functions).
|
||||||
|
// ****************************************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
} // END OF NAMESPACE DEVICE
|
||||||
|
|
||||||
|
|
||||||
|
// ****************************************************************************************************
|
||||||
|
// Generic Functions.
|
||||||
|
// ****************************************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
# endif
|
|
@ -0,0 +1,462 @@
|
||||||
|
// ****************************************************************************************************
|
||||||
|
// File: TrMos.cpp
|
||||||
|
// Authors: Wu YiFei
|
||||||
|
// Date : 21/12/2006
|
||||||
|
// ****************************************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
#include "TrMos.h"
|
||||||
|
|
||||||
|
#include "Instance.h"
|
||||||
|
#include "MetaTransistor.h"
|
||||||
|
#include "Net.h"
|
||||||
|
#include "Transistor.h"
|
||||||
|
#include "Transistors.h"
|
||||||
|
|
||||||
|
#include "UpdateSession.h"
|
||||||
|
|
||||||
|
#include "DtrAccess.h"
|
||||||
|
using namespace Hurricane;
|
||||||
|
|
||||||
|
|
||||||
|
namespace DEVICE{
|
||||||
|
|
||||||
|
// ****************************************************************************************************
|
||||||
|
// TrMos implementation
|
||||||
|
// ****************************************************************************************************
|
||||||
|
|
||||||
|
TrMos::TrMos(Library* library, const Name& name)
|
||||||
|
// **************************************************************************
|
||||||
|
: Inherit(library, name),
|
||||||
|
_type('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::Delete()
|
||||||
|
// *****************
|
||||||
|
{
|
||||||
|
_PreDelete();
|
||||||
|
delete this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void TrMos::_PreDelete()
|
||||||
|
// ******************************
|
||||||
|
{
|
||||||
|
// do something
|
||||||
|
// ************
|
||||||
|
|
||||||
|
Inherit::_PreDelete();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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::Instance())->GetSingleRealRuleByLabel(string("RW_ALU1"));
|
||||||
|
|
||||||
|
_widthOfSourceWire = minWidth;
|
||||||
|
_widthOfDrainWire = minWidth;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Transistors TrMos::GetTransistors() const
|
||||||
|
// **************************************
|
||||||
|
{
|
||||||
|
return GetCollection(_transistorList);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void TrMos::Create(const char type, const bool isbsconnected)
|
||||||
|
// **********************************************************
|
||||||
|
{
|
||||||
|
if( _tr1 ) {
|
||||||
|
throw Error("Can't Create Logical View of TrMos " + GetString(GetName()) + " : "
|
||||||
|
+ "it has already been created");
|
||||||
|
}
|
||||||
|
|
||||||
|
if( (type!=TRANSN) && (type!=TRANSP)) {
|
||||||
|
throw Error("Can't Create TrMos " + GetString(GetName()) + " : type " + GetString(type) + " is invalid");
|
||||||
|
}
|
||||||
|
|
||||||
|
_type = type;
|
||||||
|
_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" ), _type);
|
||||||
|
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 << ts << "################################################################" <<endl
|
||||||
|
<< ts << "#### BEGIN AUTOGENERATON FOR " + _GetTypeName() + " " + GetString(GetName()) + " #####" <<endl
|
||||||
|
<< ts << "################################################################" <<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)
|
||||||
|
, _type
|
||||||
|
);
|
||||||
|
|
||||||
|
_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 << ts << GetString(_tr1) + " 's M is " + GetString(_tr1->GetM()) + ".\n"
|
||||||
|
<< ts << 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 = Transistor::MaskV1Info::Create( 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++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
masqueinfo->Delete();
|
||||||
|
|
||||||
|
IF_DEBUG_HUR_ANALOG
|
||||||
|
cout << "*** Stage 3 : CreateLayout of " + GetString(this) + " finish ***" <<endl;
|
||||||
|
cout << ts << "Real l_finger is " + GetString(l_finger) + "." << endl
|
||||||
|
<< ts << "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 << ts << "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 << ts << "Real l of " << (long)_tr1 << GetString(_tr1) + " is " + GetString(_tr1->_le) + "." << endl
|
||||||
|
// << ts << "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 << ts << GetString(instance) <<" 's boundingBox is " << GetString(instance->GetBoundingBox())<<endl;
|
||||||
|
END_IF
|
||||||
|
|
||||||
|
end_for
|
||||||
|
|
||||||
|
// CloseUpdateSession();
|
||||||
|
|
||||||
|
IF_DEBUG_HUR_ANALOG
|
||||||
|
cout << ts << GetString(this) << " 's primary (without wire) boundingBox is " << GetString(GetBoundingBox()) <<endl;
|
||||||
|
END_IF
|
||||||
|
|
||||||
|
Materialize();
|
||||||
|
|
||||||
|
IF_DEBUG_HUR_ANALOG
|
||||||
|
cout << ts << GetString(this) << " 's boundingBox is " << GetString(GetBoundingBox()) <<endl;
|
||||||
|
END_IF
|
||||||
|
|
||||||
|
cout << ts << endl
|
||||||
|
<< ts << "################################################################" <<endl
|
||||||
|
<< ts << "#### END AUTOGENERATON FOR " + _GetTypeName() + " " + GetString(GetName()) + " #####" <<endl
|
||||||
|
<< ts << "################################################################" <<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,161 @@
|
||||||
|
// ****************************************************************************************************
|
||||||
|
// File: TrMos.h
|
||||||
|
// Authors: Wu YiFei
|
||||||
|
// Date : 21/12/2006
|
||||||
|
// ****************************************************************************************************
|
||||||
|
|
||||||
|
#ifndef DEVICE_TRMOS
|
||||||
|
#define DEVICE_TRMOS
|
||||||
|
|
||||||
|
|
||||||
|
#include "Device.h"
|
||||||
|
#include "Transistors.h"
|
||||||
|
#include "MetaTransistor.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace Hurricane {
|
||||||
|
|
||||||
|
class Library;
|
||||||
|
class Name;
|
||||||
|
class Record;
|
||||||
|
class Transistor;
|
||||||
|
|
||||||
|
class Net;
|
||||||
|
class Pin;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace DEVICE {
|
||||||
|
|
||||||
|
using Hurricane::Library;
|
||||||
|
using Hurricane::Name;
|
||||||
|
using Hurricane::Record;
|
||||||
|
using Hurricane::MetaTransistor;
|
||||||
|
using Hurricane::Transistor;
|
||||||
|
using Hurricane::Transistors;
|
||||||
|
using Hurricane::Net;
|
||||||
|
using Hurricane::Pin;
|
||||||
|
|
||||||
|
|
||||||
|
class TrMos : public Device {
|
||||||
|
// **************************
|
||||||
|
|
||||||
|
# if !defined(__DOXYGEN_PROCESSOR__)
|
||||||
|
// Types
|
||||||
|
// *****
|
||||||
|
public : typedef Device Inherit;
|
||||||
|
|
||||||
|
public : enum PinName { D, G, S, B };
|
||||||
|
|
||||||
|
// Attributes
|
||||||
|
// *******************
|
||||||
|
|
||||||
|
// Structural parameter.
|
||||||
|
// ********************
|
||||||
|
private : char _type;
|
||||||
|
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();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
public : static TrMos* Create(Library* library, const Name & name);
|
||||||
|
|
||||||
|
|
||||||
|
# if !defined(__DOXYGEN_PROCESSOR__)
|
||||||
|
// Destructors
|
||||||
|
// ***********
|
||||||
|
protected : ~TrMos() {};
|
||||||
|
public : virtual void Delete();
|
||||||
|
protected : virtual void _PreDelete();
|
||||||
|
|
||||||
|
|
||||||
|
// Operations
|
||||||
|
// **********
|
||||||
|
public : virtual void Dses() { /* to do */};
|
||||||
|
public : virtual void Shape() { /* to do */};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
public : void Create(const char type, const bool isbsconnected);
|
||||||
|
public : void Generate(const unsigned m, const bool sourceisfirst, const bool hasring,
|
||||||
|
const unsigned nbsourcecolumn, const unsigned nbdraincolumn);
|
||||||
|
|
||||||
|
// Accessors
|
||||||
|
// *********
|
||||||
|
public : char GetType() const { return _type; };
|
||||||
|
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; };
|
||||||
|
public : Transistors GetTransistors() const ;
|
||||||
|
|
||||||
|
// 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
|
||||||
|
|
||||||
|
} ;
|
||||||
|
|
||||||
|
} // end of namespace Device
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,689 @@
|
||||||
|
// ****************************************************************************************************
|
||||||
|
// 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::Instance();
|
||||||
|
|
||||||
|
char type;
|
||||||
|
if(_type == 'P') type = 'N';
|
||||||
|
else type = 'P';
|
||||||
|
|
||||||
|
long minImpWidth = dtraccess->GetSingleRdsRuleByLabel("RW_", GetString(type), "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(type), "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)) );
|
||||||
|
|
||||||
|
OpenUpdateSession();
|
||||||
|
|
||||||
|
if(_m == 1 ) { // If there is only one finger.
|
||||||
|
_Place( instance, Transformation::Orientation::ID, Point( horizontalMargin, verticalLowMargin ) );
|
||||||
|
//CloseUpdateSession();
|
||||||
|
//return;
|
||||||
|
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
CloseUpdateSession();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Set AbutmentBox.
|
||||||
|
// ****************
|
||||||
|
for_each_instance(instance, GetInstances())
|
||||||
|
instance->Unmaterialize();
|
||||||
|
instance->Materialize();
|
||||||
|
end_for
|
||||||
|
|
||||||
|
OpenUpdateSession();
|
||||||
|
|
||||||
|
|
||||||
|
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(_type == '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(_type == 'P') {
|
||||||
|
Net * netCaisson = Net::Create(this, Name("CAISSON"));
|
||||||
|
Contact::Create(netCaisson, layerNwell
|
||||||
|
, GetAbutmentBox().getXCenter()
|
||||||
|
, GetAbutmentBox().getYCenter()
|
||||||
|
, GetAbutmentBox().getWidth()
|
||||||
|
, GetAbutmentBox().getHeight()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
CloseUpdateSession();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} // END OF NAMESPACE DEVICE
|
|
@ -0,0 +1,34 @@
|
||||||
|
ADD_CUSTOM_TARGET(DTRParser echo "Creating DTRParser")
|
||||||
|
|
||||||
|
SET(source_dir ${CHAMSIN_SOURCE_DIR}/src/dtr)
|
||||||
|
SET(binary_dir ${CHAMSIN_BINARY_DIR}/src/dtr)
|
||||||
|
|
||||||
|
INCLUDE_DIRECTORIES(${HURRICANE_INCLUDE_DIR} ${source_dir})
|
||||||
|
|
||||||
|
ADD_CUSTOM_COMMAND(
|
||||||
|
SOURCE ${source_dir}/ParserDtrScan.ll
|
||||||
|
COMMAND ${FLEX_EXECUTABLE}
|
||||||
|
ARGS -Pdtr -o${binary_dir}/ParserDtrScan.cpp
|
||||||
|
${source_dir}/ParserDtrScan.ll
|
||||||
|
TARGET DTRParser
|
||||||
|
OUTPUTS ${binary_dir}/ParserDtrScan.cpp)
|
||||||
|
|
||||||
|
ADD_CUSTOM_COMMAND(
|
||||||
|
SOURCE ${source_dir}/ParserDtrGram.yy
|
||||||
|
COMMAND ${BISON_EXECUTABLE}
|
||||||
|
ARGS -d -v -p dtr -y ${source_dir}/ParserDtrGram.yy
|
||||||
|
-o ${binary_dir}/ParserDtrGram.cpp
|
||||||
|
TARGET DSTParser
|
||||||
|
DEPENDS ${binary_dir}/ParserDtrScan.cpp
|
||||||
|
OUTPUTS ${binary_dir}/ParserDtrGram.cpp)
|
||||||
|
|
||||||
|
SET(DST_SRCS ${DST_SRCS} ${binary_dir}/ParserDtrGram.cpp
|
||||||
|
${binary_dir}/ParserDtrScan.cpp)
|
||||||
|
|
||||||
|
SET_SOURCE_FILES_PROPERTIES(${binary_dir}/ParserDtrGram.cpp GENERATED)
|
||||||
|
SET_SOURCE_FILES_PROPERTIES(${binary_dir}/ParserDtrScan.cpp GENERATED)
|
||||||
|
|
||||||
|
ADD_LIBRARY(dtr SHARED
|
||||||
|
${DST_SRCS}
|
||||||
|
DtrAccess.cpp
|
||||||
|
GenericDtrAccess.cpp)
|
|
@ -0,0 +1,307 @@
|
||||||
|
// ****************************************************************************************************
|
||||||
|
// File: DtrAccess.cpp
|
||||||
|
// Authors: Wu YiFei
|
||||||
|
// Date : 21/12/2006
|
||||||
|
// ****************************************************************************************************
|
||||||
|
|
||||||
|
#include "DtrAccess.h"
|
||||||
|
#include "RdsUnit.h"
|
||||||
|
#include "Error.h"
|
||||||
|
|
||||||
|
#include "DataBase.h"
|
||||||
|
#include "Technology.h"
|
||||||
|
|
||||||
|
extern void ParseDtr(const char*, Hurricane::DtrAccess*);
|
||||||
|
|
||||||
|
|
||||||
|
BEGIN_NAMESPACE_HURRICANE
|
||||||
|
|
||||||
|
|
||||||
|
// ****************************************************************************************************
|
||||||
|
// DtrAccess implementation
|
||||||
|
// ****************************************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
// static data defintion
|
||||||
|
// *********************
|
||||||
|
DtrAccess* DtrAccess::_instance = NULL;
|
||||||
|
|
||||||
|
map<string, DtrAccess*> DtrAccess::_registry;
|
||||||
|
|
||||||
|
DtrAccess::DtrAccess()
|
||||||
|
// *******************
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DtrAccess * DtrAccess::Create()
|
||||||
|
// *****************************
|
||||||
|
{
|
||||||
|
DtrAccess * dtraccess = new DtrAccess();
|
||||||
|
|
||||||
|
dtraccess->_PostCreate();
|
||||||
|
|
||||||
|
return dtraccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DtrAccess::_PostCreate()
|
||||||
|
// **************************
|
||||||
|
{
|
||||||
|
const char * dtrfilename = getenv("DTR_FILE");
|
||||||
|
if(!dtrfilename) {
|
||||||
|
throw Error("Can't not get Macro DTR_FILE.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use API of DtrParser for get technology informations
|
||||||
|
// ****************************************************
|
||||||
|
ParseDtr(dtrfilename, this);
|
||||||
|
|
||||||
|
// Traduit Micro to RdsUnit
|
||||||
|
// ************************
|
||||||
|
map<string, list<double> >::iterator it_rulemap = _label2ruleMap.begin(),
|
||||||
|
it_end_rulemap = _label2ruleMap.end();
|
||||||
|
|
||||||
|
while(it_rulemap!=it_end_rulemap) {
|
||||||
|
|
||||||
|
list<double>::iterator m = ((*it_rulemap).second).begin()
|
||||||
|
, n = ((*it_rulemap).second).end();
|
||||||
|
|
||||||
|
while(m!=n) {
|
||||||
|
_label2RdsRuleMap[(*it_rulemap).first].push_back(ConvertRealToRdsUnit(*m));
|
||||||
|
m++;
|
||||||
|
}
|
||||||
|
it_rulemap++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get Objet Layer from Technology with its name.
|
||||||
|
// **********************************************
|
||||||
|
|
||||||
|
DataBase * db = GetDataBase();
|
||||||
|
|
||||||
|
if(!db) throw Error("In GetV1Trans::Generate : can't find DataBase.");
|
||||||
|
|
||||||
|
Technology * tech = db->GetTechnology();
|
||||||
|
|
||||||
|
map<string, list<string> >::iterator it_layermap = _label2layerNameMap.begin(),
|
||||||
|
it_end_layermap = _label2layerNameMap.end();
|
||||||
|
|
||||||
|
while(it_layermap != it_end_layermap) {
|
||||||
|
|
||||||
|
list<string>::iterator m = (*it_layermap).second.begin(),
|
||||||
|
n = (*it_layermap).second.end();
|
||||||
|
|
||||||
|
while(m!=n) {
|
||||||
|
Layer * layer = tech->GetLayer(Name(*m));
|
||||||
|
if(!layer) {
|
||||||
|
throw Error("Error : in function DtrAccess::_PostCreate , Can't find Layer "
|
||||||
|
+ GetString(*m) + " in technology file when parser DtrFile.");
|
||||||
|
// cerr << Warning("In function DtrAccess::_PostCreate , Can't find Layer "
|
||||||
|
// + GetString(*m) + " in technology file when parser DtrFile");
|
||||||
|
}
|
||||||
|
|
||||||
|
_label2layerMap[(*it_layermap).first].push_back(layer);
|
||||||
|
m++;
|
||||||
|
}
|
||||||
|
it_layermap++;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DtrAccess * DtrAccess::Instance()
|
||||||
|
// *****************************
|
||||||
|
{
|
||||||
|
// User or environnement supplies this at startup
|
||||||
|
// **********************************************
|
||||||
|
const char * singleton_name = getenv("DTRACCESS_SINGLETON");
|
||||||
|
|
||||||
|
if(!singleton_name) { // if MACRO IS INVALID
|
||||||
|
if(!_instance) {
|
||||||
|
_instance = DtrAccess::Create();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if(!_instance){
|
||||||
|
if( !(_instance=LookUp(string(singleton_name))) ) // if singleton hasn't been registered
|
||||||
|
_instance = DtrAccess::Create();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return _instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DtrAccess::_PreDelete()
|
||||||
|
// ***********************
|
||||||
|
{
|
||||||
|
// Do something
|
||||||
|
// ************
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DtrAccess::Delete()
|
||||||
|
// ********************
|
||||||
|
{
|
||||||
|
_PreDelete();
|
||||||
|
delete this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
GenericCollection<double> DtrAccess::GetRuleByLabel(const string& label) const
|
||||||
|
// ***************************************************************************
|
||||||
|
{
|
||||||
|
map<string, list<double> >::const_iterator i = _label2ruleMap.find(label);
|
||||||
|
|
||||||
|
if(i==_label2ruleMap.end())
|
||||||
|
throw Error("Can't find in DtrFile rule the label : " + GetString(label));
|
||||||
|
|
||||||
|
return GetCollection((*i).second);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
GenericCollection<long> DtrAccess::GetRdsRuleByLabel(const string& label) const
|
||||||
|
// ******************************************************************************
|
||||||
|
{
|
||||||
|
map<string, list<long> >::const_iterator i = _label2RdsRuleMap.find(label);
|
||||||
|
|
||||||
|
if(i==_label2RdsRuleMap.end())
|
||||||
|
throw Error("Can't find in DtrFile The Rds Value of Rule by label : " + GetString(label));
|
||||||
|
|
||||||
|
return GetCollection((*i).second);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
GenericCollection<string> DtrAccess::GetLayerNamesByLabel(const string& label) const
|
||||||
|
// *********************************************************************************
|
||||||
|
{
|
||||||
|
map<string, list<string> >::const_iterator i = _label2layerNameMap.find(label);
|
||||||
|
|
||||||
|
if(i==_label2layerNameMap.end())
|
||||||
|
throw Error("Can't find in DtrFile layers the label : " + label);
|
||||||
|
|
||||||
|
return GetCollection((*i).second);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
GenericCollection<Layer*> DtrAccess::GetLayersByLabel(const string& label) const
|
||||||
|
// ******************************************************************************
|
||||||
|
{
|
||||||
|
map<string, list<Layer*> >::const_iterator i = _label2layerMap.find(label);
|
||||||
|
|
||||||
|
if(i==_label2layerMap.end())
|
||||||
|
throw Error("Can't find in DtrFile objet Layer by label : " + label );
|
||||||
|
|
||||||
|
return GetCollection((*i).second);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
GenericCollection<double> DtrAccess::GetElectricalsByLabel(const string& label) const
|
||||||
|
// **********************************************************************************
|
||||||
|
{
|
||||||
|
map<string, list<double> >::const_iterator i = _label2electricalMap.find(label);
|
||||||
|
|
||||||
|
if(i==_label2electricalMap.end())
|
||||||
|
throw Error("Can't find in DtrFile electricals by label : " + label);
|
||||||
|
|
||||||
|
return GetCollection((*i).second);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int DtrAccess::GetModellingByLabel(const string& label) const
|
||||||
|
// **********************************************************
|
||||||
|
{
|
||||||
|
map<string, int>::const_iterator i = _label2modellingMap.find(label);
|
||||||
|
|
||||||
|
if(i==_label2modellingMap.end())
|
||||||
|
throw Error("Can't find in DtrFile modelling by label : " + GetString(label));
|
||||||
|
|
||||||
|
return (*i).second;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
double DtrAccess::GetSimpleCapaMimByLabel(const string& label) const
|
||||||
|
// ****************************************************************
|
||||||
|
{
|
||||||
|
map<string, double>::const_iterator i = _label2simplecapamimMap.find(label);
|
||||||
|
|
||||||
|
if(i==_label2simplecapamimMap.end())
|
||||||
|
throw Error("Can't find in DtrFile simple capa mim by label : " + GetString(label));
|
||||||
|
|
||||||
|
return (*i).second;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ------------------------------------------------------
|
||||||
|
// Function "DtrAccess::LookUp(const string&)".
|
||||||
|
//
|
||||||
|
|
||||||
|
/* \static DtrAccess* DtrAccess::LookUp(const string& singletonname)
|
||||||
|
* \param singletonname normally the name of derive class of DtrAccess.
|
||||||
|
* \return addresse of objet singleton of derive class if success.
|
||||||
|
* NULL if failure.
|
||||||
|
*
|
||||||
|
* Find the singleton objet if it exist according to the singletonname.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
DtrAccess* DtrAccess::LookUp(const string& singletonname)
|
||||||
|
// ******************************************************
|
||||||
|
{
|
||||||
|
map<string, DtrAccess*>::iterator i = _registry.find(singletonname);
|
||||||
|
|
||||||
|
if(i==_registry.end())
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return (*i).second;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// Function Register(const string&, DtrAccess*)
|
||||||
|
|
||||||
|
/* \void DtrAccess::Register(const string& singletonname, DtrAccess* dtraccess)
|
||||||
|
* \param singletonname the name of derive class.
|
||||||
|
* \param dtraccess addresse of objet singleton of derive class.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* This function is to be called when the singleton objet of derive class is
|
||||||
|
* created.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
void DtrAccess::Register(const string& singletonname, DtrAccess* dtraccess)
|
||||||
|
// *************************************************************************
|
||||||
|
{
|
||||||
|
_registry[singletonname]=dtraccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
string DtrAccess::_GetString() const
|
||||||
|
// **********************************
|
||||||
|
{
|
||||||
|
string s("Singleton DtrAccess");
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Record* DtrAccess::_GetRecord() const
|
||||||
|
// **********************************
|
||||||
|
{
|
||||||
|
Record* record = new Record(_GetString());
|
||||||
|
return record;
|
||||||
|
}
|
||||||
|
|
||||||
|
END_NAMESPACE_HURRICANE
|
||||||
|
|
||||||
|
// ****************************************************************************************************
|
||||||
|
// Generic functions
|
||||||
|
// ****************************************************************************************************
|
||||||
|
|
||||||
|
string GetString(const H::DtrAccess& access)
|
||||||
|
// **********************************************
|
||||||
|
{
|
||||||
|
return access._GetString();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,187 @@
|
||||||
|
// ****************************************************************************************************
|
||||||
|
// File: DtrAccess.h
|
||||||
|
// Authors: Wu YiFei
|
||||||
|
// Date : 21/12/2006
|
||||||
|
// ****************************************************************************************************
|
||||||
|
|
||||||
|
#ifndef HURRICANE_DTRACCESS
|
||||||
|
#define HURRICANE_DTRACCESS
|
||||||
|
|
||||||
|
#include "Layer.h"
|
||||||
|
#include "Layers.h"
|
||||||
|
|
||||||
|
//BEGIN_NAMESPACE_HURRICANE
|
||||||
|
|
||||||
|
|
||||||
|
namespace Hurricane {
|
||||||
|
|
||||||
|
class DtrAccess {
|
||||||
|
// **************
|
||||||
|
|
||||||
|
// Types
|
||||||
|
// *****
|
||||||
|
|
||||||
|
# if !defined(__DOXYGEN_PROCESSOR__)
|
||||||
|
// Attributes
|
||||||
|
// **********
|
||||||
|
private : static DtrAccess * _instance;
|
||||||
|
|
||||||
|
private : map<string, list<double> > _label2ruleMap;
|
||||||
|
private : map<string, list<string> > _label2layerNameMap;
|
||||||
|
private : map<string, list<double> > _label2electricalMap;
|
||||||
|
private : map<string, int> _label2modellingMap;
|
||||||
|
private : map<string, double> _label2simplecapamimMap;
|
||||||
|
|
||||||
|
private : map<string, list<long> > _label2RdsRuleMap;
|
||||||
|
private : map<string, list<Layer*> > _label2layerMap;
|
||||||
|
|
||||||
|
|
||||||
|
// For reusability of software
|
||||||
|
// ***************************
|
||||||
|
private : static map<string, DtrAccess*> _registry;
|
||||||
|
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
// ************
|
||||||
|
protected : DtrAccess();
|
||||||
|
private : DtrAccess(const DtrAccess&);
|
||||||
|
private : DtrAccess& operator=(const DtrAccess&);
|
||||||
|
|
||||||
|
protected : static DtrAccess * Create();
|
||||||
|
protected : virtual void _PostCreate();
|
||||||
|
# endif
|
||||||
|
|
||||||
|
public : static DtrAccess* Instance();
|
||||||
|
|
||||||
|
// Destructors
|
||||||
|
// ***********
|
||||||
|
# if !defined(__DOXYGEN_PROCESSOR__)
|
||||||
|
protected : virtual ~DtrAccess() {};
|
||||||
|
protected : virtual void _PreDelete();
|
||||||
|
# endif
|
||||||
|
|
||||||
|
|
||||||
|
public : virtual void Delete();
|
||||||
|
|
||||||
|
|
||||||
|
// Accessors
|
||||||
|
// *********
|
||||||
|
|
||||||
|
// If can't find data , throw Hurricane::Error
|
||||||
|
// *******************************************
|
||||||
|
public : GenericCollection<double> GetRuleByLabel(const string&) const;
|
||||||
|
public : GenericCollection<long> GetRdsRuleByLabel(const string&) const;
|
||||||
|
public : GenericCollection<string> GetLayerNamesByLabel(const string&) const;
|
||||||
|
public : Layers GetLayersByLabel(const string&) const;
|
||||||
|
public : GenericCollection<double> GetElectricalsByLabel(const string& ) const;
|
||||||
|
public : int GetModellingByLabel(const string&) const;
|
||||||
|
public : double GetSimpleCapaMimByLabel(const string&) const;
|
||||||
|
|
||||||
|
|
||||||
|
# if !defined(__DOXYGEN_PROCESSOR__)
|
||||||
|
public : double GetSingleRealRuleByLabel(const string& s) const
|
||||||
|
// *************************************************
|
||||||
|
{
|
||||||
|
GenericLocator<double> locator = GetRuleByLabel(s).GetLocator();
|
||||||
|
return locator.GetElement();
|
||||||
|
}
|
||||||
|
|
||||||
|
public : long GetSingleRdsRuleByLabel(const string& s) const
|
||||||
|
// ************************************************
|
||||||
|
{
|
||||||
|
GenericLocator<long> locator = GetRdsRuleByLabel(s).GetLocator();
|
||||||
|
return locator.GetElement();
|
||||||
|
}
|
||||||
|
|
||||||
|
public : string GetSingleLayerNameByLabel(const string& s) const
|
||||||
|
// ****************************************************
|
||||||
|
{
|
||||||
|
GenericLocator<string> locator = GetLayerNamesByLabel(s).GetLocator();
|
||||||
|
return locator.GetElement();
|
||||||
|
}
|
||||||
|
|
||||||
|
public : Layer* GetSingleLayerByLabel(const string& s) const
|
||||||
|
// ************************************************
|
||||||
|
{
|
||||||
|
LayerLocator locator = GetLayersByLabel(s).GetLocator();
|
||||||
|
return locator.GetElement();
|
||||||
|
}
|
||||||
|
|
||||||
|
public : double GetSingleRealRuleByLabel(char* prefix, const string& type, char* suffix) const
|
||||||
|
// **********************************************************************************
|
||||||
|
{
|
||||||
|
return GetSingleRealRuleByLabel(prefix + type + suffix);
|
||||||
|
}
|
||||||
|
|
||||||
|
public : long GetSingleRdsRuleByLabel(char* prefix, const string& type, char* suffix) const
|
||||||
|
// *******************************************************************************
|
||||||
|
{
|
||||||
|
return GetSingleRdsRuleByLabel(prefix + type + suffix);
|
||||||
|
}
|
||||||
|
|
||||||
|
public : string GetSingleLayerNameByLabel(char* prefix, const string& type, const string& suffix) const
|
||||||
|
// ************************************************************************************
|
||||||
|
{
|
||||||
|
return GetSingleLayerNameByLabel(prefix + type + suffix);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public : Layer* GetSingleLayerByLabel(char* prefix, const string& type, const string& suffix) const
|
||||||
|
// ***************************************************************************************
|
||||||
|
{
|
||||||
|
return GetSingleLayerByLabel(prefix + type + suffix);
|
||||||
|
}
|
||||||
|
|
||||||
|
# endif
|
||||||
|
|
||||||
|
// Updators
|
||||||
|
// ********
|
||||||
|
public : void AddRuleByLabel(const string& label, const list<double>& rule){ _label2ruleMap[label]=rule; };
|
||||||
|
public : void AddLayersByLabel(const string& label, const list<string>& layers) { _label2layerNameMap[label]=layers; };
|
||||||
|
public : void AddElectricalsByLabel(const string& label, const list<double>& electricals)
|
||||||
|
{ _label2electricalMap[label]=electricals; };
|
||||||
|
|
||||||
|
public : void AddModellingByLabel(const string& label, const int modelling) { _label2modellingMap[label]=modelling; };
|
||||||
|
public : void AddSimpleCapaMimByLabel(const string& label, const double capamim) { _label2simplecapamimMap[label]=capamim; };
|
||||||
|
|
||||||
|
// Operations
|
||||||
|
// **********
|
||||||
|
|
||||||
|
// For reusability of software
|
||||||
|
// ***************************
|
||||||
|
protected : static DtrAccess* LookUp(const string&);
|
||||||
|
protected : static void Register(const string& , DtrAccess* );
|
||||||
|
|
||||||
|
|
||||||
|
# if !defined(__DOXYGEN_PROCESSOR__)
|
||||||
|
// Others
|
||||||
|
// ******
|
||||||
|
public: virtual string _GetTypeName() const {return _TName("DtrAccess");};
|
||||||
|
public: virtual string _GetString() const;
|
||||||
|
public: virtual Record* _GetRecord() const;
|
||||||
|
|
||||||
|
public: map<string, list<double> >& _GetLabel2RuleMap() { return _label2ruleMap; };
|
||||||
|
public: map<string, list<string> >& _GetLabel2LayerNameMap() { return _label2layerNameMap; };
|
||||||
|
public: map<string, list<double> >& _GetLabel2ElectricalMap()
|
||||||
|
{ return _label2electricalMap; };
|
||||||
|
public: map<string, int>& _GetLabel2ModellingMap() { return _label2modellingMap; };
|
||||||
|
public: map<string, double>& _GetLabel2SimpleCapaMimMap()
|
||||||
|
{ return _label2simplecapamimMap; };
|
||||||
|
# endif
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//END_NAMESPACE_HURRICANE
|
||||||
|
|
||||||
|
|
||||||
|
// ****************************************************************************************************
|
||||||
|
// Generic functions
|
||||||
|
// ****************************************************************************************************
|
||||||
|
|
||||||
|
string GetString(const H::DtrAccess&);
|
||||||
|
|
||||||
|
|
||||||
|
#endif // HURRICANE_DTRACCESS
|
|
@ -0,0 +1,61 @@
|
||||||
|
// ****************************************************************************************************
|
||||||
|
// File: GenericDtrAccess.cpp
|
||||||
|
// Authors: Wu YiFei
|
||||||
|
// Date : 21/12/2006
|
||||||
|
// ****************************************************************************************************
|
||||||
|
|
||||||
|
#include "DtrAccess.h"
|
||||||
|
#include "GenericDtrAccess.h"
|
||||||
|
//#include "DtrAccess.h"
|
||||||
|
|
||||||
|
BEGIN_NAMESPACE_HURRICANE
|
||||||
|
|
||||||
|
|
||||||
|
// ****************************************************************************************************
|
||||||
|
// GenericDtrAccess implementation
|
||||||
|
// ****************************************************************************************************
|
||||||
|
|
||||||
|
GenericDtrAccess GenericDtrAccess::instance(NULL);
|
||||||
|
|
||||||
|
GenericDtrAccess::GenericDtrAccess(DtrAccess* dtraccess):_dtrAccess(dtraccess)
|
||||||
|
// **************************************************************************
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void GenericDtrAccess::Instance(DtrAccess* dtraccess)
|
||||||
|
// **************************************************
|
||||||
|
{
|
||||||
|
if(!(instance._dtrAccess))
|
||||||
|
instance._dtrAccess = dtraccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
GenericDtrAccess::~GenericDtrAccess()
|
||||||
|
// *********************************
|
||||||
|
{
|
||||||
|
if(_dtrAccess) { cout<<GetString(_dtrAccess)<<" is delete "<<endl; _dtrAccess->Delete();}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
string GenericDtrAccess::_GetString() const
|
||||||
|
// ****************************************
|
||||||
|
{
|
||||||
|
string s("Singleton GenericDtrAccess");
|
||||||
|
return s;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
END_NAMESPACE_HURRICANE
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ****************************************************************************************************
|
||||||
|
// Generic functions
|
||||||
|
// ****************************************************************************************************
|
||||||
|
|
||||||
|
string GetString(const H::GenericDtrAccess& access)
|
||||||
|
// ************************************************
|
||||||
|
{
|
||||||
|
return access._GetString();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,77 @@
|
||||||
|
// ****************************************************************************************************
|
||||||
|
// File: GenericDtrAccess.h
|
||||||
|
// Authors: Wu YiFei
|
||||||
|
// Date : 21/12/2006
|
||||||
|
// ****************************************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef HURRICANE_GENERICDTRACCESS
|
||||||
|
#define HURRICANE_GENERICDTRACCESS
|
||||||
|
|
||||||
|
|
||||||
|
//BEGIN_NAMESPACE_HURRICANE
|
||||||
|
|
||||||
|
namespace Hurricane {
|
||||||
|
|
||||||
|
class DtrAccess;
|
||||||
|
|
||||||
|
class GenericDtrAccess {
|
||||||
|
// *********************
|
||||||
|
|
||||||
|
// Types
|
||||||
|
// *****
|
||||||
|
|
||||||
|
# if !defined(__DOXYGEN_PROCESSOR__)
|
||||||
|
// Attributes
|
||||||
|
// **********
|
||||||
|
private : static GenericDtrAccess instance;
|
||||||
|
|
||||||
|
private : DtrAccess * _dtrAccess;
|
||||||
|
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
// ************
|
||||||
|
protected : GenericDtrAccess(DtrAccess*);
|
||||||
|
private : GenericDtrAccess(const GenericDtrAccess&);
|
||||||
|
private : GenericDtrAccess& operator=(const GenericDtrAccess&);
|
||||||
|
|
||||||
|
# endif
|
||||||
|
|
||||||
|
public : static void Instance(DtrAccess*);
|
||||||
|
|
||||||
|
// Destructors
|
||||||
|
// ***********
|
||||||
|
protected : virtual ~GenericDtrAccess();
|
||||||
|
|
||||||
|
// Accessors
|
||||||
|
// *********
|
||||||
|
|
||||||
|
|
||||||
|
// Updators
|
||||||
|
// ********
|
||||||
|
|
||||||
|
// Operations
|
||||||
|
// **********
|
||||||
|
|
||||||
|
# if !defined(__DOXYGEN_PROCESSOR__)
|
||||||
|
// Others
|
||||||
|
// ******
|
||||||
|
public: virtual string _GetTypeName() const {return _TName("GenericDtrAccess");};
|
||||||
|
public: virtual string _GetString() const;
|
||||||
|
# endif
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//END_NAMESPACE_HURRICANE
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// ****************************************************************************************************
|
||||||
|
// Generic functions
|
||||||
|
// ****************************************************************************************************
|
||||||
|
|
||||||
|
string GetString(const H::GenericDtrAccess&);
|
||||||
|
|
||||||
|
|
||||||
|
#endif // HURRICANE_GENERICDTRACCESS
|
|
@ -0,0 +1,72 @@
|
||||||
|
/* A Bison parser, made by GNU Bison 2.3. */
|
||||||
|
|
||||||
|
/* Skeleton interface for Bison's Yacc-like parsers in C
|
||||||
|
|
||||||
|
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
|
||||||
|
Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||||
|
Boston, MA 02110-1301, USA. */
|
||||||
|
|
||||||
|
/* As a special exception, you may create a larger work that contains
|
||||||
|
part or all of the Bison parser skeleton and distribute that work
|
||||||
|
under terms of your choice, so long as that work isn't itself a
|
||||||
|
parser generator using the skeleton or a modified version thereof
|
||||||
|
as a parser skeleton. Alternatively, if you modify or redistribute
|
||||||
|
the parser skeleton itself, you may (at your option) remove this
|
||||||
|
special exception, which will cause the skeleton and the resulting
|
||||||
|
Bison output files to be licensed under the GNU General Public
|
||||||
|
License without this special exception.
|
||||||
|
|
||||||
|
This special exception was added by the Free Software Foundation in
|
||||||
|
version 2.2 of Bison. */
|
||||||
|
|
||||||
|
/* Tokens. */
|
||||||
|
#ifndef YYTOKENTYPE
|
||||||
|
# define YYTOKENTYPE
|
||||||
|
/* Put the tokens into the symbol table, so that GDB and other debuggers
|
||||||
|
know about them. */
|
||||||
|
enum yytokentype {
|
||||||
|
T_TABLE = 258,
|
||||||
|
T_TABLE_END = 259,
|
||||||
|
T_DOUBLE = 260,
|
||||||
|
T_ID = 261
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
/* Tokens. */
|
||||||
|
#define T_TABLE 258
|
||||||
|
#define T_TABLE_END 259
|
||||||
|
#define T_DOUBLE 260
|
||||||
|
#define T_ID 261
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
|
||||||
|
typedef union YYSTYPE
|
||||||
|
#line 47 "/home/xtof/workspace/hurricane/src/analogic/ParserDtrGram.yy"
|
||||||
|
{ double _value;
|
||||||
|
char * _text;
|
||||||
|
}
|
||||||
|
/* Line 1489 of yacc.c. */
|
||||||
|
#line 65 "/home/xtof/workspace/hurricane/src/analogic/ParserDtrGram.hpp"
|
||||||
|
YYSTYPE;
|
||||||
|
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
|
||||||
|
# define YYSTYPE_IS_DECLARED 1
|
||||||
|
# define YYSTYPE_IS_TRIVIAL 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern YYSTYPE dtrlval;
|
||||||
|
|
|
@ -0,0 +1,202 @@
|
||||||
|
%{
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <map>
|
||||||
|
#include <list>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "Error.h"
|
||||||
|
#include "DtrAccess.h"
|
||||||
|
using namespace Hurricane;
|
||||||
|
|
||||||
|
#include "ParserDtrGram.hpp"
|
||||||
|
|
||||||
|
extern FILE * dtrin;
|
||||||
|
extern int dtrlex(void);
|
||||||
|
extern char * dtrtext;
|
||||||
|
extern int DTRlineno;
|
||||||
|
|
||||||
|
|
||||||
|
// *************************************************************************
|
||||||
|
// Static Function&Data
|
||||||
|
// *************************************************************************
|
||||||
|
|
||||||
|
static int dtrerror( char * message)
|
||||||
|
// *********************************
|
||||||
|
{
|
||||||
|
char * str = (char*)malloc(200*sizeof(char));
|
||||||
|
sprintf(str, "ParserDtr():\n %s before %s at line %d.\n", message, dtrtext, DTRlineno);
|
||||||
|
|
||||||
|
string errmsg = str;
|
||||||
|
|
||||||
|
throw Error (errmsg);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DtrAccess * dtraccess = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
static char* table_name = NULL;
|
||||||
|
|
||||||
|
static list<double> doubleList;
|
||||||
|
static list<string> stringList;
|
||||||
|
|
||||||
|
|
||||||
|
%}
|
||||||
|
|
||||||
|
%union { double _value;
|
||||||
|
char * _text;
|
||||||
|
};
|
||||||
|
|
||||||
|
%token T_TABLE T_TABLE_END T_DOUBLE T_ID
|
||||||
|
%type < _value > T_DOUBLE
|
||||||
|
%type < _text > T_ID
|
||||||
|
|
||||||
|
%start file
|
||||||
|
|
||||||
|
%%
|
||||||
|
|
||||||
|
file: lines tables
|
||||||
|
;
|
||||||
|
|
||||||
|
lines : '\n'
|
||||||
|
| lines '\n'
|
||||||
|
;
|
||||||
|
|
||||||
|
tables: table
|
||||||
|
|tables table
|
||||||
|
;
|
||||||
|
|
||||||
|
table: T_TABLE T_ID '\n'
|
||||||
|
{ table_name = $2; }
|
||||||
|
items T_TABLE_END lines
|
||||||
|
;
|
||||||
|
|
||||||
|
items: item
|
||||||
|
|items item
|
||||||
|
;
|
||||||
|
|
||||||
|
item: T_ID elems '\n'
|
||||||
|
{
|
||||||
|
|
||||||
|
string label = $1;
|
||||||
|
delete $1;
|
||||||
|
|
||||||
|
if( strcmp(table_name, "RULES")==0 ) {
|
||||||
|
if ( doubleList.empty() ) {
|
||||||
|
|
||||||
|
dtrerror("ParserDtr detect no data in a line of table RULES : Please check it");
|
||||||
|
}
|
||||||
|
|
||||||
|
list<double>::iterator i = doubleList.begin()
|
||||||
|
, j = doubleList.end();
|
||||||
|
|
||||||
|
while(i!=j) {
|
||||||
|
(dtraccess->_GetLabel2RuleMap())[label].push_back(*i);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if( strcmp(table_name, "LAYERS")==0 ) {
|
||||||
|
if ( stringList.empty() ) {
|
||||||
|
dtrerror("ParserDtr detect no data in a line of table LAYERS : Please check it");
|
||||||
|
}
|
||||||
|
|
||||||
|
list<string>::iterator i = stringList.begin()
|
||||||
|
, j = stringList.end();
|
||||||
|
|
||||||
|
while(i!=j) {
|
||||||
|
(dtraccess->_GetLabel2LayerNameMap())[label].push_back(*i);;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if( strcmp(table_name, "ELECTRICAL") == 0 ) {
|
||||||
|
if ( doubleList.empty() ) {
|
||||||
|
dtrerror("ParserDtr detect no data in a line of table ELECTRICAL : Please check it");
|
||||||
|
}
|
||||||
|
|
||||||
|
list<double>::iterator i = doubleList.begin()
|
||||||
|
, j = doubleList.end();
|
||||||
|
|
||||||
|
while(i!=j) {
|
||||||
|
(dtraccess->_GetLabel2ElectricalMap())[label].push_back(*i);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if( strcmp(table_name, "MODELLING") == 0 ) {
|
||||||
|
if ( (doubleList.empty()) || (doubleList.size()!=1) ) {
|
||||||
|
dtrerror("ParserDtr detect no data or mutli datas in a line of table MODELLING: Please check it");
|
||||||
|
}
|
||||||
|
|
||||||
|
list<double>::iterator i = doubleList.begin();
|
||||||
|
|
||||||
|
(dtraccess->_GetLabel2ModellingMap())[label] = (int)(*i);
|
||||||
|
}
|
||||||
|
|
||||||
|
else if( strcmp(table_name, "SIMPLE_CAPA_MIM")==0 ) {
|
||||||
|
if( (doubleList.empty()) || (doubleList.size()!=1) ) {
|
||||||
|
dtrerror("ParserDtr detect no data or mutli datas in a line of table SIMPLE_CAPA_MIM : Please check it");
|
||||||
|
}
|
||||||
|
|
||||||
|
list<double>::iterator i = doubleList.begin();
|
||||||
|
(dtraccess->_GetLabel2SimpleCapaMimMap())[label] = (*i);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
throw Error("ParserDtr detect unknown table name " + string(table_name));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Vide temporary list
|
||||||
|
// ********************
|
||||||
|
doubleList.clear();
|
||||||
|
stringList.clear();
|
||||||
|
|
||||||
|
}
|
||||||
|
| lines
|
||||||
|
;
|
||||||
|
|
||||||
|
elems: elem
|
||||||
|
|elems elem
|
||||||
|
;
|
||||||
|
|
||||||
|
elem: T_ID
|
||||||
|
{
|
||||||
|
if(!(doubleList.empty())) {
|
||||||
|
|
||||||
|
dtrerror("ParserDtr detect incompatibles datas : Please check it");
|
||||||
|
}
|
||||||
|
|
||||||
|
stringList.push_back(string($1));
|
||||||
|
delete $1;
|
||||||
|
}
|
||||||
|
| T_DOUBLE
|
||||||
|
{
|
||||||
|
if(!(stringList.empty())) {
|
||||||
|
|
||||||
|
dtrerror("ParserDtr detect incompatibles datas : Please check it");
|
||||||
|
}
|
||||||
|
|
||||||
|
doubleList.push_back($1);
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
%%
|
||||||
|
|
||||||
|
// *************************************************************************
|
||||||
|
// Generic Function
|
||||||
|
// *************************************************************************
|
||||||
|
|
||||||
|
void ParseDtr(const char* dtrfilename, DtrAccess* dtr)
|
||||||
|
// ***************************************************
|
||||||
|
{
|
||||||
|
dtraccess = dtr;
|
||||||
|
|
||||||
|
if((dtrin=fopen(dtrfilename, "r"))==NULL)
|
||||||
|
{
|
||||||
|
throw Error("Can't open dtr file : " + string(dtrfilename));
|
||||||
|
}
|
||||||
|
|
||||||
|
dtrparse();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
%{
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <vector>
|
||||||
|
#include <iostream>
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
#include "ParserDtrGram.hpp"
|
||||||
|
|
||||||
|
#define YY_NO_UNPUT
|
||||||
|
|
||||||
|
int DTRlineno = 1;
|
||||||
|
|
||||||
|
%}
|
||||||
|
%%
|
||||||
|
([ \t]+|#.*) {/* nothing to do */}
|
||||||
|
\n { DTRlineno++; return '\n'; }
|
||||||
|
TABLE_1DM { return T_TABLE;}
|
||||||
|
END_TABLE_1DM { return T_TABLE_END;}
|
||||||
|
[1-9]?[0-9]*(\.)?[0-9]+ { dtrlval._value=atof(dtrtext); return T_DOUBLE;}
|
||||||
|
[a-zA-Z0-9]+(_?[a-zA-Z0-9]+)* {dtrlval._text=strdup(dtrtext); return T_ID;}
|
||||||
|
. { return *dtrtext; }
|
||||||
|
|
||||||
|
%%
|
||||||
|
|
||||||
|
int dtrwrap() {return 1;}
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "DataBase.h"
|
||||||
|
#include "Library.h"
|
||||||
|
USING_NAMESPACE_HURRICANE
|
||||||
|
|
||||||
|
#include "TrMos.h"
|
||||||
|
using namespace DEVICE;
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
cout << "simple analogic test" << endl;
|
||||||
|
DataBase* db = DataBase::Create();
|
||||||
|
Library* rootLibrary = Library::Create(db, Name("RootLibrary"));
|
||||||
|
Library* workLibrary = Library::Create(rootLibrary, Name("WorkLibrary"));
|
||||||
|
TrMos* trmos = TrMos::Create(workLibrary, Name("MosTr"));
|
||||||
|
return 1;
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
INCLUDE_DIRECTORIES(${HURRICANE_INCLUDE_DIR}
|
||||||
|
${CHAMSIN_SOURCE_DIR}/src/analogic ${CHAMSIN_SOURCE_DIR}/src/device)
|
||||||
|
|
||||||
|
ADD_EXECUTABLE(atest AnalogicTest.cpp)
|
||||||
|
|
||||||
|
TARGET_LINK_LIBRARIES(atest analogic device ${HURRICANE_LIBRARIES})
|
Loading…
Reference in New Issue