From 5f6b3710b5f607152e7b9a17611895fed833f841 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Tue, 1 Jun 2021 20:59:25 +0200 Subject: [PATCH 1/4] Doc fixed. --- src/drc/drc/built-in-macros/_drc_layer.rb | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/drc/drc/built-in-macros/_drc_layer.rb b/src/drc/drc/built-in-macros/_drc_layer.rb index 41c645f9d..3442b3742 100644 --- a/src/drc/drc/built-in-macros/_drc_layer.rb +++ b/src/drc/drc/built-in-macros/_drc_layer.rb @@ -3859,7 +3859,7 @@ CODE # # @code # # reports areas where layer 1/0 density is below 10% on 20x20 um tiles - # low_density = input(1, 0).density(0.0 .. 0.1, tile_size(20.um)) + # low_density = input(1, 0).with_density(0.0 .. 0.1, tile_size(20.um)) # @/code # # Anisotropic tiles can be specified by giving two values, like "tile_size(10.um, 20.um)". @@ -3873,7 +3873,7 @@ CODE # @code # # reports areas where layer 1/0 density is below 10% on 30x30 um tiles # # with a tile step of 20x20 um: - # low_density = input(1, 0).density(0.0 .. 0.1, tile_size(30.um), tile_step(20.um)) + # low_density = input(1, 0).with_density(0.0 .. 0.1, tile_size(30.um), tile_step(20.um)) # @/code # # For "tile_step", anisotropic values can be given as well by using two values: the first for the @@ -3891,7 +3891,7 @@ CODE # # reports density of layer 1/0 below 10% on 20x20 um tiles. The layout's boundary is taken from # # layer 0/0: # cell_frame = input(0, 0) - # low_density = input(1, 0).density(0.0 .. 0.1, tile_size(20.um), tile_boundary(cell_frame)) + # low_density = input(1, 0).with_density(0.0 .. 0.1, tile_size(20.um), tile_boundary(cell_frame)) # @/code # # Note that the layer given in "tile_boundary" adds to the input layer for computing the bounding box. @@ -3903,7 +3903,7 @@ CODE # @code # # reports density of layer 1/0 below 10% on 20x20 um tiles in the region 0,0 .. 2000,3000 # # (100 and 150 tiles of 20 um each are used in horizontal and vertical direction): - # low_density = input(1, 0).density(0.0 .. 0.1, tile_size(20.um), tile_origin(0.0, 0.0), tile_count(100, 150)) + # low_density = input(1, 0).with_density(0.0 .. 0.1, tile_size(20.um), tile_origin(0.0, 0.0), tile_count(100, 150)) # @/code # # The "padding mode" indicates how the area outside the layout's bounding box is considered. @@ -3917,7 +3917,7 @@ CODE # Example: # # @code - # low_density = input(1, 0).density(0.0 .. 0.1, tile_size(20.um), padding_ignore) + # low_density = input(1, 0).with_density(0.0 .. 0.1, tile_size(20.um), padding_ignore) # @/code # # The complementary version of "with_density" is \without_density. From a762797d58105659f032308fdf957986a146a903 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Tue, 1 Jun 2021 21:17:00 +0200 Subject: [PATCH 2/4] Typos fixed. --- src/db/db/gsiDeclDbNetlist.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/db/db/gsiDeclDbNetlist.cc b/src/db/db/gsiDeclDbNetlist.cc index 1a47fac77..be85f137f 100644 --- a/src/db/db/gsiDeclDbNetlist.cc +++ b/src/db/db/gsiDeclDbNetlist.cc @@ -2487,7 +2487,7 @@ Class db_NetlistSpiceReaderDelegate ("db", "Netl "This method receives a string with the element specification and the element code. It is supposed to " "parse the element line and return a model name, a value, a list of net names and a parameter value dictionary.\n" "\n" - "'parse_element' is called one every element card. The results of this call go into the \\element method " + "'parse_element' is called on every element card. The results of this call go into the \\element method " "to actually create the device. This method can be reimplemented to support other flavors of SPICE.\n" "\n" "This method has been introduced in version 0.27.1\n" @@ -2522,8 +2522,8 @@ Class db_NetlistSpiceReaderDelegate ("db", "Netl ) + gsi::method_ext ("parse_element_components", &parse_element_components, gsi::arg ("s"), "@brief Parses a string into string and parameter components.\n" - "This method is provided for simplifying the implementation of 'parse_element'. It takes a string and splits it into " - "string arguments and parameter values. For example, 'a b c=6' renders two string arguments in 'nn' and one parameter in pv ('C'->6.0). " + "This method is provided to simplify the implementation of 'parse_element'. It takes a string and splits it into " + "string arguments and parameter values. For example, 'a b c=6' renders two string arguments in 'nn' and one parameter ('C'->6.0). " "It returns data \\ParseElementComponentsData object with the strings and parameters.\n" "The parameter names are already translated to upper case.\n" "\n" From 7aaddcf20539d491ba505e762933212117e5e32a Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Thu, 3 Jun 2021 17:32:38 +0200 Subject: [PATCH 3/4] Normalize S/D choice on MOS transistor extraction for better test reproducability --- src/db/db/dbNetlistDeviceExtractorClasses.cc | 23 ++++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/db/db/dbNetlistDeviceExtractorClasses.cc b/src/db/db/dbNetlistDeviceExtractorClasses.cc index a2a96400a..1b8ff6280 100644 --- a/src/db/db/dbNetlistDeviceExtractorClasses.cc +++ b/src/db/db/dbNetlistDeviceExtractorClasses.cc @@ -144,13 +144,18 @@ void NetlistDeviceExtractorMOS3Transistor::extract_devices (const std::vector widths; + // normalize the diffusion polygons so that the S/D assignment is more predicable + std::vector diffpoly; + diffpoly.reserve (2); for (db::Region::const_iterator d2g = rdiff2gate.begin (); ! d2g.at_end (); ++d2g) { + diffpoly.push_back (*d2g); + } + std::sort (diffpoly.begin (), diffpoly.end ()); - db::Region rd2g; - rd2g.insert (*d2g); + std::vector widths; + for (std::vector::const_iterator d2g = diffpoly.begin (); d2g != diffpoly.end (); ++d2g) { - db::Edges edges (rgate.edges () & rd2g.edges ()); + db::Edges edges (rgate.edges () & db::Edges (*d2g)); db::Edges::length_type l = edges.length (); if (l == 0) { error (tl::to_string (tr ("Vanishing edges for interaction gate/diff (corner interaction) - gate shape ignored"))); @@ -179,18 +184,18 @@ void NetlistDeviceExtractorMOS3Transistor::extract_devices (const std::vectorset_parameter_value (db::DeviceClassMOS3Transistor::param_id_L, param_l); int diff_index = 0; - for (db::Region::const_iterator d = rdiff2gate.begin (); !d.at_end () && diff_index < 2; ++d, ++diff_index) { + for (std::vector::const_iterator d2g = diffpoly.begin (); d2g != diffpoly.end () && diff_index < 2; ++d2g, ++diff_index) { // count the number of gate shapes attached to this shape and distribute the area of the // diffusion region to the number of gates - size_t n = rgates.selected_interacting (db::Region (*d)).count (); + size_t n = rgates.selected_interacting (db::Region (*d2g)).count (); tl_assert (n > 0); - device->set_parameter_value (diff_index == 0 ? db::DeviceClassMOS3Transistor::param_id_AS : db::DeviceClassMOS3Transistor::param_id_AD, sdbu () * sdbu () * d->area () / double (n)); - device->set_parameter_value (diff_index == 0 ? db::DeviceClassMOS3Transistor::param_id_PS : db::DeviceClassMOS3Transistor::param_id_PD, sdbu () * d->perimeter () / double (n)); + device->set_parameter_value (diff_index == 0 ? db::DeviceClassMOS3Transistor::param_id_AS : db::DeviceClassMOS3Transistor::param_id_AD, sdbu () * sdbu () * d2g->area () / double (n)); + device->set_parameter_value (diff_index == 0 ? db::DeviceClassMOS3Transistor::param_id_PS : db::DeviceClassMOS3Transistor::param_id_PD, sdbu () * d2g->perimeter () / double (n)); unsigned int sd_index = diff_index == 0 ? source_terminal_geometry_index : drain_terminal_geometry_index; - define_terminal (device, diff_index == 0 ? db::DeviceClassMOS3Transistor::terminal_id_S : db::DeviceClassMOS3Transistor::terminal_id_D, sd_index, *d); + define_terminal (device, diff_index == 0 ? db::DeviceClassMOS3Transistor::terminal_id_S : db::DeviceClassMOS3Transistor::terminal_id_D, sd_index, *d2g); } From 02ec262df013272beded3574e7f9e4e26981c494 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Thu, 3 Jun 2021 23:43:00 +0200 Subject: [PATCH 4/4] Normalized resistor contact polygons for better test reproducibility. --- src/db/db/dbNetlistDeviceExtractorClasses.cc | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/db/db/dbNetlistDeviceExtractorClasses.cc b/src/db/db/dbNetlistDeviceExtractorClasses.cc index 1b8ff6280..2eb1d5c2a 100644 --- a/src/db/db/dbNetlistDeviceExtractorClasses.cc +++ b/src/db/db/dbNetlistDeviceExtractorClasses.cc @@ -468,8 +468,16 @@ void NetlistDeviceExtractorResistor::extract_devices (const std::vectorset_parameter_value (db::DeviceClassResistor::param_id_A, sdbu () * sdbu () * p->area ()); device->set_parameter_value (db::DeviceClassResistor::param_id_P, sdbu () * p->perimeter ()); + // collect and normalize the contact polygons (gives better reproducibility) + std::vector contact_poly; + contact_poly.reserve (2); + for (db::Region::const_iterator d = contacts_per_res.begin (); !d.at_end (); ++d) { + contact_poly.push_back (*d); + } + std::sort (contact_poly.begin (), contact_poly.end ()); + int cont_index = 0; - for (db::Region::const_iterator d = contacts_per_res.begin (); !d.at_end () && cont_index < 2; ++d, ++cont_index) { + for (std::vector::const_iterator d = contact_poly.begin (); d != contact_poly.end () && cont_index < 2; ++d, ++cont_index) { size_t terminal_geometry_index = cont_index == 0 ? a_terminal_geometry_index : b_terminal_geometry_index; define_terminal (device, cont_index == 0 ? db::DeviceClassResistor::terminal_id_A : db::DeviceClassResistor::terminal_id_B, terminal_geometry_index, *d); }