mirror of https://github.com/KLayout/klayout.git
WIP: combined devices and geometry/L2N DB representation. Yet to do: device cell transformation beyond vector?
This commit is contained in:
parent
9a361ee234
commit
db1e813635
|
|
@ -189,17 +189,15 @@ void Device::set_parameter_value (const std::string &name, double v)
|
||||||
|
|
||||||
void Device::add_others_terminals (unsigned int this_terminal, db::Device *other, unsigned int other_terminal)
|
void Device::add_others_terminals (unsigned int this_terminal, db::Device *other, unsigned int other_terminal)
|
||||||
{
|
{
|
||||||
|
std::vector<OtherTerminalRef> &terminals = m_reconnected_terminals [this_terminal];
|
||||||
|
|
||||||
std::map<unsigned int, std::vector<OtherTerminalRef> >::const_iterator ot = other->m_reconnected_terminals.find (other_terminal);
|
std::map<unsigned int, std::vector<OtherTerminalRef> >::const_iterator ot = other->m_reconnected_terminals.find (other_terminal);
|
||||||
if (ot == other->m_reconnected_terminals.end ()) {
|
if (ot == other->m_reconnected_terminals.end ()) {
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (other->m_reconnected_terminals.empty ()) {
|
terminals.push_back (OtherTerminalRef (other->device_abstract (), other->position () - position (), other_terminal));
|
||||||
m_reconnected_terminals.insert (std::make_pair (this_terminal, ot->second));
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
std::vector<OtherTerminalRef> &terminals = m_reconnected_terminals [this_terminal];
|
|
||||||
|
|
||||||
size_t n = terminals.size ();
|
size_t n = terminals.size ();
|
||||||
terminals.insert (terminals.end (), ot->second.begin (), ot->second.end ());
|
terminals.insert (terminals.end (), ot->second.begin (), ot->second.end ());
|
||||||
|
|
||||||
|
|
@ -212,10 +210,22 @@ void Device::add_others_terminals (unsigned int this_terminal, db::Device *other
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Device::init_terminal_routes ()
|
||||||
|
{
|
||||||
|
if (! device_class ()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t n = device_class ()->terminal_definitions ().size ();
|
||||||
|
for (size_t i = 0; i < n; ++i) {
|
||||||
|
m_reconnected_terminals [i].push_back (OtherTerminalRef (device_abstract (), db::DVector (), i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Device::join_terminals (unsigned int this_terminal, db::Device *other, unsigned int other_terminal)
|
void Device::join_terminals (unsigned int this_terminal, db::Device *other, unsigned int other_terminal)
|
||||||
{
|
{
|
||||||
if (m_reconnected_terminals.empty ()) {
|
if (m_reconnected_terminals.empty ()) {
|
||||||
m_reconnected_terminals [this_terminal].push_back (OtherTerminalRef (device_abstract (), db::DVector (), this_terminal));
|
init_terminal_routes ();
|
||||||
}
|
}
|
||||||
|
|
||||||
other->connect_terminal (other_terminal, 0);
|
other->connect_terminal (other_terminal, 0);
|
||||||
|
|
@ -227,6 +237,10 @@ void Device::reroute_terminal (unsigned int this_terminal, db::Device *other, un
|
||||||
{
|
{
|
||||||
// TODO: the internal connection is not represented currently ...
|
// TODO: the internal connection is not represented currently ...
|
||||||
|
|
||||||
|
if (m_reconnected_terminals.empty ()) {
|
||||||
|
init_terminal_routes ();
|
||||||
|
}
|
||||||
|
|
||||||
if (! m_reconnected_terminals.empty ()) {
|
if (! m_reconnected_terminals.empty ()) {
|
||||||
m_reconnected_terminals.erase (this_terminal);
|
m_reconnected_terminals.erase (this_terminal);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -280,6 +280,14 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets the map of reconnected terminals
|
||||||
|
*/
|
||||||
|
const std::map<unsigned int, std::vector<OtherTerminalRef> > &reconnected_terminals () const
|
||||||
|
{
|
||||||
|
return m_reconnected_terminals;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Gets the set of other device abstracts
|
* @brief Gets the set of other device abstracts
|
||||||
*
|
*
|
||||||
|
|
@ -291,6 +299,26 @@ public:
|
||||||
return m_other_abstracts;
|
return m_other_abstracts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets the map of reconnected terminals (non-const version)
|
||||||
|
*
|
||||||
|
* NOTE: don't use this method to modify this container! It's provided for persistence implementation only.
|
||||||
|
*/
|
||||||
|
std::map<unsigned int, std::vector<OtherTerminalRef> > &reconnected_terminals ()
|
||||||
|
{
|
||||||
|
return m_reconnected_terminals;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets the set of other device abstracts (non-const version)
|
||||||
|
*
|
||||||
|
* NOTE: don't use this method to modify this container! It's provided for persistence implementation only.
|
||||||
|
*/
|
||||||
|
std::vector<std::pair<const db::DeviceAbstract *, db::DVector> > &other_abstracts ()
|
||||||
|
{
|
||||||
|
return m_other_abstracts;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class Circuit;
|
friend class Circuit;
|
||||||
friend class Net;
|
friend class Net;
|
||||||
|
|
@ -335,6 +363,7 @@ private:
|
||||||
void set_circuit (Circuit *circuit);
|
void set_circuit (Circuit *circuit);
|
||||||
|
|
||||||
void add_others_terminals (unsigned int this_terminal, db::Device *other, unsigned int other_terminal);
|
void add_others_terminals (unsigned int this_terminal, db::Device *other, unsigned int other_terminal);
|
||||||
|
void init_terminal_routes ();
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -69,11 +69,26 @@ namespace db
|
||||||
* A net declaration shall be there also if no geometry
|
* A net declaration shall be there also if no geometry
|
||||||
* is present. The ID is a numerical shortcut for the net.
|
* is present. The ID is a numerical shortcut for the net.
|
||||||
* pin(<name> <net-id>) - outgoing pin connection [short key: P]
|
* pin(<name> <net-id>) - outgoing pin connection [short key: P]
|
||||||
* device(<name> <abstract> [device-def])
|
* device(<name> <abstract> [combined-device]* [terminal-route]* [device-def])
|
||||||
* - device with connections [short key: D]
|
* - device with connections [short key: D]
|
||||||
* circuit(<name> [circuit-def]) - subcircuit with connections [short key: X]
|
* circuit(<name> [circuit-def]) - subcircuit with connections [short key: X]
|
||||||
*
|
*
|
||||||
|
* [combined-device]:
|
||||||
|
*
|
||||||
|
* device(<abstract> <dx> <dy>) - specifies an additional device component
|
||||||
|
* (for combined devices) with abstract <abstract>
|
||||||
|
* and offset dx, dy.
|
||||||
|
*
|
||||||
|
* [terminal-route]:
|
||||||
|
*
|
||||||
|
* connect(<device-index> <outer-terminal-name> <inner-terminal-name>)
|
||||||
|
* - connects the outer terminal with the terminal
|
||||||
|
* of the device component with <device-index>:
|
||||||
|
* 0 is the basic device, 1 the first combined
|
||||||
|
* device etc.
|
||||||
|
*
|
||||||
* [net-name]:
|
* [net-name]:
|
||||||
|
*
|
||||||
* name(<net-name>) - specify net name [short key: I]
|
* name(<net-name>) - specify net name [short key: I]
|
||||||
*
|
*
|
||||||
* [geometry-def]:
|
* [geometry-def]:
|
||||||
|
|
@ -82,7 +97,9 @@ namespace db
|
||||||
* "*" for <x> or <y> means take previous
|
* "*" for <x> or <y> means take previous
|
||||||
* rect(<layer> [coord] [coord]) - defines a rectangle [short key: R]
|
* rect(<layer> [coord] [coord]) - defines a rectangle [short key: R]
|
||||||
* coordinates are bottom/left and top/right
|
* coordinates are bottom/left and top/right
|
||||||
|
*
|
||||||
* [coord]
|
* [coord]
|
||||||
|
*
|
||||||
* <x> <y> - absolute coordinates
|
* <x> <y> - absolute coordinates
|
||||||
* (<x> <y>) - relative coordinates (reference is reset to 0,0
|
* (<x> <y>) - relative coordinates (reference is reset to 0,0
|
||||||
* for each net or terminal in device abstract)
|
* for each net or terminal in device abstract)
|
||||||
|
|
|
||||||
|
|
@ -309,7 +309,7 @@ void LayoutToNetlistStandardReader::do_read (db::LayoutToNetlist *l2n)
|
||||||
std::map<db::CellInstArray, std::list<Connections> >::const_iterator c = connections.find (i->cell_inst ());
|
std::map<db::CellInstArray, std::list<Connections> >::const_iterator c = connections.find (i->cell_inst ());
|
||||||
if (c != connections.end ()) {
|
if (c != connections.end ()) {
|
||||||
for (std::list<Connections>::const_iterator j = c->second.begin (); j != c->second.end (); ++j) {
|
for (std::list<Connections>::const_iterator j = c->second.begin (); j != c->second.end (); ++j) {
|
||||||
l2n->net_clusters ().clusters_per_cell (ci).add_connection (j->from_cluster, db::ClusterInstance (j->to_cluster, i->cell_index (), i->complex_trans (), i->prop_id ()));
|
l2n->net_clusters ().clusters_per_cell (ci).add_connection (j->from_cluster, db::ClusterInstance (j->to_cluster, i->cell_index (), i->complex_trans () * db::ICplxTrans (j->offset), i->prop_id ()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -486,6 +486,31 @@ LayoutToNetlistStandardReader::read_pin (db::LayoutToNetlist * /*l2n*/, db::Circ
|
||||||
circuit->connect_pin (pin.id (), net);
|
circuit->connect_pin (pin.id (), net);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static size_t
|
||||||
|
terminal_id (const db::DeviceClass *device_class, const std::string &tname)
|
||||||
|
{
|
||||||
|
const std::vector<db::DeviceTerminalDefinition> &td = device_class->terminal_definitions ();
|
||||||
|
for (std::vector<db::DeviceTerminalDefinition>::const_iterator t = td.begin (); t != td.end (); ++t) {
|
||||||
|
if (t->name () == tname) {
|
||||||
|
return t->id ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw tl::Exception (tl::to_string (tr ("Not a valid terminal name: ")) + tname + tl::to_string (tr (" for device class: ")) + device_class->name ());
|
||||||
|
}
|
||||||
|
|
||||||
|
static db::DeviceAbstract *
|
||||||
|
device_model_by_name (db::Netlist *netlist, const std::string &dmname)
|
||||||
|
{
|
||||||
|
for (db::Netlist::device_abstract_iterator i = netlist->begin_device_abstracts (); i != netlist->end_device_abstracts (); ++i) {
|
||||||
|
if (i->name () == dmname) {
|
||||||
|
return i.operator-> ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw tl::Exception (tl::to_string (tr ("Not a valid device abstract name: ")) + dmname);
|
||||||
|
}
|
||||||
|
|
||||||
db::CellInstArray
|
db::CellInstArray
|
||||||
LayoutToNetlistStandardReader::read_device (db::LayoutToNetlist *l2n, db::Circuit *circuit, std::list<Connections> &refs, std::map<unsigned int, Net *> &id2net)
|
LayoutToNetlistStandardReader::read_device (db::LayoutToNetlist *l2n, db::Circuit *circuit, std::list<Connections> &refs, std::map<unsigned int, Net *> &id2net)
|
||||||
{
|
{
|
||||||
|
|
@ -497,16 +522,7 @@ LayoutToNetlistStandardReader::read_device (db::LayoutToNetlist *l2n, db::Circui
|
||||||
std::string dmname;
|
std::string dmname;
|
||||||
read_word_or_quoted (dmname);
|
read_word_or_quoted (dmname);
|
||||||
|
|
||||||
db::DeviceAbstract *dm = 0;
|
db::DeviceAbstract *dm = device_model_by_name (l2n->netlist (), dmname);
|
||||||
for (db::Netlist::device_abstract_iterator i = l2n->netlist ()->begin_device_abstracts (); i != l2n->netlist ()->end_device_abstracts (); ++i) {
|
|
||||||
if (i->name () == dmname) {
|
|
||||||
dm = i.operator-> ();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (! dm) {
|
|
||||||
throw tl::Exception (tl::to_string (tr ("Not a valid device abstract name: ")) + dmname);
|
|
||||||
}
|
|
||||||
|
|
||||||
db::Device *device = new db::Device ();
|
db::Device *device = new db::Device ();
|
||||||
device->set_device_class (const_cast<db::DeviceClass *> (dm->device_class ()));
|
device->set_device_class (const_cast<db::DeviceClass *> (dm->device_class ()));
|
||||||
|
|
@ -515,6 +531,8 @@ LayoutToNetlistStandardReader::read_device (db::LayoutToNetlist *l2n, db::Circui
|
||||||
circuit->add_device (device);
|
circuit->add_device (device);
|
||||||
|
|
||||||
db::Coord x = 0, y = 0;
|
db::Coord x = 0, y = 0;
|
||||||
|
double dbu = l2n->internal_layout ()->dbu ();
|
||||||
|
db::VCplxTrans dbu_inv (1.0 / dbu);
|
||||||
|
|
||||||
while (br) {
|
while (br) {
|
||||||
|
|
||||||
|
|
@ -525,6 +543,44 @@ LayoutToNetlistStandardReader::read_device (db::LayoutToNetlist *l2n, db::Circui
|
||||||
y = read_coord ();
|
y = read_coord ();
|
||||||
br2.done ();
|
br2.done ();
|
||||||
|
|
||||||
|
} else if (test (skeys::device_key) || test (lkeys::device_key)) {
|
||||||
|
|
||||||
|
std::string n;
|
||||||
|
|
||||||
|
Brace br2 (this);
|
||||||
|
|
||||||
|
read_word_or_quoted (n);
|
||||||
|
|
||||||
|
db::Coord dx = read_coord ();
|
||||||
|
db::Coord dy = read_coord ();
|
||||||
|
|
||||||
|
br2.done ();
|
||||||
|
|
||||||
|
device->other_abstracts ().push_back (std::make_pair (device_model_by_name (l2n->netlist (), n), db::DVector (dbu * dx, dbu * dy)));
|
||||||
|
|
||||||
|
} else if (test (skeys::connect_key) || test (lkeys::connect_key)) {
|
||||||
|
|
||||||
|
Brace br2 (this);
|
||||||
|
|
||||||
|
int device_comp_index = read_int ();
|
||||||
|
|
||||||
|
std::string touter, tinner;
|
||||||
|
read_word_or_quoted (touter);
|
||||||
|
read_word_or_quoted (tinner);
|
||||||
|
|
||||||
|
br2.done ();
|
||||||
|
|
||||||
|
if (device_comp_index < 0 || device_comp_index > int (device->other_abstracts ().size ())) {
|
||||||
|
throw tl::Exception (tl::to_string (tr ("Not a valid device component index: ")) + tl::to_string (device_comp_index));
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t touter_id = terminal_id (dm->device_class (), touter);
|
||||||
|
size_t tinner_id = terminal_id (dm->device_class (), tinner);
|
||||||
|
|
||||||
|
const db::DeviceAbstract *da = device_comp_index > 0 ? device->other_abstracts () [device_comp_index - 1].first : dm;
|
||||||
|
db::DVector da_offset = device_comp_index > 0 ? device->other_abstracts () [device_comp_index - 1].second : db::DVector ();
|
||||||
|
device->reconnected_terminals () [touter_id].push_back (db::Device::OtherTerminalRef (da, da_offset, tinner_id));
|
||||||
|
|
||||||
} else if (test (skeys::terminal_key) || test (lkeys::terminal_key)) {
|
} else if (test (skeys::terminal_key) || test (lkeys::terminal_key)) {
|
||||||
|
|
||||||
Brace br2 (this);
|
Brace br2 (this);
|
||||||
|
|
@ -533,18 +589,7 @@ LayoutToNetlistStandardReader::read_device (db::LayoutToNetlist *l2n, db::Circui
|
||||||
unsigned int netid = (unsigned int) read_int ();
|
unsigned int netid = (unsigned int) read_int ();
|
||||||
br2.done ();
|
br2.done ();
|
||||||
|
|
||||||
size_t tid = std::numeric_limits<size_t>::max ();
|
size_t tid = terminal_id (dm->device_class (), tname);
|
||||||
const std::vector<db::DeviceTerminalDefinition> &td = dm->device_class ()->terminal_definitions ();
|
|
||||||
for (std::vector<db::DeviceTerminalDefinition>::const_iterator t = td.begin (); t != td.end (); ++t) {
|
|
||||||
if (t->name () == tname) {
|
|
||||||
tid = t->id ();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tid == std::numeric_limits<size_t>::max ()) {
|
|
||||||
throw tl::Exception (tl::to_string (tr ("Not a valid terminal name: ")) + tname + tl::to_string (tr (" for device class: ")) + dm->device_class ()->name ());
|
|
||||||
}
|
|
||||||
|
|
||||||
db::Net *net = id2net [netid];
|
db::Net *net = id2net [netid];
|
||||||
if (!net) {
|
if (!net) {
|
||||||
|
|
@ -552,7 +597,15 @@ LayoutToNetlistStandardReader::read_device (db::LayoutToNetlist *l2n, db::Circui
|
||||||
}
|
}
|
||||||
|
|
||||||
device->connect_terminal (tid, net);
|
device->connect_terminal (tid, net);
|
||||||
refs.push_back (Connections (net->cluster_id (), dm->cluster_id_for_terminal (tid)));
|
|
||||||
|
const std::vector<db::Device::OtherTerminalRef> *tr = device->reconnected_terminals_for (tid);
|
||||||
|
if (tr) {
|
||||||
|
for (std::vector<db::Device::OtherTerminalRef>::const_iterator i = tr->begin (); i != tr->end (); ++i) {
|
||||||
|
refs.push_back (Connections (net->cluster_id (), i->device_abstract->cluster_id_for_terminal (i->other_terminal_id), dbu_inv * i->offset));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
refs.push_back (Connections (net->cluster_id (), dm->cluster_id_for_terminal (tid), db::Vector ()));
|
||||||
|
}
|
||||||
|
|
||||||
} else if (test (skeys::param_key) || test (lkeys::param_key)) {
|
} else if (test (skeys::param_key) || test (lkeys::param_key)) {
|
||||||
|
|
||||||
|
|
@ -586,16 +639,24 @@ LayoutToNetlistStandardReader::read_device (db::LayoutToNetlist *l2n, db::Circui
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
double dbu = l2n->internal_layout ()->dbu ();
|
|
||||||
device->set_position (db::DPoint (dbu * x, dbu * y));
|
device->set_position (db::DPoint (dbu * x, dbu * y));
|
||||||
|
|
||||||
br.done ();
|
br.done ();
|
||||||
|
|
||||||
// make device cell instance
|
|
||||||
db::CellInstArray inst (db::CellInst (dm->cell_index ()), db::Trans (db::Vector (x, y)));
|
|
||||||
db::Cell &ccell = l2n->internal_layout ()->cell (circuit->cell_index ());
|
db::Cell &ccell = l2n->internal_layout ()->cell (circuit->cell_index ());
|
||||||
|
|
||||||
|
// make device cell instances
|
||||||
|
db::CellInstArray inst (db::CellInst (dm->cell_index ()), db::Trans (db::Vector (x, y)));
|
||||||
ccell.insert (inst);
|
ccell.insert (inst);
|
||||||
|
|
||||||
|
const std::vector<std::pair<const db::DeviceAbstract *, db::DVector> > &other_devices = device->other_abstracts ();
|
||||||
|
for (std::vector<std::pair<const db::DeviceAbstract *, db::DVector> >::const_iterator i = other_devices.begin (); i != other_devices.end (); ++i) {
|
||||||
|
|
||||||
|
db::CellInstArray other_inst (db::CellInst (i->first->cell_index ()), db::Trans (db::Vector (x, y) + dbu_inv * i->second));
|
||||||
|
ccell.insert (other_inst);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
return inst;
|
return inst;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -688,7 +749,7 @@ LayoutToNetlistStandardReader::read_subcircuit (db::LayoutToNetlist *l2n, db::Ci
|
||||||
subcircuit->connect_pin (sc_pin->id (), net);
|
subcircuit->connect_pin (sc_pin->id (), net);
|
||||||
db::Net *sc_net = circuit_ref->net_for_pin (sc_pin->id ());
|
db::Net *sc_net = circuit_ref->net_for_pin (sc_pin->id ());
|
||||||
if (sc_net) {
|
if (sc_net) {
|
||||||
refs.push_back (Connections (net->cluster_id (), sc_net->cluster_id ()));
|
refs.push_back (Connections (net->cluster_id (), sc_net->cluster_id (), db::Vector ()));
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -74,11 +74,12 @@ private:
|
||||||
|
|
||||||
struct Connections
|
struct Connections
|
||||||
{
|
{
|
||||||
Connections (size_t _from_cluster, size_t _to_cluster)
|
Connections (size_t _from_cluster, size_t _to_cluster, const db::Vector &_offset)
|
||||||
: from_cluster (_from_cluster), to_cluster (_to_cluster)
|
: from_cluster (_from_cluster), to_cluster (_to_cluster), offset (_offset)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
size_t from_cluster, to_cluster;
|
size_t from_cluster, to_cluster;
|
||||||
|
db::Vector offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
tl::TextInputStream m_stream;
|
tl::TextInputStream m_stream;
|
||||||
|
|
|
||||||
|
|
@ -489,20 +489,53 @@ void std_writer_impl<Keys>::write (const db::LayoutToNetlist *l2n, const db::Dev
|
||||||
{
|
{
|
||||||
const db::Layout *ly = l2n->internal_layout ();
|
const db::Layout *ly = l2n->internal_layout ();
|
||||||
double dbu = ly->dbu ();
|
double dbu = ly->dbu ();
|
||||||
|
db::VCplxTrans dbu_inv (1.0 / dbu);
|
||||||
|
|
||||||
|
tl_assert (device.device_class () != 0);
|
||||||
|
const std::vector<DeviceTerminalDefinition> &td = device.device_class ()->terminal_definitions ();
|
||||||
|
const std::vector<DeviceParameterDefinition> &pd = device.device_class ()->parameter_definitions ();
|
||||||
|
|
||||||
*mp_stream << indent1 << Keys::device_key << "(" << tl::to_word_or_quoted_string (device.expanded_name ());
|
*mp_stream << indent1 << Keys::device_key << "(" << tl::to_word_or_quoted_string (device.expanded_name ());
|
||||||
|
|
||||||
tl_assert (device.device_abstract () != 0);
|
tl_assert (device.device_abstract () != 0);
|
||||||
*mp_stream << " " << tl::to_word_or_quoted_string (device.device_abstract ()->name ()) << endl;
|
*mp_stream << " " << tl::to_word_or_quoted_string (device.device_abstract ()->name ()) << endl;
|
||||||
|
|
||||||
*mp_stream << indent2 << Keys::location_key << "(" << device.position ().x () / dbu << " " << device.position ().y () / dbu << ")" << endl;
|
std::map<std::pair<const db::DeviceAbstract *, db::Vector>, size_t> abstracts;
|
||||||
|
abstracts.insert (std::make_pair (std::make_pair (device.device_abstract (), db::Vector ()), 0));
|
||||||
|
|
||||||
|
const std::vector<std::pair<const db::DeviceAbstract *, db::DVector> > &other_abstracts = device.other_abstracts ();
|
||||||
|
for (std::vector<std::pair<const db::DeviceAbstract *, db::DVector> >::const_iterator a = other_abstracts.begin (); a != other_abstracts.end (); ++a) {
|
||||||
|
|
||||||
|
db::Vector pos = dbu_inv * a->second;
|
||||||
|
abstracts.insert (std::make_pair (std::make_pair (a->first, pos), a - other_abstracts.begin () + 1));
|
||||||
|
|
||||||
|
*mp_stream << " " << Keys::device_key << "(" << tl::to_word_or_quoted_string (a->first->name ()) << " " << pos.x () << " " << pos.y () << ")" << endl;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::map<unsigned int, std::vector<db::Device::OtherTerminalRef> > &reconnected_terminals = device.reconnected_terminals ();
|
||||||
|
for (std::map<unsigned int, std::vector<db::Device::OtherTerminalRef> >::const_iterator t = reconnected_terminals.begin (); t != reconnected_terminals.end (); ++t) {
|
||||||
|
|
||||||
|
for (std::vector<db::Device::OtherTerminalRef>::const_iterator c = t->second.begin (); c != t->second.end (); ++c) {
|
||||||
|
|
||||||
|
db::Vector pos = dbu_inv * c->offset;
|
||||||
|
std::map<std::pair<const db::DeviceAbstract *, db::Vector>, size_t>::const_iterator a = abstracts.find (std::make_pair (c->device_abstract, pos));
|
||||||
|
tl_assert (a != abstracts.end ());
|
||||||
|
|
||||||
|
*mp_stream << " " << Keys::connect_key << "(" << a->second << " " << tl::to_word_or_quoted_string (td [t->first].name ()) << " " << tl::to_word_or_quoted_string (td [c->other_terminal_id].name ()) << ")" << endl;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
db::Point pos = dbu_inv * device.position ();
|
||||||
|
|
||||||
|
*mp_stream << indent2 << Keys::location_key << "(" << pos.x () << " " << pos.y () << ")" << endl;
|
||||||
|
|
||||||
const std::vector<DeviceParameterDefinition> &pd = device.device_class ()->parameter_definitions ();
|
|
||||||
for (std::vector<DeviceParameterDefinition>::const_iterator i = pd.begin (); i != pd.end (); ++i) {
|
for (std::vector<DeviceParameterDefinition>::const_iterator i = pd.begin (); i != pd.end (); ++i) {
|
||||||
*mp_stream << indent2 << Keys::param_key << "(" << tl::to_word_or_quoted_string (i->name ()) << " " << device.parameter_value (i->id ()) << ")" << endl;
|
*mp_stream << indent2 << Keys::param_key << "(" << tl::to_word_or_quoted_string (i->name ()) << " " << device.parameter_value (i->id ()) << ")" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<DeviceTerminalDefinition> &td = device.device_class ()->terminal_definitions ();
|
|
||||||
for (std::vector<DeviceTerminalDefinition>::const_iterator i = td.begin (); i != td.end (); ++i) {
|
for (std::vector<DeviceTerminalDefinition>::const_iterator i = td.begin (); i != td.end (); ++i) {
|
||||||
const db::Net *net = device.net_for_terminal (i->id ());
|
const db::Net *net = device.net_for_terminal (i->id ());
|
||||||
if (net) {
|
if (net) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue