new Technology management : symetric and asymetric rules

new DTR file
Transistor Layout in progress
This commit is contained in:
Christophe Alexandre 2008-06-16 18:04:27 +00:00
parent 4deb80c3c7
commit 77d56ae638
8 changed files with 131 additions and 57 deletions

View File

@ -1,22 +1,23 @@
<technology name="hcmos9">
<physical_rules>
<rule name="minWidth" layer="cut0" value="0.16" ref="19-1"/>
<rule name="minExtension" layer1="poly" layer2="cut0" value="0.07" ref="19-3"/>
<arule name="minExtension" layer1="poly" layer2="cut0" value="0.07" ref="19-3"/>
<rule name="minExtension" layer1="nImplant" layer2="poly" value="0.2" ref="16-17"/>
<rule name="minExtension" layer1="nImplant" layer2="active" value="0.18" ref="16-8"/>
<arule name="minExtension" layer1="nImplant" layer2="poly" value="0.2" ref="16-17"/>
<arule name="minExtension" layer1="nImplant" layer2="active" value="0.18" ref="16-8"/>
<rule name="minExtension" layer1="pImplant" layer2="poly" value="0.2" ref="17-17"/>
<rule name="minExtension" layer1="pImplant" layer2="active" value="0.18" ref="17-8"/>
<arule name="minGateEnclosure" layer1="pImplant" layer2="poly" value="0.4" ref="17-6"/>
<arule name="minEnclosure" layer1="pImplant" layer2="poly" value="0.2" ref="17-17"/>
<arule name="minExtension" layer1="pImplant" layer2="active" value="0.18" ref="17-8"/>
<rule name="minExtension" layer1="active" layer2="cut0" value="0.07" ref="19-4.a"/>
<rule name="minExtension" layer1="pImplant" layer2="cut0" value="0.09" ref="19-4.b"/>
<rule name="minExtension" layer1="nImplant" layer2="cut0" value="0.09" ref="19-4.c"/>
<arule name="minExtension" layer1="active" layer2="cut0" value="0.07" ref="19-4.a"/>
<arule name="minExtension" layer1="pImplant" layer2="cut0" value="0.09" ref="19-4.b"/>
<arule name="minExtension" layer1="nImplant" layer2="cut0" value="0.09" ref="19-4.c"/>
<rule name="minSpacing" layer1="active" layer2="cut0" value="0.14" ref="19-5"/>
<rule name="minSpacing" layer1="active" layer2="poly" value="0.07" ref="13-5"/>
<rule name="minGateExtension" layer1="poly" layer2="active" value="0.18" ref="13-7"/>
<arule name="minExtension" layer1="poly" layer2="active" value="0.18" ref="13-7"/>
</physical_rules>

View File

@ -63,7 +63,7 @@ const Name Transistor::GridName("GRID");
const Name Transistor::BulkName("BULK");
const Name Transistor::AnonymousName("ANONYMOUS");
Transistor::Transistor(Library* library, const Name& name, const Polarity& polarity):
Transistor::Transistor(Library* library, const Name& name, const Polarity& polarity, DbU::Unit l, DbU::Unit w):
Cell(library, name),
_drain(NULL),
_source(NULL),
@ -72,8 +72,8 @@ Transistor::Transistor(Library* library, const Name& name, const Polarity& polar
_anonymous(NULL),
_polarity(polarity),
_abutmentType(),
_l(DbU::Min),
_w(DbU::Min),
_l(l),
_w(w),
_source20(NULL), _source22(NULL),
_drain40(NULL), _drain42(NULL),
_grid00(NULL), _grid01(NULL), _grid30(NULL), _grid31(NULL),
@ -81,8 +81,9 @@ Transistor::Transistor(Library* library, const Name& name, const Polarity& polar
{}
Transistor* Transistor::create(Library* library, const Name& name, const Polarity& polarity) {
Transistor* transistor = new Transistor(library, name, polarity);
Transistor* Transistor::create(Library* library, const Name& name, const Polarity& polarity,
DbU::Unit l, DbU::Unit w) {
Transistor* transistor = new Transistor(library, name, polarity, l, w);
transistor->_postCreate();
@ -118,6 +119,7 @@ void Transistor::_postCreate() {
_anonymous11 = createPad(technology, _anonymous, "pImplant");
_anonymous12 = createPad(technology, _anonymous, "pImplant");
}
setTerminal(false);
}
void Transistor::createLayout() {
@ -132,7 +134,7 @@ void Transistor::createLayout() {
ATechnology* atechno = AEnv::getATechnology();
DbU::Unit widthCut0 = atechno->getPhysicalRule("minWidth", getLayer(techno, "cut0"))->getValue();
DbU::Unit extGateActive = atechno->getPhysicalRule("minGateExtension",
DbU::Unit extGateActive = atechno->getPhysicalRule("minExtension",
getLayer(techno, "poly"), getLayer(techno, "active"))->getValue();
DbU::Unit extPolyCut0 = atechno->getPhysicalRule("minExtension",
getLayer(techno, "poly"), getLayer(techno, "cut0"))->getValue();
@ -140,18 +142,18 @@ void Transistor::createLayout() {
getLayer(techno, "active"), getLayer(techno, "cut0"))->getValue();
DbU::Unit spacingActivePoly = atechno->getPhysicalRule("minSpacing",
getLayer(techno, "active"), getLayer(techno, "poly"))->getValue();
DbU::Unit extImplantPoly = 0;
DbU::Unit enclosureImplantPoly = 0;
DbU::Unit extImplantActive = 0;
DbU::Unit extImplantCut0 = 0;
if (_polarity == N) {
extImplantPoly = atechno->getPhysicalRule("minExtension",
enclosureImplantPoly = atechno->getPhysicalRule("minEnclosure",
getLayer(techno, "nImplant"), getLayer(techno, "poly"))->getValue();
extImplantActive = atechno->getPhysicalRule("minExtension",
getLayer(techno, "nImplant"), getLayer(techno, "active"))->getValue();
extImplantCut0 = atechno->getPhysicalRule("minExtension",
getLayer(techno, "nImplant"), getLayer(techno, "cut0"))->getValue();
} else {
extImplantPoly = atechno->getPhysicalRule("minExtension",
enclosureImplantPoly = atechno->getPhysicalRule("minEnclosure",
getLayer(techno, "pImplant"), getLayer(techno, "poly"))->getValue();
extImplantActive = atechno->getPhysicalRule("minExtension",
getLayer(techno, "pImplant"), getLayer(techno, "active"))->getValue();
@ -160,6 +162,7 @@ void Transistor::createLayout() {
}
UpdateSession::open();
DbU::setStringMode(1);
//grid 00
DbU::Unit x00 = 0;
@ -168,6 +171,8 @@ void Transistor::createLayout() {
DbU::Unit dy00 = _w - y00*2;
Box box00(x00, y00, dx00, dy00);
_grid00->setBoundingBox(box00);
Contact* contact = Contact::create(_grid, getLayer(techno, "metal1"), box00.getXCenter(), box00.getYCenter(), box00.getWidth(), box00.getHeight());
Pad* pad = Pad::create(_grid, getLayer(techno, "metal1"), box00);
//grid30
DbU::Unit maxValue = widthCut0 + 2*extPolyCut0;
@ -207,14 +212,15 @@ void Transistor::createLayout() {
_grid01->setBoundingBox(box01);
//anonymous12
DbU::Unit x12 = min(x31, x00) - extImplantPoly;
DbU::Unit y12 = min(0 - extImplantActive, y00 - extImplantPoly);
DbU::Unit dx12 = max(dx31, dx00) + 2 * extImplantPoly;
DbU::Unit yMax = max( max(y30 + dy30 + extImplantCut0, max(y31 + dy31, y00 + dy00) + extImplantPoly), _w + extImplantActive);
DbU::Unit x12 = min(x31, x00) - enclosureImplantPoly;
DbU::Unit y12 = min(0 - extImplantActive, y00 - enclosureImplantPoly);
DbU::Unit dx12 = max(dx31, dx00) + 2 * enclosureImplantPoly;
DbU::Unit yMax = max( max(y30 + dy30 + extImplantCut0, max(y31 + dy31, y00 + dy00) + enclosureImplantPoly), _w + extImplantActive);
DbU::Unit dy12 = yMax - y12;
Box box12(x12, y12, dx12, dy12);
_anonymous12->setBoundingBox(box12);
//setAbutmentBox(getAbutmentBox());
UpdateSession::close();
}

View File

@ -17,7 +17,9 @@ class Transistor : public Cell {
enum Polarity {N=0, P=1};
enum AbutmentType { INTERNAL=0, LEFT=1, RIGHT=2, SINGLE=3};
static Transistor* create(Library* library, const Name& name, const Polarity& polarity);
static Transistor* create(Library* library, const Name& name,
const Polarity& polarity,
DbU::Unit l, DbU::Unit w);
void createLayout();
bool isNmos() const { return _polarity == N; };
@ -45,7 +47,9 @@ class Transistor : public Cell {
Pad *_grid00, *_grid01, *_grid30, *_grid31;
Pad *_anonymous10, *_anonymous11, *_anonymous12;
Transistor(Library* library, const Name& name, const Polarity& polarity);
Transistor(Library* library, const Name& name,
const Polarity& polarity,
DbU::Unit l, DbU::Unit w);
};
}

View File

@ -6,14 +6,27 @@ using namespace Hurricane;
namespace {
static Name ATechnologyPropertyName("ATechnologyProperty");
void printPhysicalRule(const ATechnology::PhysicalRule* physicalRule) {
cout << " - name = " << physicalRule->_name <<
", value = " << physicalRule->_value <<
", ref = " << physicalRule->_reference << endl;
}
void printPhysicalRules(const ATechnology::PhysicalRules& physicalRules) {
for (ATechnology::PhysicalRules::iterator prit = physicalRules.begin();
for (ATechnology::PhysicalRules::const_iterator prit = physicalRules.begin();
prit != physicalRules.end();
prit++) {
ATechnology::PhysicalRule* physicalRule = *prit;
cout << " - name = " << physicalRule->_name <<
", value = " << physicalRule->_value <<
", ref = " << physicalRule->_reference << endl;
printPhysicalRule(physicalRule);
}
}
void printPhysicalRules(const ATechnology::TwoLayersPhysicalRulesSet& physicalRules) {
for (ATechnology::TwoLayersPhysicalRulesSet::const_iterator prit = physicalRules.begin();
prit != physicalRules.end();
prit++) {
ATechnology::PhysicalRule* physicalRule = *prit;
printPhysicalRule(physicalRule);
}
}
@ -58,24 +71,25 @@ void ATechnology::addPhysicalRule(const Name& name, const Name& layerName, DbU::
}
void ATechnology::addPhysicalRule(const Name& name, const Name& layer1Name,
const Name& layer2Name, DbU::Unit value, const string& reference) {
const Name& layer2Name, bool symetric, DbU::Unit value,
const string& reference) {
Layer* layer1 = getLayer(layer1Name);
Layer* layer2 = getLayer(layer2Name);
LayerPair layerPair(layer1, layer2);
TwoLayersPhysicalRules::iterator tlprit = _twoLayersPhysicalRules.find(layerPair);
if (tlprit == _twoLayersPhysicalRules.end()) {
pair<TwoLayersPhysicalRules::iterator, bool> result =
_twoLayersPhysicalRules.insert(TwoLayersPhysicalRules::value_type(layerPair, PhysicalRules()));
_twoLayersPhysicalRules.insert(TwoLayersPhysicalRules::value_type(layerPair, TwoLayersPhysicalRulesSet()));
tlprit = result.first;
PhysicalRule* newPhysicalRule = new PhysicalRule(name, value, reference);
TwoLayersPhysicalRule* newPhysicalRule = new TwoLayersPhysicalRule(name, value, reference, symetric);
tlprit->second.insert(newPhysicalRule);
} else {
PhysicalRules& physicalRules = tlprit->second;
PhysicalRule searchPR(name, 0, "");
TwoLayersPhysicalRulesSet& physicalRules = tlprit->second;
TwoLayersPhysicalRule searchPR(name, 0, "", true);
if (physicalRules.find(&searchPR) != physicalRules.end()) {
throw Error("duplicate rule");
}
PhysicalRule* newPhysicalRule = new PhysicalRule(name, value, reference);
TwoLayersPhysicalRule* newPhysicalRule = new TwoLayersPhysicalRule(name, value, reference, symetric);
physicalRules.insert(newPhysicalRule);
}
}
@ -155,20 +169,31 @@ const ATechnology::PhysicalRule* ATechnology::getPhysicalRule(
const Layer* layer2) const {
LayerPair searchLayerPair(layer1, layer2);
TwoLayersPhysicalRules::const_iterator tlprit = _twoLayersPhysicalRules.find(searchLayerPair);
if (tlprit == _twoLayersPhysicalRules.end()) {
throw Error("Cannot find Physical Rules for layers " +
getString(layer1->getName()) +
" and " +
getString(layer2->getName()) +
" (searching Rule : " + getString(name) +")");
if (tlprit != _twoLayersPhysicalRules.end()) {
const TwoLayersPhysicalRulesSet& physicalRules = tlprit->second;
TwoLayersPhysicalRule searchPR(name, 0, "", true);
TwoLayersPhysicalRulesSet::const_iterator prit = physicalRules.find(&searchPR);
if (prit != physicalRules.end()) {
return *prit;
}
}
const PhysicalRules& physicalRules = tlprit->second;
PhysicalRule searchPR(name, 0, "");
PhysicalRules::iterator prit = physicalRules.find(&searchPR);
if (prit == physicalRules.end()) {
throw Error("Cannot find Physical Rule " + getString(name));
LayerPair reverseSearchLayerPair(layer2, layer1);
tlprit = _twoLayersPhysicalRules.find(reverseSearchLayerPair);
if (tlprit != _twoLayersPhysicalRules.end()) {
const TwoLayersPhysicalRulesSet& physicalRules = tlprit->second;
TwoLayersPhysicalRule searchPR(name, 0, "", true);
TwoLayersPhysicalRulesSet::const_iterator prit = physicalRules.find(&searchPR);
if (prit != physicalRules.end()) {
if ((*prit)->isSymetric()) {
return *prit;
}
}
}
return *prit;
throw Error("Cannot find Physical Rule " +
getString(name) + " for layers " +
getString(layer1->getName()) +
" and " +
getString(layer2->getName()));
}
Layer* ATechnology::getLayer(const Name& layerName) {

View File

@ -31,6 +31,19 @@ class ATechnology : public PrivateProperty {
double getValue() const { return _value; }
};
class TwoLayersPhysicalRule : public PhysicalRule {
public:
TwoLayersPhysicalRule(const Name& name,
DbU::Unit value,
const string& reference,
bool symetric):
PhysicalRule(name, value, reference),
_symetric(symetric) {}
bool isSymetric() const { return _symetric; }
const bool _symetric;
};
struct PhysicalRuleNameCompare:
public std::binary_function<const PhysicalRule*, const PhysicalRule*, bool> {
bool operator()(const PhysicalRule* pr1, const PhysicalRule* pr2) const {
@ -41,8 +54,9 @@ class ATechnology : public PrivateProperty {
typedef pair<const Layer*, const Layer*> LayerPair;
typedef set<ATechnology::PhysicalRule*, PhysicalRuleNameCompare> PhysicalRules;
typedef set<ATechnology::TwoLayersPhysicalRule*, PhysicalRuleNameCompare> TwoLayersPhysicalRulesSet;
typedef map<const Layer*, PhysicalRules> OneLayerPhysicalRules;
typedef map<LayerPair, PhysicalRules> TwoLayersPhysicalRules;
typedef map<LayerPair, TwoLayersPhysicalRulesSet> TwoLayersPhysicalRules;
static ATechnology* create(Hurricane::Technology* technology);
static ATechnology* getATechnology(Hurricane::Technology* technology);
@ -52,7 +66,7 @@ class ATechnology : public PrivateProperty {
void addPhysicalRule(const Name& name, DbU::Unit value, const string& reference);
void addPhysicalRule(const Name& name, const Name& layerName, DbU::Unit value, const string& reference);
void addPhysicalRule(const Name& name, const Name& layer1Name,
const Name& layer2Name, DbU::Unit value, const string& reference);
const Name& layer2Name, bool symetric, DbU::Unit value, const string& reference);
Layer* getLayer(const Name& layerName);
void print();

View File

@ -23,7 +23,22 @@ void readPhysicalRules(xmlNode* node, ATechnology* aTechnology) {
ruleNode;
ruleNode = ruleNode->next) {
if (ruleNode->type == XML_ELEMENT_NODE) {
if (xmlStrEqual(ruleNode->name, (xmlChar*)"rule")) {
if (xmlStrEqual(ruleNode->name, (xmlChar*)"arule")) {
xmlChar* ruleNameC = xmlGetProp(ruleNode, (xmlChar*)"name");
xmlChar* valueC = xmlGetProp(ruleNode, (xmlChar*)"value");
xmlChar* refC = xmlGetProp(ruleNode, (xmlChar*)"ref");
xmlChar* layer1C = xmlGetProp(ruleNode, (xmlChar*)"layer1");
xmlChar* layer2C = xmlGetProp(ruleNode, (xmlChar*)"layer2");
if (ruleNameC && valueC && refC && layer1C && layer2C) {
string ruleName((const char*)ruleNameC);
double value = atof((const char*)valueC);
DbU::Unit unitValue= DbU::real(value);
string reference((const char*)refC);
Name layer1Name((const char*)layer1C);
Name layer2Name((const char*)layer2C);
aTechnology->addPhysicalRule(ruleName, layer1Name, layer2Name, false, unitValue, reference);
}
} else if (xmlStrEqual(ruleNode->name, (xmlChar*)"rule")) {
xmlChar* ruleNameC = xmlGetProp(ruleNode, (xmlChar*)"name");
xmlChar* valueC = xmlGetProp(ruleNode, (xmlChar*)"value");
xmlChar* refC = xmlGetProp(ruleNode, (xmlChar*)"ref");
@ -41,7 +56,7 @@ void readPhysicalRules(xmlNode* node, ATechnology* aTechnology) {
} else if (layer1C && layer2C) {
Name layer1Name((const char*)layer1C);
Name layer2Name((const char*)layer2C);
aTechnology->addPhysicalRule(ruleName, layer1Name, layer2Name, unitValue, reference);
aTechnology->addPhysicalRule(ruleName, layer1Name, layer2Name, true, unitValue, reference);
} else {
aTechnology->addPhysicalRule(ruleName, unitValue, reference);
}

View File

@ -6,6 +6,8 @@
#include "hurricane/Error.h"
#include "hurricane/DataBase.h"
#include "hurricane/Library.h"
#include "hurricane/viewer/CellViewer.h"
using namespace Hurricane;
#include "AEnv.h"
@ -14,6 +16,7 @@ using namespace Hurricane;
int main(int argc, char* argv[]) {
int returnCode;
try {
QApplication* qa = new QApplication(argc, argv);
@ -33,10 +36,15 @@ int main(int argc, char* argv[]) {
exit(56);
}
aTechnology->print();
Transistor* trans = Transistor::create(userLibrary, Name("TEST"), Transistor::P);
Transistor* trans = Transistor::create(userLibrary, Name("TEST"), Transistor::P, 10, 10);
trans->createLayout();
cerr << trans << endl;
exit(0);
CellViewer* viewer = new CellViewer ( trans );
viewer->show();
returnCode = qa->exec();
delete viewer;
delete qa;
} catch (Hurricane::Warning& w) {
cerr << w.what() << endl;
} catch (Hurricane::Error& e) {
@ -46,4 +54,5 @@ int main(int argc, char* argv[]) {
cout << "Abnormal termination\n" << endl;
exit(2);
}
return returnCode;
}

View File

@ -1,11 +1,11 @@
include(${QT_USE_FILE})
include_directories(${HURRICANE_INCLUDE_DIR} ${CORIOLIS_INCLUDE_DIR}
${CHAMSIN_SOURCE_DIR}/src/technology
${CHAMSIN_SOURCE_DIR}/src/analogic ${CHAMSIN_SOURCE_DIR}/src/device)
include_directories(${HURRICANE_INCLUDE_DIR} ${HURRICANE_GRAPHICAL_INCLUDE_DIR}
${CORIOLIS_INCLUDE_DIR} ${CHAMSIN_SOURCE_DIR}/src/technology
${CHAMSIN_SOURCE_DIR}/src/analogic ${CHAMSIN_SOURCE_DIR}/src/device)
add_executable(atest AnalogicTest.cpp)
target_link_libraries(atest atechnology analogic ${HURRICANE_LIBRARIES} ${QT_LIBRARIES})
target_link_libraries(atest atechnology analogic ${HURRICANE_LIBRARIES} ${HURRICANE_GRAPHICAL_LIBRARIES} ${QT_LIBRARIES})
install(TARGETS atest DESTINATION /bin)