coriolis/hurricane/src/analog/Device.cpp

182 lines
5.3 KiB
C++
Raw Normal View History

// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC 2009-2018, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | H u r r i c a n e A n a l o g |
// | |
// | Authors : Christophe Alexandre, Damien Dupuis |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Header : "./Device.cpp" |
// +-----------------------------------------------------------------+
#include <cfloat>
#include "hurricane/Warning.h"
#include "hurricane/DataBase.h"
#include "hurricane/Technology.h"
#include "hurricane/Pad.h"
#include "hurricane/Vertical.h"
#include "hurricane/Horizontal.h"
#include "hurricane/Library.h"
#include "hurricane/UpdateSession.h"
#include "hurricane/Reference.h"
#include "hurricane/analog/Device.h"
namespace {
using namespace Hurricane;
static Name anonymousNetName( "anonymous" );
} // anonymous namespace.
namespace Analog {
using namespace Hurricane;
Device::Device ( Library* library, const Name& name )
: Cell (library, name)
, _temperature (0.0)
, _parameterSet ()
, _layoutStyles (NULL)
, _subDevicesLibrary(NULL)
, _anonymous (NULL)
, _layouts ()
, _netRestrictions ()
{ }
void Device::preCreate ( const Name& deviceName )
{
Analog integration part II. Analog place & route (slicing tree). * Change: In Hurricane::CellWidget, set the minimal size to 350 pixels to fit my normal DPI secondary screen... * Change: In Hurricane::Error(), reactivate the backtrace generation by default. Seriously slow down the program each time an Error is to be constructed. * Bug: In Analog::Device::preCreate(), check for NULL Technology before attempting to use it. * Change: In Hurricane/Analog, remove all '*Arguments*' classes and their Python interface. It was an obsoleted way of passing devices parameters to the Python layout generators (located in Oroshi). Now we just get them straight from the Device with the getParamter() method. * Change: In CRL::System CTOR, add Python pathes for Oroshi & Karakaze. * Change: In Oroshi/Python/WIP_*.py layout generator scripts, remove all uses of the "Arguments". Directly access the parameters through the device itself. Make the checkCoherency() with identical arguments as of layout(). * New: Bora tool that performs analog place & route. Based on a slicing tree representation. It is the thesis work of Eric Lao. Code beautyfication and some programming cleanup. * New: Karakaze tool, provide the Python base class AnalogDesign used to build an analog design. Create/configure devices and assemble them in a slicing tree. * Change: In Unicorn/cgt.py, display the stack trace in case of an ImportError exception as well as for other exceptions. Add Bora to the set for included tool engines.
2018-10-18 11:10:01 -05:00
Technology* tech = DataBase::getDB()->getTechnology();
if (not tech)
throw Error( "Device::preCreate(): Technology database not initialied while called for \"%s\"."
, getString(deviceName).c_str() );
DeviceDescriptor* dd = tech->getDeviceDescriptor( deviceName );
if (not dd)
throw Error( "Device::preCreate(): No DeviceDescriptor for \"%s\"."
, getString(deviceName).c_str() );
}
void Device::_postCreate ( const Name& deviceName )
{
Super::_postCreate();
Clarify semantic of flatten Collections (walkthrough). In the Cell/Instance hierarchy, the "terminal" and "leaf cell" concepts where not clearly defined and partially overlapping. Now, "Terminal" is the refer to the physical hierarchy (layout) and "TerminalNetlist" to the logical hierarchy (netlist). The logical hierarchy can be less deep than the physical one thanks to a Cell dedicated cell flags. Collections related to the physical hierarchy keep their old names, the one related to the logical hierarchy are renamed from "Leaf" to "TerminalNetlist". The name "Leaf" was too ambiguous (leaf for *what* hierarchy). * Change: In Hurricane::Device, set the "TerminalNetlist" flag once and for all. No need set it in all the derived classes again. * New: In Hurricane::MultiCapacitor, added new parameter "dummy" to create dummies around the capacity matrix. * Change: In Hurricane::Cell, remove "Leaf" related methods, replace them by "TerminalNetlist" one, especially Collections. Now we have two clear sets of Collections to walkthough the layout or the netlist. Change the "Terminal" flag into "TerminalNetlist". * Change: In Hurricane::CellCollections, rename "Leaf" into "TerminalNetlist" collections and apply the new semantic to the locators. * Change: In Hurricane::DataBase, Leaf to TerminalInstance renaming. * Change: In Hurricane::DeepNet, Leaf to TerminalInstance renaming. * Change: In Hurricane::HyperNet, Leaf to TerminalInstance renaming. * Change: In Hurricane::Instance, Leaf to TerminalInstance renaming. * Change: In Hurricane::Viewer::HierarchyInformations, Leaf to TerminalInstance renaming. * Change: In CRL::AllianceFramework, Leaf to TerminalInstance renaming. * Change: In CRL::Catalog, Leaf to TerminalInstance renaming. * Change: In CRL::ApParser, Leaf to TerminalInstance renaming. * Change: In EtesianEngine::AddFeeds, Leaf to TerminalInstance renaming. * Bug: In EtesianEngine::resetPlacement, move there the loop over non terminal netlist instances to flag fully placed sub-blocks as terminal for the netlist. Only then remove the feed cells from unplaced instances. Previously, the feed cells where stripped even from already placed instances. * Change: In Katana, Leaf to TerminalInstance renaming. * Bug: In Bora::PyDSlicingNode, allow the range parameter to be the Python None object when we do not want to pass one but need to have it as positional parameter. * Change: In Cumulus/clocktree/ClockTree.py, Leaf to TerminalInstance renaming.
2020-03-10 06:10:53 -05:00
setTerminalNetlist( true );
_subDevicesLibrary = Library::create( getLibrary(), getName() );
_anonymous = Net::create( this, anonymousNetName );
_anonymous->setAutomatic( true );
Technology* tech = DataBase::getDB()->getTechnology();
DeviceDescriptor* dd = tech->getDeviceDescriptor( deviceName );
DeviceDescriptor::Layouts ddLayouts = dd->getLayouts();
for ( auto ddLayout : ddLayouts ) _layouts.insert( ddLayout );
Choices layouts;
for ( auto layout : _layouts ) layouts << getString(layout.first);
_layoutStyles = addChoiceParameter( "Layout Styles", layouts );
}
void Device::_preDestroy ()
{
for ( Parameter* parameter : _parameterSet ) delete parameter;
_subDevicesLibrary->destroy();
Super::_preDestroy();
}
First stage in analog capacitor integration * Bug: In Technology::getPhysicalRule(), if the named layerdo not exists, throw an exception instead of silently putting a NULL pointer inside a rule. * New: In Hurricane/Analog, new parameters classes for capacitor devices: - Analog::Matrix, a matrix of null or positives integers to encode capacitor matrix matching. - Analog::Capacities, a list of float values for all component of a multi-capacitor. * New: In Hurricane::Script, add a "getFileName()" method to get the full path name of the Python module. * Change: In Analog::LayoutGenerator, completly remove the logger utility as it is no longer used. Simply print error messages instead. * Change: In Analog::MetaCapacitor, rename top & bottom plate 'T' & 'B'. Accessors renamed in "getTopPlate()" & "getBottomPlate()". * New: In Analog::MultiCapacitor, complete rewrite. Makes use of the new parameters "capacities" and "matrix". Dynamically generates it's terminals as we do not know beforehand how many capacitors could be put in it. * Bug: In isobar/PyHurricane.h, in Type object definition, do not prepend a "Py" to class name (so the keep the C++ name). * Change: In CRL/etc/scn6m_deep_09/devices.py, add entry for the new capacitor generator. * New: In oroshi/python/ParamsMatrix, add a "family" entry in the [0,0] element to distinguish between transistor, capacitor and resistor. (this is the matrix of values returned to the LayoutGenerator after device generation). Now have one "setGlobalParams()" function per family. * New: In oroshi/python/Rules.py, added DTR rules needed by capacitors. Catch exceptions if something wrong append when we extract the rules from the technology. * New: In Bora, the devices are no longer *only* transistors, so the possibles configurations are no longer defined only by a number of fingers. We must be able to support any kind of range of configuration. So the explicit range of number of fingers is replaced by a base class ParameterRange, and it's derived classes: - Bora::StepParameterRange, to encode the possible number of fingers of a transistor (the former only possibility). - Bora::MatrixParameterRange, to encode all the possible matching scheme for a capacitor. As there is no way to compress it, this is a vector of Matrix (from Analog). * Change: In Bora::DSlicingNode::_place(), the ParameterRange has to be set on the right configuration (through the index) before being called. The generation parameters are taken from the active item in the ParameterRange. * Change: In Bora::NodeSets::create(), iterate over the ParameterRange to build all the configuration. Adjustement to the routing gauge pitchs are moved into the DBoxSet CTOR to save a lot of code. Semantic change: the index in the NodeSets is now the index in the associated ParameterRange and no longer the number of fingers of a transistor. Check that the ParameterRange dynamic class is consitent with the device family. * Change: In Bora::DBoxSet, same semantic change as for NodeSets, the number of finger become an index in ParameterRange. In DBoxSet::create(), now also perform the abutment box adjustement to the RoutingGauge, if possible. * New: In Karakaze/python/AnalogDesign.py, add support for Capacitor devices.
2019-11-07 10:05:49 -06:00
Parameter* Device::getParameter ( const string& parameterId ) const
{
for ( Parameter* parameter : _parameterSet) {
if (parameter->getName() == parameterId)
return parameter;
}
return NULL;
}
const string Device::getLayoutScript ()
{
Name layoutName = Name( _layoutStyles->getValue() );
Layouts::iterator findLayout = _layouts.find( layoutName );
if (findLayout != _layouts.end()) return (*findLayout).second;
return NULL;
}
void Device::destroyLayout ()
{
UpdateSession::open();
// size_t icomp = 0;
// for ( Component* component : getComponents() ) {
// cerr << setw(4) << icomp << " | " << component << endl;
// }
while ( not getComponents().isEmpty() ) getComponents().getFirst()->destroy();
while ( not getReferences().isEmpty() ) getReferences().getFirst()->destroy();
for ( Net* net : getNets() ) {
Rubbers rubbers = net->getRubbers();
while ( rubbers.getFirst() ) rubbers.getFirst()->_destroy();
}
UpdateSession::close();
}
unsigned int Device::getRestriction( Hurricane::Net* net ) const
{ return 0xAA; }
unsigned int Device::getRestrictions2 ( Hurricane::Net* net ) const
{
map<Net*,unsigned int>::const_iterator inet = _netRestrictions.find( net );
if (inet == _netRestrictions.end()) return AllBlocked;
return (*inet).second;
}
void Device::setRestrictions2 ( Hurricane::Net* net, unsigned int flags )
{
if (not net) return;
if (net->getCell() != this) {
cerr << Hurricane::Warning( "Device::setRestrictions2(): Net \"%s\" (of Device \"%s\")"
" do not belong to \"%s\"."
, getString(net->getName()).c_str()
, getString(net->getCell()->getName()).c_str()
, getString(getName()).c_str()
) << endl;
return;
}
_netRestrictions[ net ] = flags;
}
Hurricane::Record* Device::_getRecord () const
{
Record* record = Super::_getRecord();
if (record) {
record->add( getSlot("_subDevicesLibrary", _subDevicesLibrary) );
record->add( getSlot("_netRestrictions" , &_netRestrictions ) );
}
return record;
}
} // Analog namespace.