From 5c217b90b554d25333442fb6534c76f78e171d69 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Wed, 27 Nov 2019 22:33:50 +0100 Subject: [PATCH] WIP: starting MAG writer. --- .../streamers/cif/db_plugin/dbCIFWriter.cc | 28 +++++----- .../streamers/cif/db_plugin/dbCIFWriter.h | 2 +- .../streamers/cif/db_plugin/gsiDeclDbCIF.cc | 2 +- .../streamers/magic/db_plugin/dbMAG.cc | 9 +-- .../streamers/magic/db_plugin/dbMAGFormat.h | 19 +++---- .../streamers/magic/db_plugin/dbMAGReader.cc | 2 +- .../streamers/magic/db_plugin/dbMAGWriter.cc | 39 ++----------- .../streamers/magic/db_plugin/dbMAGWriter.h | 22 -------- .../streamers/magic/db_plugin/gsiDeclDbMAG.cc | 55 ++++++------------- .../magic/lay_plugin/MAGWriterOptionPage.ui | 49 +++++------------ .../magic/lay_plugin/layMAGWriterPlugin.cc | 14 +++-- .../streamers/magic/unit_tests/dbMAGReader.cc | 3 +- 12 files changed, 73 insertions(+), 171 deletions(-) diff --git a/src/plugins/streamers/cif/db_plugin/dbCIFWriter.cc b/src/plugins/streamers/cif/db_plugin/dbCIFWriter.cc index 6422af9d8..a4e84a83a 100644 --- a/src/plugins/streamers/cif/db_plugin/dbCIFWriter.cc +++ b/src/plugins/streamers/cif/db_plugin/dbCIFWriter.cc @@ -107,7 +107,7 @@ CIFWriter::write (db::Layout &layout, tl::OutputStream &stream, const db::SaveLa strftime(timestr, sizeof (timestr), "%F %T", &tt); // Write header - *this << "(CIF file written " << (const char *)timestr << " by KLayout);" << endl; + *this << "(CIF file written " << (const char *)timestr << " by KLayout);" << m_endl; // TODO: this can be done more intelligently .. int tl_scale_divider; @@ -136,8 +136,8 @@ CIFWriter::write (db::Layout &layout, tl::OutputStream &stream, const db::SaveLa double sf = 1.0; - *this << "DS " << cell_index << " " << tl_scale_denom << " " << tl_scale_divider << ";" << endl; - *this << "9 " << tl::to_word_or_quoted_string (layout.cell_name (*cell)) << ";" << endl; + *this << "DS " << cell_index << " " << tl_scale_denom << " " << tl_scale_divider << ";" << m_endl; + *this << "9 " << tl::to_word_or_quoted_string (layout.cell_name (*cell)) << ";" << m_endl; // instances for (db::Cell::const_iterator inst = cref.begin (); ! inst.at_end (); ++inst) { @@ -195,7 +195,7 @@ CIFWriter::write (db::Layout &layout, tl::OutputStream &stream, const db::SaveLa *this << " T" << d.x() << xy_sep () << d.y(); - *this << ";" << endl; + *this << ";" << m_endl; } @@ -219,7 +219,7 @@ CIFWriter::write (db::Layout &layout, tl::OutputStream &stream, const db::SaveLa } // end of cell - *this << "DF;" << endl; + *this << "DF;" << m_endl; } @@ -232,7 +232,7 @@ CIFWriter::write (db::Layout &layout, tl::OutputStream &stream, const db::SaveLa std::map::const_iterator cif_index = db_to_cif_index_map.find (*cell); tl_assert(cif_index != db_to_cif_index_map.end ()); - *this << "C" << cif_index->second << ";" << endl; + *this << "C" << cif_index->second << ";" << m_endl; } @@ -241,7 +241,7 @@ CIFWriter::write (db::Layout &layout, tl::OutputStream &stream, const db::SaveLa } // end of file - *this << "E" << endl; + *this << "E" << m_endl; m_progress.set (mp_stream->pos ()); @@ -252,7 +252,7 @@ CIFWriter::emit_layer() { if (m_needs_emit) { m_needs_emit = false; - *this << "L " << tl::to_word_or_quoted_string(m_layer.name, "0123456789_.$") << ";" << endl; + *this << "L " << tl::to_word_or_quoted_string(m_layer.name, "0123456789_.$") << ";" << m_endl; } } @@ -271,7 +271,7 @@ CIFWriter::write_texts (const db::Layout &layout, const db::Cell &cell, unsigned double h = shape->text_size () * layout.dbu (); db::Vector p (shape->text_trans ().disp () * sf); - *this << " " << p.x() << xy_sep () << p.y () << " " << h << ";" << endl; + *this << " " << p.x() << xy_sep () << p.y () << " " << h << ";" << m_endl; ++shape; @@ -324,7 +324,7 @@ CIFWriter::write_polygon (const db::Polygon &polygon, double sf) db::Point pp (*p * sf); *this << " " << pp.x () << xy_sep () << pp.y (); } - *this << ";" << endl; + *this << ";" << m_endl; } void @@ -338,7 +338,7 @@ CIFWriter::write_boxes (const db::Layout & /*layout*/, const db::Cell &cell, uns emit_layer (); db::Box b (shape->bbox () * sf); - *this << "B " << b.width () << " " << b.height () << " " << b.center ().x () << xy_sep () << b.center ().y () << ";" << endl; + *this << "B " << b.width () << " " << b.height () << " " << b.center ().x () << xy_sep () << b.center ().y () << ";" << m_endl; ++shape; @@ -411,13 +411,13 @@ CIFWriter::write_paths (const db::Layout & /*layout*/, const db::Cell &cell, uns db::Point pp (*shape->begin_point () * sf); *this << " " << pp.x () << xy_sep () << pp.y (); - *this << ";" << endl; + *this << ";" << m_endl; } else if (path_type >= 0 && npts > 1) { emit_layer (); - *this << "98 " << path_type << ";" << endl; + *this << "98 " << path_type << ";" << m_endl; *this << "W " << long (floor (0.5 + sf * shape->path_width ())); @@ -426,7 +426,7 @@ CIFWriter::write_paths (const db::Layout & /*layout*/, const db::Cell &cell, uns *this << " " << pp.x () << xy_sep () << pp.y (); } - *this << ";" << endl; + *this << ";" << m_endl; } else { db::Polygon poly; diff --git a/src/plugins/streamers/cif/db_plugin/dbCIFWriter.h b/src/plugins/streamers/cif/db_plugin/dbCIFWriter.h index d5ade32f8..ab81244b7 100644 --- a/src/plugins/streamers/cif/db_plugin/dbCIFWriter.h +++ b/src/plugins/streamers/cif/db_plugin/dbCIFWriter.h @@ -66,7 +66,7 @@ private: tl::OutputStream *mp_stream; CIFWriterOptions m_options; tl::AbsoluteProgress m_progress; - endl_tag endl; + endl_tag m_endl; db::LayerProperties m_layer; bool m_needs_emit; diff --git a/src/plugins/streamers/cif/db_plugin/gsiDeclDbCIF.cc b/src/plugins/streamers/cif/db_plugin/gsiDeclDbCIF.cc index ed41fb092..dd9f47783 100644 --- a/src/plugins/streamers/cif/db_plugin/gsiDeclDbCIF.cc +++ b/src/plugins/streamers/cif/db_plugin/gsiDeclDbCIF.cc @@ -212,7 +212,7 @@ static bool get_cif_blank_separator (const db::SaveLayoutOptions *options) return options->get_options ().blank_separator; } -// extend lay::SaveLayoutOptions with the GDS2 options +// extend lay::SaveLayoutOptions with the CIF options static gsi::ClassExt cif_writer_options ( gsi::method_ext ("cif_dummy_calls=", &set_cif_dummy_calls, diff --git a/src/plugins/streamers/magic/db_plugin/dbMAG.cc b/src/plugins/streamers/magic/db_plugin/dbMAG.cc index 522adc5a8..76cb45985 100644 --- a/src/plugins/streamers/magic/db_plugin/dbMAG.cc +++ b/src/plugins/streamers/magic/db_plugin/dbMAG.cc @@ -83,7 +83,7 @@ public: virtual tl::XMLElementBase *xml_reader_options_element () const { - return new db::ReaderOptionsXMLElement ("cif", + return new db::ReaderOptionsXMLElement ("mag", tl::make_member (&db::MAGReaderOptions::lambda, "lambda") + tl::make_member (&db::MAGReaderOptions::dbu, "dbu") + tl::make_member (&db::MAGReaderOptions::layer_map, "layer-map") + @@ -98,12 +98,9 @@ public: virtual tl::XMLElementBase *xml_writer_options_element () const { -// @@@ - return new db::WriterOptionsXMLElement ("cif", - tl::make_member (&db::MAGWriterOptions::dummy_calls, "dummy-calls") + - tl::make_member (&db::MAGWriterOptions::blank_separator, "blank-separator") + return new db::WriterOptionsXMLElement ("mag", + tl::make_member (&db::MAGWriterOptions::lambda, "lambda") ); -// @@@ } }; diff --git a/src/plugins/streamers/magic/db_plugin/dbMAGFormat.h b/src/plugins/streamers/magic/db_plugin/dbMAGFormat.h index d2a74e4e6..4a3cea896 100644 --- a/src/plugins/streamers/magic/db_plugin/dbMAGFormat.h +++ b/src/plugins/streamers/magic/db_plugin/dbMAGFormat.h @@ -146,24 +146,19 @@ public: * @brief The constructor */ MAGWriterOptions () - : dummy_calls (false), blank_separator (false) + : lambda (0.0) { // .. nothing yet .. } /** - * @brief A flag indicating whether dummy calls shall be written - * If this flag is true, the writer will produce dummy cell calls on global - * level for all top cells. + * @brief Specifies the lambda value for writing + * + * The lambda value is the basic scaling parameter. + * If this value is set to 0 or negative, the lambda value stored in the layout + * is used (meta data "lambda"). */ - bool dummy_calls; - - /** - * @brief A flag indicating whether to use blanks as x/y separators - * If this flag is true, blank characters will be used to separate x and y values. - * Otherwise comma characters will be used. - */ - bool blank_separator; + double lambda; /** * @brief Implementation of FormatSpecificWriterOptions diff --git a/src/plugins/streamers/magic/db_plugin/dbMAGReader.cc b/src/plugins/streamers/magic/db_plugin/dbMAGReader.cc index 0f440cf31..6cba1ed41 100644 --- a/src/plugins/streamers/magic/db_plugin/dbMAGReader.cc +++ b/src/plugins/streamers/magic/db_plugin/dbMAGReader.cc @@ -283,7 +283,7 @@ MAGReader::do_read_part (db::Layout &layout, db::cell_index_type cell_index, tl: error (tl::to_string (tr ("Could not find 'magic' header line - is this a MAGIC file?"))); } - layout.add_meta_info (db::MetaInfo ("magic_lambda", "MAGIC lambda value", tl::to_string (m_lambda))); + layout.add_meta_info (db::MetaInfo ("lambda", "lambda value (tech scaling)", tl::to_string (m_lambda))); bool valid_layer = false; unsigned int current_layer = 0; diff --git a/src/plugins/streamers/magic/db_plugin/dbMAGWriter.cc b/src/plugins/streamers/magic/db_plugin/dbMAGWriter.cc index fbcaec5f0..c149aeff6 100644 --- a/src/plugins/streamers/magic/db_plugin/dbMAGWriter.cc +++ b/src/plugins/streamers/magic/db_plugin/dbMAGWriter.cc @@ -37,50 +37,19 @@ namespace db MAGWriter::MAGWriter () : mp_stream (0), - m_progress (tl::to_string (tr ("Writing MAG file")), 10000), - m_needs_emit (false) + m_progress (tl::to_string (tr ("Writing Magic file")), 10000) { m_progress.set_format (tl::to_string (tr ("%.0f MB"))); m_progress.set_unit (1024 * 1024); } -MAGWriter & -MAGWriter::operator<<(const char *s) -{ - mp_stream->put(s, strlen(s)); - return *this; -} - -MAGWriter & -MAGWriter::operator<<(const std::string &s) -{ - mp_stream->put(s.c_str(), s.size()); - return *this; -} - -MAGWriter & -MAGWriter::operator<<(endl_tag) -{ -#ifdef _WIN32 - *this << "\r\n"; -#else - *this << "\n"; -#endif - return *this; -} - -const char * -MAGWriter::xy_sep () const -{ - return m_options.blank_separator ? " " : ","; -} - void MAGWriter::write (db::Layout &layout, tl::OutputStream &stream, const db::SaveLayoutOptions &options) { m_options = options.get_options (); mp_stream = &stream; +#if 0 // @@@ // compute the scale factor to get to the 10 nm basic database unit of MAG double tl_scale = options.scale_factor () * layout.dbu () / 0.01; @@ -242,11 +211,12 @@ MAGWriter::write (db::Layout &layout, tl::OutputStream &stream, const db::SaveLa // end of file *this << "E" << endl; +#endif m_progress.set (mp_stream->pos ()); - } +#if 0 // @@@ void MAGWriter::emit_layer() { @@ -440,6 +410,7 @@ MAGWriter::write_paths (const db::Layout & /*layout*/, const db::Cell &cell, uns } } +#endif } diff --git a/src/plugins/streamers/magic/db_plugin/dbMAGWriter.h b/src/plugins/streamers/magic/db_plugin/dbMAGWriter.h index 813b4d046..d648d9e1c 100644 --- a/src/plugins/streamers/magic/db_plugin/dbMAGWriter.h +++ b/src/plugins/streamers/magic/db_plugin/dbMAGWriter.h @@ -66,28 +66,6 @@ private: tl::OutputStream *mp_stream; MAGWriterOptions m_options; tl::AbsoluteProgress m_progress; - endl_tag endl; - db::LayerProperties m_layer; - bool m_needs_emit; - - MAGWriter &operator<<(const char *s); - MAGWriter &operator<<(const std::string &s); - MAGWriter &operator<<(endl_tag); - - template MAGWriter &operator<<(const X &x) - { - return (*this << tl::to_string(x)); - } - - void write_texts (const db::Layout &layout, const db::Cell &cell, unsigned int layer, double tl_scale); - void write_polygons (const db::Layout &layout, const db::Cell &cell, unsigned int layer, double tl_scale); - void write_polygon (const db::Polygon &polygon, double tl_scale); - void write_boxes (const db::Layout &layout, const db::Cell &cell, unsigned int layer, double tl_scale); - void write_paths (const db::Layout &layout, const db::Cell &cell, unsigned int layer, double tl_scale); - void write_edges (const db::Layout &layout, const db::Cell &cell, unsigned int layer, double tl_scale); - const char *xy_sep () const; - - void emit_layer(); }; } // namespace db diff --git a/src/plugins/streamers/magic/db_plugin/gsiDeclDbMAG.cc b/src/plugins/streamers/magic/db_plugin/gsiDeclDbMAG.cc index 00b5e86b6..33bcbbf4c 100644 --- a/src/plugins/streamers/magic/db_plugin/gsiDeclDbMAG.cc +++ b/src/plugins/streamers/magic/db_plugin/gsiDeclDbMAG.cc @@ -236,53 +236,32 @@ gsi::ClassExt mag_reader_options ( // --------------------------------------------------------------- // gsi Implementation of specific methods -static void set_mag_dummy_calls (db::SaveLayoutOptions *options, bool f) +static void set_mag_lambda_w (db::SaveLayoutOptions *options, double f) { - options->get_options ().dummy_calls = f; + options->get_options ().lambda = f; } -static bool get_mag_dummy_calls (const db::SaveLayoutOptions *options) +static double get_mag_lambda_w (const db::SaveLayoutOptions *options) { - return options->get_options ().dummy_calls; + return options->get_options ().lambda; } -static void set_mag_blank_separator (db::SaveLayoutOptions *options, bool f) -{ - options->get_options ().blank_separator = f; -} - -static bool get_mag_blank_separator (const db::SaveLayoutOptions *options) -{ - return options->get_options ().blank_separator; -} - -// extend lay::SaveLayoutOptions with the GDS2 options +// extend lay::SaveLayoutOptions with the MAG options static gsi::ClassExt mag_writer_options ( - gsi::method_ext ("mag_dummy_calls=", &set_mag_dummy_calls, - "@brief Sets a flag indicating whether dummy calls shall be written\n" - "If this property is set to true, dummy calls will be written in the top level entity " - "of the MAG file calling every top cell.\n" - "This option is useful for enhanced compatibility with other tools.\n" - "\nThis property has been added in version 0.23.10.\n" + gsi::method_ext ("mag_lambda=", &set_mag_lambda_w, gsi::arg ("lambda"), + "@brief Specifies the lambda value to used for writing\n" + "\n" + "The lamdba value is the basic unit of the layout.\n" + "The layout is brought to units of this value. If the layout is not on-grid on this unit, snapping will happen. " + "If the value is less or equal to zero, KLayout will use the lambda value stored inside the layout (set by a previous read operation " + "of a MAGIC file).\n" + "\nThis property has been added in version 0.26.2.\n" ) + - gsi::method_ext ("mag_dummy_calls?|#mag_dummy_calls", &get_mag_dummy_calls, - "@brief Gets a flag indicating whether dummy calls shall be written\n" - "See \\mag_dummy_calls= method for a description of that property." - "\nThis property has been added in version 0.23.10.\n" - "\nThe predicate version (mag_blank_separator?) has been added in version 0.25.1.\n" - ) + - gsi::method_ext ("mag_blank_separator=", &set_mag_blank_separator, - "@brief Sets a flag indicating whether blanks shall be used as x/y separator characters\n" - "If this property is set to true, the x and y coordinates are separated with blank characters " - "rather than comma characters." - "\nThis property has been added in version 0.23.10.\n" - ) + - gsi::method_ext ("mag_blank_separator?|#mag_blank_separator", &get_mag_blank_separator, - "@brief Gets a flag indicating whether blanks shall be used as x/y separator characters\n" - "See \\mag_blank_separator= method for a description of that property." - "\nThis property has been added in version 0.23.10.\n" - "\nThe predicate version (mag_blank_separator?) has been added in version 0.25.1.\n" + gsi::method_ext ("mag_lambda", &get_mag_lambda_w, + "@brief Get the lambda value\n" + "See \\mag_lambda= method for a description of this attribute." + "\nThis property has been added in version 0.26.2.\n" ), "" ); diff --git a/src/plugins/streamers/magic/lay_plugin/MAGWriterOptionPage.ui b/src/plugins/streamers/magic/lay_plugin/MAGWriterOptionPage.ui index 08ca57d76..0b0b842c6 100644 --- a/src/plugins/streamers/magic/lay_plugin/MAGWriterOptionPage.ui +++ b/src/plugins/streamers/magic/lay_plugin/MAGWriterOptionPage.ui @@ -35,50 +35,27 @@ CIF Writer Options - - 9 - - - 9 - - - 9 - - - 9 - - - - - 0 - 0 - - + + + + - If checked, a blank character is used as x/y coordinate -separator. Otherweise a comma is used. + Micron + + + Lambda value + + + + - Blank as x/y separator - - - - - - - Dummy cell calls - - - - - - - If checked, dummy cell calls are added on global level + Leave this value empty to take the lambda value stored in the layout diff --git a/src/plugins/streamers/magic/lay_plugin/layMAGWriterPlugin.cc b/src/plugins/streamers/magic/lay_plugin/layMAGWriterPlugin.cc index 20f59473d..d017cc186 100644 --- a/src/plugins/streamers/magic/lay_plugin/layMAGWriterPlugin.cc +++ b/src/plugins/streamers/magic/lay_plugin/layMAGWriterPlugin.cc @@ -55,8 +55,11 @@ MAGWriterOptionPage::setup (const db::FormatSpecificWriterOptions *o, const db:: { const db::MAGWriterOptions *options = dynamic_cast (o); if (options) { - mp_ui->dummy_calls_cbx->setChecked (options->dummy_calls); - mp_ui->blank_separator_cbx->setChecked (options->blank_separator); + if (options->lambda <= 0.0) { + mp_ui->lambda_le->setText (QString ()); + } else { + mp_ui->lambda_le->setText (tl::to_qstring (tl::to_string (options->lambda))); + } } } @@ -65,8 +68,11 @@ MAGWriterOptionPage::commit (db::FormatSpecificWriterOptions *o, const db::Techn { db::MAGWriterOptions *options = dynamic_cast (o); if (options) { - options->dummy_calls = mp_ui->dummy_calls_cbx->isChecked (); - options->blank_separator = mp_ui->blank_separator_cbx->isChecked (); + QString l = mp_ui->lambda_le->text ().trimmed (); + options->lambda = 0.0; + if (! l.isEmpty ()) { + tl::from_string (tl::to_string (l), options->lambda); + } } } diff --git a/src/plugins/streamers/magic/unit_tests/dbMAGReader.cc b/src/plugins/streamers/magic/unit_tests/dbMAGReader.cc index 5214482cf..6766055b5 100644 --- a/src/plugins/streamers/magic/unit_tests/dbMAGReader.cc +++ b/src/plugins/streamers/magic/unit_tests/dbMAGReader.cc @@ -97,8 +97,7 @@ static void run_test (tl::TestBase *_this, const std::string &base, const char * tl::OutputStream stream (tmp_cif_file); db::MAGWriterOptions *opt = new db::MAGWriterOptions(); - opt->dummy_calls = dummy_calls; - opt->blank_separator = blank_sep; + opt->lambda = 0.5; db::MAGWriter writer; db::SaveLayoutOptions options;