mirror of https://github.com/KLayout/klayout.git
Extension of the L2N/LVSDB format to support deleted terminals and parameters
Previously, when deleting parameters or terminals from device definitions, these parameters or terminals re-appeared in the netlist browser, because they were generated from the template class (e.g. "A" and "B" from "RES"). An additional token is added that indicates whether to remove all entries before adding new ones. This feature is backward-compatible and LVSDB/L2N files have to be generated from new KLayout versions to make use of that feature.
This commit is contained in:
parent
5173a2aad7
commit
f2172d8e2a
|
|
@ -79,7 +79,10 @@ namespace db
|
|||
* circuit(<name> [circuit-def]) - circuit (cell) [short key: X]
|
||||
*
|
||||
* [class]:
|
||||
* class(<name> <template> [template-def]) - a device class definition (template: RES,CAP,...) [short key: K]
|
||||
* class(<name> <template> <full-specs>? [template-def]) - a device class definition (template: RES,CAP,...) [short key: K]
|
||||
* "fill_specs" is an optional value (0 or 1), indicating that all parameters and terminals
|
||||
* are listed. For "1", the reader will remove all specs from the template before rebuilding
|
||||
* them.
|
||||
*
|
||||
* [device]:
|
||||
* device(<name> <class> [device-abstract-terminal|any]*)
|
||||
|
|
@ -158,8 +161,8 @@ namespace db
|
|||
* [template-param|template-terminal|any]*
|
||||
*
|
||||
* [template-param]:
|
||||
* param(<name> <primary>? <default-value>*) - defines a template parameter [short key: E]
|
||||
* ('primary' is a value: 0 or 1)
|
||||
* param(<name> <primary> <default-value>) - defines a template parameter [short key: E]
|
||||
* ('primary' is a value: 0 or 1, 'default_value' is a float)
|
||||
*
|
||||
* [template-terminal]:
|
||||
* terminal(<name>) - defines a terminal [short key: T]
|
||||
|
|
|
|||
|
|
@ -391,6 +391,9 @@ void LayoutToNetlistStandardReader::read_netlist (db::Netlist *netlist, db::Layo
|
|||
read_word_or_quoted (class_name);
|
||||
read_word_or_quoted (templ_name);
|
||||
|
||||
int full_specs = 0;
|
||||
try_read_int (full_specs);
|
||||
|
||||
if (netlist->device_class_by_name (class_name) != 0) {
|
||||
throw tl::Exception (tl::to_string (tr ("Duplicate definition of device class: ")) + class_name);
|
||||
}
|
||||
|
|
@ -407,6 +410,13 @@ void LayoutToNetlistStandardReader::read_netlist (db::Netlist *netlist, db::Layo
|
|||
dc = dct->create ();
|
||||
}
|
||||
|
||||
// start with tabula rasa on "full specs"
|
||||
if (full_specs != 0) {
|
||||
dc->clear_equivalent_terminal_ids ();
|
||||
dc->clear_parameter_definitions ();
|
||||
dc->clear_terminal_definitions ();
|
||||
}
|
||||
|
||||
dc->set_name (class_name);
|
||||
netlist->add_device_class (dc);
|
||||
|
||||
|
|
|
|||
|
|
@ -294,11 +294,29 @@ void std_writer_impl<Keys>::write_device_class (TokenizedOutput &stream, const d
|
|||
TokenizedOutput out (stream, Keys::class_key);
|
||||
out << tl::to_word_or_quoted_string (cls->name ()) << tl::to_word_or_quoted_string (temp_name);
|
||||
|
||||
// we need to issue all specs if some are deleted
|
||||
bool full_specs = false;
|
||||
|
||||
const std::vector<DeviceParameterDefinition> &pd_temp = temp_class->parameter_definitions ();
|
||||
for (auto p = pd_temp.begin (); p != pd_temp.end () && ! full_specs; ++p) {
|
||||
full_specs = ! cls->has_parameter_with_name (p->name ());
|
||||
}
|
||||
|
||||
const std::vector<DeviceTerminalDefinition> &td_temp = temp_class->terminal_definitions ();
|
||||
for (auto t = td_temp.begin (); t != td_temp.end () && ! full_specs; ++t) {
|
||||
full_specs = ! cls->has_terminal_with_name (t->name ());
|
||||
}
|
||||
|
||||
// new token: indicates that all specs will be listed
|
||||
if (full_specs) {
|
||||
out << tl::to_string (1);
|
||||
}
|
||||
|
||||
bool any_def = false;
|
||||
|
||||
const std::vector<DeviceParameterDefinition> &pd = cls->parameter_definitions ();
|
||||
for (std::vector<DeviceParameterDefinition>::const_iterator p = pd.begin (); p != pd.end (); ++p) {
|
||||
if (! temp_class->has_parameter_with_name (p->name ()) || !same_parameter (*p, *temp_class->parameter_definition (temp_class->parameter_id_for_name (p->name ())))) {
|
||||
for (auto p = pd.begin (); p != pd.end (); ++p) {
|
||||
if (full_specs || ! temp_class->has_parameter_with_name (p->name ()) || !same_parameter (*p, *temp_class->parameter_definition (temp_class->parameter_id_for_name (p->name ())))) {
|
||||
if (! any_def) {
|
||||
out << endl;
|
||||
}
|
||||
|
|
@ -308,8 +326,8 @@ void std_writer_impl<Keys>::write_device_class (TokenizedOutput &stream, const d
|
|||
}
|
||||
|
||||
const std::vector<DeviceTerminalDefinition> &td = cls->terminal_definitions ();
|
||||
for (std::vector<DeviceTerminalDefinition>::const_iterator t = td.begin (); t != td.end (); ++t) {
|
||||
if (! temp_class->has_terminal_with_name (t->name ())) {
|
||||
for (auto t = td.begin (); t != td.end (); ++t) {
|
||||
if (full_specs || ! temp_class->has_terminal_with_name (t->name ())) {
|
||||
if (! any_def) {
|
||||
out << endl;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue