mirror of https://github.com/KLayout/klayout.git
855 lines
30 KiB
C++
855 lines
30 KiB
C++
|
|
/*
|
|
|
|
KLayout Layout Viewer
|
|
Copyright (C) 2006-2021 Matthias Koefferlein
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
*/
|
|
|
|
|
|
#include "dbLEFDEFImporter.h"
|
|
|
|
#include "tlExceptions.h"
|
|
|
|
#include "layLEFDEFImportDialogs.h"
|
|
#include "layLoadLayoutOptionsDialog.h"
|
|
#include "layQtTools.h"
|
|
#include "layMainWindow.h"
|
|
#include "tlString.h"
|
|
|
|
#include <QFileDialog>
|
|
|
|
namespace lay
|
|
{
|
|
|
|
// -----------------------------------------------------------------------------------------------
|
|
// LEFDEF importer data
|
|
|
|
LEFDEFImportData::LEFDEFImportData ()
|
|
: mode (0)
|
|
{
|
|
// .. nothing yet ..
|
|
|
|
}
|
|
|
|
void LEFDEFImportData::from_string (const std::string &s)
|
|
{
|
|
tl::Extractor ex (s.c_str ());
|
|
while (! ex.at_end ()) {
|
|
|
|
if (ex.test ("file")) {
|
|
|
|
ex.test ("=");
|
|
ex.read_quoted (file);
|
|
ex.test (";");
|
|
|
|
} else if (ex.test ("lef-files")) {
|
|
|
|
ex.test ("=");
|
|
lef_files.clear ();
|
|
while (! ex.test (";")) {
|
|
ex.test (",");
|
|
lef_files.push_back (std::string ());
|
|
ex.read_quoted (lef_files.back ());
|
|
}
|
|
|
|
} else if (ex.test ("import-mode")) {
|
|
|
|
ex.test ("=");
|
|
ex.read (mode);
|
|
ex.test (";");
|
|
|
|
} else {
|
|
break;
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
std::string
|
|
LEFDEFImportData::to_string () const
|
|
{
|
|
std::string s;
|
|
s += "file=" + tl::to_quoted_string(file) + ";";
|
|
if (! lef_files.empty ()) {
|
|
s += "lef-files=";
|
|
for (size_t i = 0; i < lef_files.size (); ++i) {
|
|
if (i > 0) {
|
|
s += ",";
|
|
}
|
|
s += tl::to_quoted_string(lef_files [i]);
|
|
}
|
|
s += ";";
|
|
}
|
|
s += "import-mode=" + tl::to_string(mode) + ";";
|
|
return s;
|
|
}
|
|
|
|
// -----------------------------------------------------------------------------------------------
|
|
// LEFDEF import options dialog
|
|
|
|
LEFDEFImportOptionsDialog::LEFDEFImportOptionsDialog (QWidget *parent, bool is_lef_dialog)
|
|
: QDialog (parent), m_is_lef_dialog (is_lef_dialog)
|
|
{
|
|
setupUi (this);
|
|
|
|
lef_files_frame->setVisible (! is_lef_dialog);
|
|
|
|
connect (browse_pb, SIGNAL (clicked ()), this, SLOT (browse_button_clicked ()));
|
|
connect (reader_options_pb, SIGNAL (clicked ()), this, SLOT (tech_setup_button_clicked ()));
|
|
connect (add_lef_file, SIGNAL (clicked ()), this, SLOT (add_lef_file_clicked ()));
|
|
connect (del_lef_files, SIGNAL (clicked ()), this, SLOT (del_lef_files_clicked ()));
|
|
connect (move_lef_files_up, SIGNAL (clicked ()), this, SLOT (move_lef_files_up_clicked ()));
|
|
connect (move_lef_files_down, SIGNAL (clicked ()), this, SLOT (move_lef_files_down_clicked ()));
|
|
|
|
lay::activate_help_links (help_label);
|
|
|
|
setWindowTitle (tl::to_qstring (m_is_lef_dialog ? tl::to_string (QObject::tr ("Import LEF File")) : tl::to_string (QObject::tr ("Import DEF File"))));
|
|
}
|
|
|
|
int
|
|
LEFDEFImportOptionsDialog::exec_dialog (LEFDEFImportData &data)
|
|
{
|
|
file_le->setText (tl::to_qstring (data.file));
|
|
|
|
for (std::vector <std::string>::const_iterator f = data.lef_files.begin (); f != data.lef_files.end (); ++f) {
|
|
lef_files->addItem (tl::to_qstring (*f));
|
|
}
|
|
for (int i = 0; i < lef_files->count (); ++i) {
|
|
lef_files->item (i)->setFlags (Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled);
|
|
}
|
|
|
|
replace_rb->setChecked (data.mode == 0);
|
|
import_same_panel_rb->setChecked (data.mode == 2);
|
|
import_new_panel_rb->setChecked (data.mode == 1);
|
|
|
|
int result = QDialog::exec ();
|
|
if (result) {
|
|
|
|
data.file = tl::to_string (file_le->text ());
|
|
|
|
data.lef_files.clear ();
|
|
data.lef_files.reserve (lef_files->count ());
|
|
for (int i = 0; i < lef_files->count (); ++i) {
|
|
data.lef_files.push_back (tl::to_string (lef_files->item (i)->text ()));
|
|
}
|
|
|
|
data.mode = 0;
|
|
if (import_same_panel_rb->isChecked ()) {
|
|
data.mode = 2;
|
|
} else if (import_new_panel_rb->isChecked ()) {
|
|
data.mode = 1;
|
|
}
|
|
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
void
|
|
LEFDEFImportOptionsDialog::add_lef_file_clicked ()
|
|
{
|
|
std::string title, filters;
|
|
title = tl::to_string (QObject::tr ("Add LEF Files"));
|
|
filters = tl::to_string (QObject::tr ("LEF files (*.lef *.LEF *.lef.gz *.LEF.gz);;All files (*)"));
|
|
QStringList files = QFileDialog::getOpenFileNames (this, tl::to_qstring (title), QString (), tl::to_qstring (filters));
|
|
for (QStringList::const_iterator f = files.begin (); f != files.end (); ++f) {
|
|
lef_files->addItem (*f);
|
|
}
|
|
for (int i = 0; i < lef_files->count (); ++i) {
|
|
lef_files->item (i)->setFlags (Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled);
|
|
}
|
|
}
|
|
|
|
void
|
|
LEFDEFImportOptionsDialog::del_lef_files_clicked ()
|
|
{
|
|
QStringList files;
|
|
for (int i = 0; i < lef_files->count (); ++i) {
|
|
if (! lef_files->item (i)->isSelected ()) {
|
|
files.push_back (lef_files->item (i)->text ());
|
|
}
|
|
}
|
|
|
|
lef_files->clear ();
|
|
for (QStringList::const_iterator f = files.begin (); f != files.end (); ++f) {
|
|
lef_files->addItem (*f);
|
|
}
|
|
for (int i = 0; i < lef_files->count (); ++i) {
|
|
lef_files->item (i)->setFlags (Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled);
|
|
}
|
|
}
|
|
|
|
void
|
|
LEFDEFImportOptionsDialog::move_lef_files_up_clicked ()
|
|
{
|
|
std::set<QString> selected;
|
|
for (int i = 0; i < lef_files->count (); ++i) {
|
|
if (lef_files->item (i)->isSelected ()) {
|
|
selected.insert (lef_files->item (i)->text ());
|
|
}
|
|
}
|
|
|
|
QStringList files;
|
|
int j = -1;
|
|
for (int i = 0; i < lef_files->count (); ++i) {
|
|
if (lef_files->item (i)->isSelected ()) {
|
|
files.push_back (lef_files->item (i)->text ());
|
|
} else {
|
|
if (j >= 0) {
|
|
files.push_back (lef_files->item (j)->text ());
|
|
}
|
|
j = i;
|
|
}
|
|
}
|
|
if (j >= 0) {
|
|
files.push_back (lef_files->item (j)->text ());
|
|
}
|
|
|
|
lef_files->clear ();
|
|
for (QStringList::const_iterator f = files.begin (); f != files.end (); ++f) {
|
|
lef_files->addItem (*f);
|
|
if (selected.find (*f) != selected.end ()) {
|
|
lef_files->item (lef_files->count () - 1)->setSelected (true);
|
|
}
|
|
}
|
|
for (int i = 0; i < lef_files->count (); ++i) {
|
|
lef_files->item (i)->setFlags (Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled);
|
|
}
|
|
}
|
|
|
|
void
|
|
LEFDEFImportOptionsDialog::move_lef_files_down_clicked ()
|
|
{
|
|
std::set<QString> selected;
|
|
for (int i = 0; i < lef_files->count (); ++i) {
|
|
if (lef_files->item (i)->isSelected ()) {
|
|
selected.insert (lef_files->item (i)->text ());
|
|
}
|
|
}
|
|
|
|
QStringList files;
|
|
int j = -1;
|
|
for (int i = lef_files->count (); i > 0; ) {
|
|
--i;
|
|
if (lef_files->item (i)->isSelected ()) {
|
|
files.push_back (lef_files->item (i)->text ());
|
|
} else {
|
|
if (j >= 0) {
|
|
files.push_back (lef_files->item (j)->text ());
|
|
}
|
|
j = i;
|
|
}
|
|
}
|
|
if (j >= 0) {
|
|
files.push_back (lef_files->item (j)->text ());
|
|
}
|
|
|
|
lef_files->clear ();
|
|
for (QStringList::const_iterator f = files.end (); f != files.begin (); ) {
|
|
--f;
|
|
lef_files->addItem (*f);
|
|
if (selected.find (*f) != selected.end ()) {
|
|
lef_files->item (lef_files->count () - 1)->setSelected (true);
|
|
}
|
|
}
|
|
for (int i = 0; i < lef_files->count (); ++i) {
|
|
lef_files->item (i)->setFlags (Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled);
|
|
}
|
|
}
|
|
|
|
void
|
|
LEFDEFImportOptionsDialog::browse_button_clicked ()
|
|
{
|
|
QString file = file_le->text ();
|
|
std::string title, filters;
|
|
if (m_is_lef_dialog) {
|
|
title = tl::to_string (QObject::tr ("Import LEF File"));
|
|
filters = tl::to_string (QObject::tr ("LEF files (*.lef *.LEF *.lef.gz *.LEF.gz);;All files (*)"));
|
|
} else {
|
|
title = tl::to_string (QObject::tr ("Import DEF File"));
|
|
filters = tl::to_string (QObject::tr ("DEF files (*.def *.DEF *.def.gz *.DEF.gz);;All files (*)"));
|
|
}
|
|
|
|
file = QFileDialog::getOpenFileName (this, tl::to_qstring (title), file, tl::to_qstring (filters));
|
|
if (! file.isNull ()) {
|
|
|
|
file_le->setText (file);
|
|
|
|
if (! m_is_lef_dialog) {
|
|
|
|
// Scan all LEF files near that DEF file
|
|
lef_files->clear ();
|
|
QDir dir = QFileInfo (file).absoluteDir ();
|
|
QStringList lef_file_filters;
|
|
lef_file_filters << QString::fromUtf8 ("*.lef") << QString::fromUtf8 ("*.LEF") << QString::fromUtf8 ("*.lef.gz") << QString::fromUtf8 ("*.LEF.gz");
|
|
QStringList lef_file_list = dir.entryList (lef_file_filters, QDir::Readable | QDir::Files);
|
|
for (QStringList::const_iterator f = lef_file_list.begin (); f != lef_file_list.end (); ++f) {
|
|
lef_files->addItem (*f);
|
|
}
|
|
for (int i = 0; i < lef_files->count (); ++i) {
|
|
lef_files->item (i)->setFlags (Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled);
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
void
|
|
LEFDEFImportOptionsDialog::tech_setup_button_clicked ()
|
|
{
|
|
BEGIN_PROTECTED
|
|
|
|
std::string tech_name;
|
|
tech_name = lay::MainWindow::instance ()->initial_technology ();
|
|
if (! db::Technologies::instance ()->has_technology (tech_name)) {
|
|
tech_name.clear (); // use default technology
|
|
}
|
|
|
|
db::Technology *tech = db::Technologies::instance ()->technology_by_name (tech_name);
|
|
if (!tech) {
|
|
return;
|
|
}
|
|
|
|
db::LoadLayoutOptions options = tech->load_layout_options ();
|
|
|
|
// calls the dialog and if successful, install the new options
|
|
lay::SpecificLoadLayoutOptionsDialog dialog (this, &options, "LEFDEF");
|
|
if (dialog.exec ()) {
|
|
tech->set_load_layout_options (options);
|
|
}
|
|
|
|
END_PROTECTED
|
|
}
|
|
|
|
// -----------------------------------------------------------------------------------------------
|
|
// LEFDEF technology components editor
|
|
|
|
LEFDEFReaderOptionsEditor::LEFDEFReaderOptionsEditor (QWidget *parent)
|
|
: lay::StreamReaderOptionsPage (parent), mp_tech (0)
|
|
{
|
|
setupUi (this);
|
|
|
|
connect (produce_net_names, SIGNAL (stateChanged (int)), this, SLOT (checkbox_changed ()));
|
|
connect (produce_inst_names, SIGNAL (stateChanged (int)), this, SLOT (checkbox_changed ()));
|
|
connect (produce_pin_names, SIGNAL (stateChanged (int)), this, SLOT (checkbox_changed ()));
|
|
connect (produce_outlines, SIGNAL (stateChanged (int)), this, SLOT (checkbox_changed ()));
|
|
connect (produce_placement_blockages, SIGNAL (stateChanged (int)), this, SLOT (checkbox_changed ()));
|
|
connect (produce_regions, SIGNAL (stateChanged (int)), this, SLOT (checkbox_changed ()));
|
|
connect (produce_via_geometry, SIGNAL (stateChanged (int)), this, SLOT (checkbox_changed ()));
|
|
connect (produce_pins, SIGNAL (stateChanged (int)), this, SLOT (checkbox_changed ()));
|
|
connect (produce_lef_pins, SIGNAL (stateChanged (int)), this, SLOT (checkbox_changed ()));
|
|
connect (produce_fills, SIGNAL (stateChanged (int)), this, SLOT (checkbox_changed ()));
|
|
connect (produce_obstructions, SIGNAL (stateChanged (int)), this, SLOT (checkbox_changed ()));
|
|
connect (produce_blockages, SIGNAL (stateChanged (int)), this, SLOT (checkbox_changed ()));
|
|
connect (produce_routing, SIGNAL (stateChanged (int)), this, SLOT (checkbox_changed ()));
|
|
connect (produce_special_routing, SIGNAL (stateChanged (int)), this, SLOT (checkbox_changed ()));
|
|
connect (produce_labels, SIGNAL (stateChanged (int)), this, SLOT (checkbox_changed ()));
|
|
connect (add_lef_file, SIGNAL (clicked ()), this, SLOT (add_lef_file_clicked ()));
|
|
connect (del_lef_files, SIGNAL (clicked ()), this, SLOT (del_lef_files_clicked ()));
|
|
connect (move_lef_files_up, SIGNAL (clicked ()), this, SLOT (move_lef_files_up_clicked ()));
|
|
connect (move_lef_files_down, SIGNAL (clicked ()), this, SLOT (move_lef_files_down_clicked ()));
|
|
connect (add_macro_layout_file, SIGNAL (clicked ()), this, SLOT (add_macro_layout_file_clicked ()));
|
|
connect (del_macro_layout_files, SIGNAL (clicked ()), this, SLOT (del_macro_layout_files_clicked ()));
|
|
connect (move_macro_layout_files_up, SIGNAL (clicked ()), this, SLOT (move_macro_layout_files_up_clicked ()));
|
|
connect (move_macro_layout_files_down, SIGNAL (clicked ()), this, SLOT (move_macro_layout_files_down_clicked ()));
|
|
connect (browse_mapfile, SIGNAL (clicked ()), this, SLOT (browse_mapfile_clicked ()));
|
|
|
|
lay::activate_help_links (help_label);
|
|
lay::activate_help_links (help_label2);
|
|
}
|
|
|
|
void
|
|
LEFDEFReaderOptionsEditor::commit (db::FormatSpecificReaderOptions *options, const db::Technology * /*tech*/)
|
|
{
|
|
db::LEFDEFReaderOptions *data = dynamic_cast<db::LEFDEFReaderOptions *> (options);
|
|
if (! data) {
|
|
return;
|
|
}
|
|
|
|
bool has_error = false;
|
|
|
|
data->set_read_all_layers (read_all_cbx->isChecked ());
|
|
data->set_layer_map (layer_map->get_layer_map ());
|
|
data->set_produce_net_names (produce_net_names->isChecked ());
|
|
data->set_produce_inst_names (produce_inst_names->isChecked ());
|
|
data->set_produce_pin_names (produce_pin_names->isChecked ());
|
|
|
|
double dbu_value = 0.0;
|
|
tl::from_string (tl::to_string (dbu->text ()), dbu_value);
|
|
if (dbu_value < 1e-7) {
|
|
throw tl::Exception (tl::to_string (tr ("Invalid database unit value (must be non-null and positive)")));
|
|
}
|
|
data->set_dbu (dbu_value);
|
|
|
|
// parse the net property name (may throw an exception)
|
|
try {
|
|
std::string np = tl::to_string (net_prop_name->text ());
|
|
tl::Extractor ex (np.c_str ());
|
|
tl::Variant v;
|
|
ex.read (v);
|
|
ex.expect_end ();
|
|
data->set_net_property_name (v);
|
|
indicate_error (net_prop_name, (tl::Exception *) 0);
|
|
} catch (tl::Exception &ex) {
|
|
indicate_error (net_prop_name, &ex);
|
|
has_error = true;
|
|
}
|
|
|
|
// parse the inst property name (may throw an exception)
|
|
try {
|
|
std::string np = tl::to_string (inst_prop_name->text ());
|
|
tl::Extractor ex (np.c_str ());
|
|
tl::Variant v;
|
|
ex.read (v);
|
|
ex.expect_end ();
|
|
data->set_inst_property_name (v);
|
|
indicate_error (inst_prop_name, (tl::Exception *) 0);
|
|
} catch (tl::Exception &ex) {
|
|
indicate_error (inst_prop_name, &ex);
|
|
has_error = true;
|
|
}
|
|
|
|
// parse the pin property name (may throw an exception)
|
|
try {
|
|
std::string np = tl::to_string (pin_prop_name->text ());
|
|
tl::Extractor ex (np.c_str ());
|
|
tl::Variant v;
|
|
ex.read (v);
|
|
ex.expect_end ();
|
|
data->set_pin_property_name (v);
|
|
indicate_error (pin_prop_name, (tl::Exception *) 0);
|
|
} catch (tl::Exception &ex) {
|
|
indicate_error (pin_prop_name, &ex);
|
|
has_error = true;
|
|
}
|
|
|
|
// check the outline layer spec
|
|
try {
|
|
db::LayerProperties lp;
|
|
std::string s = tl::to_string (outline_layer->text ());
|
|
tl::Extractor ex (s.c_str ());
|
|
lp.read (ex);
|
|
ex.expect_end ();
|
|
indicate_error (outline_layer, (tl::Exception *) 0);
|
|
} catch (tl::Exception &ex) {
|
|
indicate_error (outline_layer, &ex);
|
|
has_error = true;
|
|
}
|
|
|
|
// check the region layer spec
|
|
try {
|
|
db::LayerProperties lp;
|
|
std::string s = tl::to_string (region_layer->text ());
|
|
tl::Extractor ex (s.c_str ());
|
|
lp.read (ex);
|
|
ex.expect_end ();
|
|
indicate_error (region_layer, (tl::Exception *) 0);
|
|
} catch (tl::Exception &ex) {
|
|
indicate_error (region_layer, &ex);
|
|
has_error = true;
|
|
}
|
|
|
|
// check the blockage layer spec
|
|
try {
|
|
db::LayerProperties lp;
|
|
std::string s = tl::to_string (placement_blockage_layer->text ());
|
|
tl::Extractor ex (s.c_str ());
|
|
lp.read (ex);
|
|
ex.expect_end ();
|
|
indicate_error (placement_blockage_layer, (tl::Exception *) 0);
|
|
} catch (tl::Exception &ex) {
|
|
indicate_error (placement_blockage_layer, &ex);
|
|
has_error = true;
|
|
}
|
|
|
|
if (has_error) {
|
|
throw tl::Exception (tl::to_string (tr ("Some values are not correct - see highlighted entry fields")));
|
|
}
|
|
|
|
data->set_produce_cell_outlines (produce_outlines->isChecked ());
|
|
data->set_cell_outline_layer (tl::to_string (outline_layer->text ()));
|
|
data->set_produce_regions (produce_regions->isChecked ());
|
|
data->set_region_layer (tl::to_string (region_layer->text ()));
|
|
data->set_produce_placement_blockages (produce_placement_blockages->isChecked ());
|
|
data->set_placement_blockage_layer (tl::to_string (placement_blockage_layer->text ()));
|
|
data->set_produce_via_geometry (produce_via_geometry->isChecked ());
|
|
data->set_via_geometry_suffix_str (tl::to_string (suffix_via_geometry->text ()));
|
|
data->set_via_geometry_datatype_str (tl::to_string (datatype_via_geometry->text ()));
|
|
data->set_via_cellname_prefix (tl::to_string (prefix_via_cellname->text ()));
|
|
data->set_produce_pins (produce_pins->isChecked ());
|
|
data->set_pins_suffix_str (tl::to_string (suffix_pins->text ()));
|
|
data->set_pins_datatype_str (tl::to_string (datatype_pins->text ()));
|
|
data->set_produce_lef_pins (produce_lef_pins->isChecked ());
|
|
data->set_lef_pins_suffix_str (tl::to_string (suffix_lef_pins->text ()));
|
|
data->set_lef_pins_datatype_str (tl::to_string (datatype_lef_pins->text ()));
|
|
data->set_produce_fills (produce_fills->isChecked ());
|
|
data->set_fills_suffix_str (tl::to_string (suffix_fills->text ()));
|
|
data->set_fills_datatype_str (tl::to_string (datatype_fills->text ()));
|
|
data->set_produce_obstructions (produce_obstructions->isChecked ());
|
|
data->set_obstructions_suffix (tl::to_string (suffix_obstructions->text ()));
|
|
data->set_obstructions_datatype (datatype_obstructions->text ().toInt ());
|
|
data->set_produce_blockages (produce_blockages->isChecked ());
|
|
data->set_blockages_suffix (tl::to_string (suffix_blockages->text ()));
|
|
data->set_blockages_datatype (datatype_blockages->text ().toInt ());
|
|
data->set_produce_routing (produce_routing->isChecked ());
|
|
data->set_routing_suffix_str (tl::to_string (suffix_routing->text ()));
|
|
data->set_routing_datatype_str (tl::to_string (datatype_routing->text ()));
|
|
data->set_produce_special_routing (produce_special_routing->isChecked ());
|
|
data->set_special_routing_suffix_str (tl::to_string (suffix_special_routing->text ()));
|
|
data->set_special_routing_datatype_str (tl::to_string (datatype_special_routing->text ()));
|
|
data->set_produce_labels (produce_labels->isChecked ());
|
|
data->set_labels_suffix (tl::to_string (suffix_labels->text ()));
|
|
data->set_labels_datatype (datatype_labels->text ().toInt ());
|
|
data->set_produce_lef_labels (produce_lef_labels->isChecked ());
|
|
data->set_lef_labels_suffix (tl::to_string (suffix_lef_labels->text ()));
|
|
data->set_lef_labels_datatype (datatype_lef_labels->text ().toInt ());
|
|
data->set_separate_groups (separate_groups->isChecked ());
|
|
data->set_read_lef_with_def (read_lef_with_def->isChecked ());
|
|
data->set_map_file (tl::to_string (mapfile_path->text ()));
|
|
data->set_macro_resolution_mode (macro_resolution_mode->currentIndex ());
|
|
|
|
data->clear_lef_files ();
|
|
for (int i = 0; i < lef_files->count (); ++i) {
|
|
data->push_lef_file (tl::to_string (lef_files->item (i)->text ()));
|
|
}
|
|
|
|
data->clear_macro_layout_files ();
|
|
for (int i = 0; i < macro_layout_files->count (); ++i) {
|
|
data->push_macro_layout_file (tl::to_string (macro_layout_files->item (i)->text ()));
|
|
}
|
|
}
|
|
|
|
void
|
|
LEFDEFReaderOptionsEditor::setup (const db::FormatSpecificReaderOptions *options, const db::Technology *tech)
|
|
{
|
|
static db::LEFDEFReaderOptions empty;
|
|
const db::LEFDEFReaderOptions *data = dynamic_cast<const db::LEFDEFReaderOptions *> (options);
|
|
if (! data) {
|
|
data = ∅
|
|
}
|
|
|
|
// TODO: there should be a const weak ptr ...
|
|
mp_tech.reset (const_cast<db::Technology *> (tech));
|
|
|
|
dbu->setText (tl::to_qstring (tl::to_string (data->dbu ())));
|
|
read_all_cbx->setChecked (data->read_all_layers ());
|
|
layer_map->set_layer_map (data->layer_map ());
|
|
produce_net_names->setChecked (data->produce_net_names ());
|
|
net_prop_name->setText (tl::to_qstring (data->net_property_name ().to_parsable_string ()));
|
|
produce_inst_names->setChecked (data->produce_inst_names ());
|
|
inst_prop_name->setText (tl::to_qstring (data->inst_property_name ().to_parsable_string ()));
|
|
produce_pin_names->setChecked (data->produce_pin_names ());
|
|
pin_prop_name->setText (tl::to_qstring (data->pin_property_name ().to_parsable_string ()));
|
|
produce_outlines->setChecked (data->produce_cell_outlines ());
|
|
outline_layer->setText (tl::to_qstring (data->cell_outline_layer ()));
|
|
produce_regions->setChecked (data->produce_regions ());
|
|
region_layer->setText (tl::to_qstring (data->region_layer ()));
|
|
produce_placement_blockages->setChecked (data->produce_placement_blockages ());
|
|
placement_blockage_layer->setText (tl::to_qstring (data->placement_blockage_layer ()));
|
|
produce_via_geometry->setChecked (data->produce_via_geometry ());
|
|
suffix_via_geometry->setText (tl::to_qstring (data->via_geometry_suffix_str ()));
|
|
datatype_via_geometry->setText (tl::to_qstring (data->via_geometry_datatype_str ()));
|
|
prefix_via_cellname->setText (tl::to_qstring (data->via_cellname_prefix ()));
|
|
produce_pins->setChecked (data->produce_pins ());
|
|
suffix_pins->setText (tl::to_qstring (data->pins_suffix_str ()));
|
|
datatype_pins->setText (tl::to_qstring (data->pins_datatype_str ()));
|
|
produce_lef_pins->setChecked (data->produce_lef_pins ());
|
|
suffix_lef_pins->setText (tl::to_qstring (data->lef_pins_suffix_str ()));
|
|
datatype_lef_pins->setText (tl::to_qstring (data->lef_pins_datatype_str ()));
|
|
produce_fills->setChecked (data->produce_fills ());
|
|
suffix_fills->setText (tl::to_qstring (data->fills_suffix_str ()));
|
|
datatype_fills->setText (tl::to_qstring (data->fills_datatype_str ()));
|
|
produce_obstructions->setChecked (data->produce_obstructions ());
|
|
suffix_obstructions->setText (tl::to_qstring (data->obstructions_suffix ()));
|
|
datatype_obstructions->setText (QString::number (data->obstructions_datatype ()));
|
|
produce_blockages->setChecked (data->produce_blockages ());
|
|
suffix_blockages->setText (tl::to_qstring (data->blockages_suffix ()));
|
|
datatype_blockages->setText (QString::number (data->blockages_datatype ()));
|
|
produce_routing->setChecked (data->produce_routing ());
|
|
suffix_routing->setText (tl::to_qstring (data->routing_suffix_str ()));
|
|
datatype_routing->setText (tl::to_qstring (data->routing_datatype_str ()));
|
|
produce_special_routing->setChecked (data->produce_special_routing ());
|
|
suffix_special_routing->setText (tl::to_qstring (data->special_routing_suffix_str ()));
|
|
datatype_special_routing->setText (tl::to_qstring (data->special_routing_datatype_str ()));
|
|
produce_labels->setChecked (data->produce_labels ());
|
|
suffix_labels->setText (tl::to_qstring (data->labels_suffix ()));
|
|
datatype_labels->setText (QString::number (data->labels_datatype ()));
|
|
produce_lef_labels->setChecked (data->produce_lef_labels ());
|
|
suffix_lef_labels->setText (tl::to_qstring (data->lef_labels_suffix ()));
|
|
datatype_lef_labels->setText (QString::number (data->lef_labels_datatype ()));
|
|
separate_groups->setChecked (data->separate_groups ());
|
|
read_lef_with_def->setChecked (data->read_lef_with_def ());
|
|
mapfile_path->setText (tl::to_qstring (data->map_file ()));
|
|
layer_map_mode->setCurrentIndex (data->map_file ().empty () ? 1 : 0);
|
|
macro_resolution_mode->setCurrentIndex (data->macro_resolution_mode ());
|
|
|
|
checkbox_changed ();
|
|
|
|
lef_files->clear ();
|
|
for (std::vector <std::string>::const_iterator f = data->begin_lef_files (); f != data->end_lef_files (); ++f) {
|
|
if (mp_tech) {
|
|
lef_files->addItem (tl::to_qstring (mp_tech->correct_path (*f)));
|
|
} else {
|
|
lef_files->addItem (tl::to_qstring (*f));
|
|
}
|
|
}
|
|
for (int i = 0; i < lef_files->count (); ++i) {
|
|
lef_files->item (i)->setFlags (Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled);
|
|
}
|
|
|
|
macro_layout_files->clear ();
|
|
for (std::vector <std::string>::const_iterator f = data->begin_macro_layout_files (); f != data->end_macro_layout_files (); ++f) {
|
|
if (mp_tech) {
|
|
macro_layout_files->addItem (tl::to_qstring (mp_tech->correct_path (*f)));
|
|
} else {
|
|
macro_layout_files->addItem (tl::to_qstring (*f));
|
|
}
|
|
}
|
|
for (int i = 0; i < macro_layout_files->count (); ++i) {
|
|
macro_layout_files->item (i)->setFlags (Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled);
|
|
}
|
|
}
|
|
|
|
void
|
|
LEFDEFReaderOptionsEditor::checkbox_changed ()
|
|
{
|
|
net_prop_name->setEnabled (produce_net_names->isChecked ());
|
|
inst_prop_name->setEnabled (produce_inst_names->isChecked ());
|
|
pin_prop_name->setEnabled (produce_pin_names->isChecked ());
|
|
outline_layer->setEnabled (produce_outlines->isChecked ());
|
|
region_layer->setEnabled (produce_regions->isChecked ());
|
|
placement_blockage_layer->setEnabled (produce_placement_blockages->isChecked ());
|
|
suffix_via_geometry->setEnabled (produce_via_geometry->isChecked ());
|
|
suffix_pins->setEnabled (produce_pins->isChecked ());
|
|
suffix_lef_pins->setEnabled (produce_lef_pins->isChecked ());
|
|
suffix_fills->setEnabled (produce_fills->isChecked ());
|
|
suffix_obstructions->setEnabled (produce_obstructions->isChecked ());
|
|
suffix_blockages->setEnabled (produce_blockages->isChecked ());
|
|
suffix_routing->setEnabled (produce_routing->isChecked ());
|
|
suffix_special_routing->setEnabled (produce_special_routing->isChecked ());
|
|
suffix_labels->setEnabled (produce_labels->isChecked ());
|
|
datatype_via_geometry->setEnabled (produce_via_geometry->isChecked ());
|
|
datatype_pins->setEnabled (produce_pins->isChecked ());
|
|
datatype_lef_pins->setEnabled (produce_lef_pins->isChecked ());
|
|
datatype_fills->setEnabled (produce_fills->isChecked ());
|
|
datatype_obstructions->setEnabled (produce_obstructions->isChecked ());
|
|
datatype_blockages->setEnabled (produce_blockages->isChecked ());
|
|
datatype_routing->setEnabled (produce_routing->isChecked ());
|
|
datatype_special_routing->setEnabled (produce_special_routing->isChecked ());
|
|
datatype_labels->setEnabled (produce_labels->isChecked ());
|
|
}
|
|
|
|
void
|
|
LEFDEFReaderOptionsEditor::browse_mapfile_clicked ()
|
|
{
|
|
std::string title, filters;
|
|
title = tl::to_string (QObject::tr ("Select Layer Map File"));
|
|
filters = tl::to_string (QObject::tr ("LEF/DEF layer map files (*.map);;All files (*)"));
|
|
QString file = QFileDialog::getOpenFileName (this, tl::to_qstring (title), QString (), tl::to_qstring (filters));
|
|
if (! file.isNull ()) {
|
|
if (mp_tech) {
|
|
mapfile_path->setText (tl::to_qstring (mp_tech->correct_path (tl::to_string (file))));
|
|
} else {
|
|
mapfile_path->setText (file);
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
LEFDEFReaderOptionsEditor::add_lef_file_clicked ()
|
|
{
|
|
std::string title, filters;
|
|
title = tl::to_string (QObject::tr ("Add LEF Files"));
|
|
filters = tl::to_string (QObject::tr ("LEF files (*.lef *.LEF *.lef.gz *.LEF.gz);;All files (*)"));
|
|
|
|
std::string dir;
|
|
if (mp_tech) {
|
|
dir = mp_tech->base_path ();
|
|
}
|
|
|
|
QStringList files = QFileDialog::getOpenFileNames (this, tl::to_qstring (title), tl::to_qstring (dir), tl::to_qstring (filters));
|
|
add_files (lef_files, files, mp_tech.get ());
|
|
}
|
|
|
|
void
|
|
LEFDEFReaderOptionsEditor::del_lef_files_clicked ()
|
|
{
|
|
del_files (lef_files);
|
|
}
|
|
|
|
void
|
|
LEFDEFReaderOptionsEditor::move_lef_files_up_clicked ()
|
|
{
|
|
move_files_up (lef_files);
|
|
}
|
|
|
|
void
|
|
LEFDEFReaderOptionsEditor::move_lef_files_down_clicked ()
|
|
{
|
|
move_files_down (lef_files);
|
|
}
|
|
|
|
void
|
|
LEFDEFReaderOptionsEditor::add_macro_layout_file_clicked ()
|
|
{
|
|
std::string title, filters;
|
|
title = tl::to_string (QObject::tr ("Add Macro Layout Files"));
|
|
filters = lay::MainWindow::instance ()->all_layout_file_formats ();
|
|
|
|
std::string dir;
|
|
if (mp_tech) {
|
|
dir = mp_tech->base_path ();
|
|
}
|
|
|
|
QStringList files = QFileDialog::getOpenFileNames (this, tl::to_qstring (title), tl::to_qstring (dir), tl::to_qstring (filters));
|
|
add_files (macro_layout_files, files, mp_tech.get ());
|
|
}
|
|
|
|
void
|
|
LEFDEFReaderOptionsEditor::del_macro_layout_files_clicked ()
|
|
{
|
|
del_files (macro_layout_files);
|
|
}
|
|
|
|
void
|
|
LEFDEFReaderOptionsEditor::move_macro_layout_files_up_clicked ()
|
|
{
|
|
move_files_up (macro_layout_files);
|
|
}
|
|
|
|
void
|
|
LEFDEFReaderOptionsEditor::move_macro_layout_files_down_clicked ()
|
|
{
|
|
move_files_down (macro_layout_files);
|
|
}
|
|
|
|
void
|
|
LEFDEFReaderOptionsEditor::add_files (QListWidget *list, const QStringList &files, const db::Technology *tech)
|
|
{
|
|
for (QStringList::const_iterator f = files.begin (); f != files.end (); ++f) {
|
|
if (tech) {
|
|
list->addItem (tl::to_qstring (tech->correct_path (tl::to_string (*f))));
|
|
} else {
|
|
list->addItem (*f);
|
|
}
|
|
}
|
|
for (int i = 0; i < list->count (); ++i) {
|
|
list->item (i)->setFlags (Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled);
|
|
}
|
|
}
|
|
|
|
void
|
|
LEFDEFReaderOptionsEditor::del_files (QListWidget *list)
|
|
{
|
|
QStringList files;
|
|
for (int i = 0; i < list->count (); ++i) {
|
|
if (! list->item (i)->isSelected ()) {
|
|
files.push_back (list->item (i)->text ());
|
|
}
|
|
}
|
|
|
|
list->clear ();
|
|
for (QStringList::const_iterator f = files.begin (); f != files.end (); ++f) {
|
|
list->addItem (*f);
|
|
}
|
|
for (int i = 0; i < list->count (); ++i) {
|
|
list->item (i)->setFlags (Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled);
|
|
}
|
|
}
|
|
|
|
void
|
|
LEFDEFReaderOptionsEditor::move_files_up (QListWidget *list)
|
|
{
|
|
std::set<QString> selected;
|
|
for (int i = 0; i < list->count (); ++i) {
|
|
if (list->item (i)->isSelected ()) {
|
|
selected.insert (list->item (i)->text ());
|
|
}
|
|
}
|
|
|
|
QStringList files;
|
|
int j = -1;
|
|
for (int i = 0; i < list->count (); ++i) {
|
|
if (list->item (i)->isSelected ()) {
|
|
files.push_back (list->item (i)->text ());
|
|
} else {
|
|
if (j >= 0) {
|
|
files.push_back (list->item (j)->text ());
|
|
}
|
|
j = i;
|
|
}
|
|
}
|
|
if (j >= 0) {
|
|
files.push_back (list->item (j)->text ());
|
|
}
|
|
|
|
list->clear ();
|
|
for (QStringList::const_iterator f = files.begin (); f != files.end (); ++f) {
|
|
list->addItem (*f);
|
|
if (selected.find (*f) != selected.end ()) {
|
|
list->item (list->count () - 1)->setSelected (true);
|
|
}
|
|
}
|
|
for (int i = 0; i < list->count (); ++i) {
|
|
list->item (i)->setFlags (Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled);
|
|
}
|
|
}
|
|
|
|
void
|
|
LEFDEFReaderOptionsEditor::move_files_down (QListWidget *list)
|
|
{
|
|
std::set<QString> selected;
|
|
for (int i = 0; i < list->count (); ++i) {
|
|
if (list->item (i)->isSelected ()) {
|
|
selected.insert (list->item (i)->text ());
|
|
}
|
|
}
|
|
|
|
QStringList files;
|
|
int j = -1;
|
|
for (int i = list->count (); i > 0; ) {
|
|
--i;
|
|
if (list->item (i)->isSelected ()) {
|
|
files.push_back (list->item (i)->text ());
|
|
} else {
|
|
if (j >= 0) {
|
|
files.push_back (list->item (j)->text ());
|
|
}
|
|
j = i;
|
|
}
|
|
}
|
|
if (j >= 0) {
|
|
files.push_back (list->item (j)->text ());
|
|
}
|
|
|
|
list->clear ();
|
|
for (QStringList::const_iterator f = files.end (); f != files.begin (); ) {
|
|
--f;
|
|
list->addItem (*f);
|
|
if (selected.find (*f) != selected.end ()) {
|
|
list->item (list->count () - 1)->setSelected (true);
|
|
}
|
|
}
|
|
for (int i = 0; i < list->count (); ++i) {
|
|
list->item (i)->setFlags (Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled);
|
|
}
|
|
}
|
|
|
|
}
|