diff --git a/src/db/db/dbLayoutToNetlistReader.cc b/src/db/db/dbLayoutToNetlistReader.cc index dbf660a6b..cfd05242a 100644 --- a/src/db/db/dbLayoutToNetlistReader.cc +++ b/src/db/db/dbLayoutToNetlistReader.cc @@ -481,18 +481,6 @@ void LayoutToNetlistStandardReader::read_netlist (db::Netlist *netlist, db::Layo br.done (); - } else if (test (skeys::param_key) || test (lkeys::param_key)) { - - Brace br (this); - - std::string param_name; - read_word_or_quoted (param_name); - int primary = read_int (); - double default_value = read_double (); - make_parameter (dc, param_name, primary, default_value); - - br.done (); - } else if (test (skeys::param_int_key) || test (lkeys::param_int_key)) { Brace br (this); @@ -549,6 +537,18 @@ void LayoutToNetlistStandardReader::read_netlist (db::Netlist *netlist, db::Layo br.done (); + } else if (test (skeys::param_key) || test (lkeys::param_key)) { + + Brace br (this); + + std::string param_name; + read_word_or_quoted (param_name); + int primary = read_int (); + double default_value = read_double (); + make_parameter (dc, param_name, primary, default_value); + + br.done (); + } else { skip_element (); } @@ -1121,17 +1121,6 @@ LayoutToNetlistStandardReader::read_device (db::Netlist *netlist, db::LayoutToNe br2.done (); - } else if (test (skeys::param_key) || test (lkeys::param_key)) { - - Brace br2 (this); - std::string pname; - read_word_or_quoted (pname); - double value = read_double (); - br2.done (); - - size_t pid = dm.second->parameter_id_for_name_create (pname, true, 0.0); - device->set_parameter_value (pid, value); - } else if (test (skeys::param_int_key) || test (lkeys::param_int_key)) { Brace br2 (this); @@ -1181,6 +1170,17 @@ LayoutToNetlistStandardReader::read_device (db::Netlist *netlist, db::LayoutToNe size_t pid = dm.second->parameter_id_for_name_create (pname, true, tl::Variant ()); device->set_parameter_value (pid, tl::Variant ()); + } else if (test (skeys::param_key) || test (lkeys::param_key)) { + + Brace br2 (this); + std::string pname; + read_word_or_quoted (pname); + double value = read_double (); + br2.done (); + + size_t pid = dm.second->parameter_id_for_name_create (pname, true, 0.0); + device->set_parameter_value (pid, value); + } else if (at_end ()) { throw tl::Exception (tl::to_string (tr ("Unexpected end of file inside device definition (location, scale, mirror, rotation, param or terminal expected)"))); } else { diff --git a/src/db/unit_tests/dbLayoutToNetlistReaderTests.cc b/src/db/unit_tests/dbLayoutToNetlistReaderTests.cc index 1ff7f893e..3fad59f11 100644 --- a/src/db/unit_tests/dbLayoutToNetlistReaderTests.cc +++ b/src/db/unit_tests/dbLayoutToNetlistReaderTests.cc @@ -563,3 +563,24 @@ TEST(7_CustomDevice) compare_text_files (path, au_path); } + +TEST(8_VariantDeviceParameters) +{ + db::LayoutToNetlist l2n; + + // build from: testdata/algo/l2n_reader_4.gds + + std::string in_path = tl::combine_path (tl::combine_path (tl::testdata (), "algo"), "l2n_reader_8.l2n"); + tl::InputStream is_in (in_path); + + db::LayoutToNetlistStandardReader reader (is_in); + reader.read (&l2n); + + tl_assert (l2n.netlist () != 0); + EXPECT_EQ (l2n.netlist ()->to_string (), + "circuit TOP ();\n" + " device DEVCLS dev (S=(null),G=(null),D=(null),B=(null)) (D=17.5,L=42,S=XYZ,B=true,N=nil);\n" + " device DEVCLS dev2 (S=(null),G=(null),D=(null),B=(null)) (D=0,L=0,S=,B=false,N=nil);\n" + "end;\n" + ); +} diff --git a/src/db/unit_tests/dbLayoutToNetlistWriterTests.cc b/src/db/unit_tests/dbLayoutToNetlistWriterTests.cc index 67648a5b0..3374ce906 100644 --- a/src/db/unit_tests/dbLayoutToNetlistWriterTests.cc +++ b/src/db/unit_tests/dbLayoutToNetlistWriterTests.cc @@ -25,6 +25,7 @@ #include "dbStream.h" #include "dbCommonReader.h" #include "dbNetlistDeviceExtractorClasses.h" +#include "dbNetlistDeviceClasses.h" #include "dbTestSupport.h" #include "tlUnitTest.h" @@ -484,3 +485,59 @@ TEST(3_Messages) compare_text_files (path, au_path); } + +TEST(4_VariantDeviceParameters) +{ + db::Layout ly; + db::Cell &tc = ly.cell (ly.add_cell ("TOP")); + db::LayoutToNetlist l2n (db::RecursiveShapeIterator (ly, tc, std::set ())); + + db::Netlist *nl = l2n.make_netlist (); + + db::DeviceClass *dc = new db::DeviceClassMOS4Transistor (); + dc->set_name ("DEVCLS"); + dc->clear_parameter_definitions (); + size_t idd = dc->add_parameter_definition (db::DeviceParameterDefinition ("D", "double", tl::Variant (0.0))).id (); + size_t idl = dc->add_parameter_definition (db::DeviceParameterDefinition ("L", "long", tl::Variant (long (0)))).id (); + size_t ids = dc->add_parameter_definition (db::DeviceParameterDefinition ("S", "string", tl::Variant (""))).id (); + size_t idb = dc->add_parameter_definition (db::DeviceParameterDefinition ("B", "bool", tl::Variant (false))).id (); + size_t idn = dc->add_parameter_definition (db::DeviceParameterDefinition ("N", "nil", tl::Variant ())).id (); + nl->add_device_class (dc); + + db::Circuit *top = new db::Circuit (); + top->set_name ("TOP"); + nl->add_circuit (top); + + db::Device *dev = new db::Device (dc, "dev"); + dev->set_parameter_value (idd, 17.5); + dev->set_parameter_value (idl, long (42)); + dev->set_parameter_value (ids, "XYZ"); + dev->set_parameter_value (idb, true); + dev->set_parameter_value (idn, tl::Variant ()); + top->add_device (dev); + + dev = new db::Device (dc, "dev2"); + top->add_device (dev); + + std::string path = tmp_file ("tmp_l2nwriter_4.txt"); + { + tl::OutputStream stream (path); + db::LayoutToNetlistStandardWriter writer (stream, false); + writer.write (&l2n); + } + + std::string au_path = tl::combine_path (tl::combine_path (tl::testdata (), "algo"), "l2n_writer_au_4.txt"); + + compare_text_files (path, au_path); + + path = tmp_file ("tmp_l2nwriter_4s.txt"); + { + tl::OutputStream stream (path); + db::LayoutToNetlistStandardWriter writer (stream, true); + writer.write (&l2n); + } + + au_path = tl::combine_path (tl::combine_path (tl::testdata (), "algo"), "l2n_writer_au_4s.txt"); + + compare_text_files (path, au_path); +}