Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/buddies/src/bd/bd.pro
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@ INCLUDEPATH += $$RBA_INC
DEPENDPATH += $$RBA_INC

equals(HAVE_RUBY, "1") {
LIBS += -lklayout_rba
INCLUDEPATH += $$DRC_INC $$LVS_INC
DEPENDPATH += $$DRC_INC $$LVS_INC
LIBS += -lklayout_rba -lklayout_drc -lklayout_lvs
} else {
LIBS += -lklayout_rbastub
}
Expand Down
8 changes: 5 additions & 3 deletions src/buddies/src/bd/strmclip.cc
Original file line number Diff line number Diff line change
Expand Up @@ -153,10 +153,10 @@ void clip (ClipData &data)
// write the layout

db::SaveLayoutOptions save_options;
save_options.set_format_from_filename (data.file_out);
std::string of = save_options.set_format_from_filename (data.file_out).second;
data.writer_options.configure (save_options, target_layout);

tl::OutputStream stream (data.file_out);
tl::OutputStream stream (of);
db::Writer writer (save_options);
writer.write (target_layout, stream);
}
Expand All @@ -176,7 +176,9 @@ BD_PUBLIC int strmclip (int argc, char *argv[])
<< tl::arg ("output", &data.file_out, "The output file",
"The output format is determined from the suffix of the file. If the suffix indicates "
"gzip compression, the file will be compressed on output. Examples for recognized suffixes are "
"\".oas\", \".gds.gz\", \".dxf\" or \".gds2\"."
"\".oas\", \".gds.gz\", \".dxf\" or \".gds2\". You can also use any name, and specify the "
"desired suffix in square brackets after the file name. For example, 'file.clip[oas]' will "
"create an OASIS file called 'file.clip'."
)
<< tl::arg ("-l|--clip-layer=spec", &data, &ClipData::set_clip_layer, "Specifies a layer to take the clip regions from",
"If this option is given, the clip rectangles are taken from the given layer."
Expand Down
2 changes: 2 additions & 0 deletions src/buddies/src/bd/strmrun.cc
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@
#include "libForceLink.h"
#include "rdbForceLink.h"
#include "pexForceLink.h"
#include "drcForceLink.h"
#include "lvsForceLink.h"
#include "lymMacro.h"
#include "lymMacroCollection.h"

Expand Down
8 changes: 5 additions & 3 deletions src/buddies/src/bd/strmxor.cc
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,9 @@ BD_PUBLIC int strmxor (int argc, char *argv[])
<< tl::arg ("?output", &output, "The output file to which the XOR differences are written",
"This argument is optional. If not given, the exit status alone will indicate whether the layouts "
"are identical or not. The output is a layout file. The format of the file is derived "
"from the file name's suffix (.oas[.gz] for (gzipped) OASIS, .gds[.gz] for (gzipped) GDS2 etc.)."
"from the file name's suffix (.oas for OASIS, .gds[.gz] for (gzipped) GDS2 etc.). "
"You can also use any name, and specify the desired suffix in square brackets after the file name. "
"For example, 'file.xor[oas]' will create an OASIS file called 'file.xor'."
)
<< tl::arg ("-ta|--top-a=name", &top_a, "Specifies the top cell for the first layout",
"Use this option to take a specific cell as the top cell from the first layout. All "
Expand Down Expand Up @@ -587,10 +589,10 @@ BD_PUBLIC int strmxor (int argc, char *argv[])
if (output_layout.get ()) {

db::SaveLayoutOptions save_options;
save_options.set_format_from_filename (output);
std::string of = save_options.set_format_from_filename (output).second;
writer_options.configure (save_options, *output_layout);

tl::OutputStream stream (output);
tl::OutputStream stream (of);
db::Writer writer (save_options);
writer.write (*output_layout, stream);

Expand Down
2 changes: 1 addition & 1 deletion src/buddies/src/buddy_app.pri
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ INCLUDEPATH += $$RBA_INC
DEPENDPATH += $$RBA_INC

equals(HAVE_RUBY, "1") {
LIBS += -lklayout_rba
LIBS += -lklayout_rba -lklayout_drc -lklayout_lvs
} else {
LIBS += -lklayout_rbastub
}
Expand Down
28 changes: 28 additions & 0 deletions src/buddies/unit_tests/bdConverterTests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,34 @@ TEST(7)
db::compare_layouts (this, layout, input, db::NoNormalization);
}

// Small DEF example with explicit format
TEST(8)
{
std::string input = tl::testdata ();
input += "/lefdef/strm2oas_small/in.defok[def]";

std::string input_au = tl::testdata ();
input_au += "/lefdef/strm2oas_small/au.gds";

std::string output = this->tmp_file ("small_def");

const char *argv[] = { "x", input.c_str (), output.c_str () };

EXPECT_EQ (bd::converter_main (sizeof (argv) / sizeof (argv[0]), (char **) argv, bd::GenericWriterOptions::oasis_format_name), 0);

db::Layout layout;

{
tl::InputStream stream (output);
db::LoadLayoutOptions options;
db::Reader reader (stream);
reader.read (layout, options);
EXPECT_EQ (reader.format (), "OASIS");
}

db::compare_layouts (this, layout, input_au, db::WriteGDS2);
}

// Large LEF/DEF to OAS converter test
TEST(10)
{
Expand Down
28 changes: 28 additions & 0 deletions src/buddies/unit_tests/bdStrmclipTests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,34 @@ TEST(2)
tl::InputStream stream (output);
db::Reader reader (stream);
reader.read (layout);
EXPECT_EQ (reader.format (), "GDS2");
}

db::compare_layouts (this, layout, au, db::NoNormalization);
}

// with explicit output format
TEST(3)
{
std::string input = tl::testdata ();
input += "/bd/strm2clip_in.gds";

std::string au = tl::testdata ();
au += "/bd/strm2clip_au2.gds";

std::string output = this->tmp_file () + "[oas]";

const char *argv[] = { "x", input.c_str (), output.c_str (), "-r=0,-2,9,5", "-t", "INV2", "-x=CLIP_OUT" };

EXPECT_EQ (strmclip (sizeof (argv) / sizeof (argv[0]), (char **) argv), 0);

db::Layout layout;

{
tl::InputStream stream (output);
db::Reader reader (stream);
reader.read (layout);
EXPECT_EQ (reader.format (), "OASIS");
}

db::compare_layouts (this, layout, au, db::NoNormalization);
Expand Down
44 changes: 32 additions & 12 deletions src/buddies/unit_tests/bdStrmrunTests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -28,30 +28,50 @@
TEST(1)
{
#if defined(HAVE_PYTHON)
std::string fp (tl::testsrc ());
fp += "/testdata/bd/strmrun.py";

std::string cmd;
std::string cmd_call;

#if defined(__APPLE__)
// NOTE: because of system integrity, MacOS does not inherit DYLD_LIBRARY_PATH to child
// processes like sh. We need to port this variable explicitly.
const char *ldpath_name = "DYLD_LIBRARY_PATH";
const char *ldpath = getenv (ldpath_name);
if (ldpath) {
cmd += std::string (ldpath_name) + "=\"" + ldpath + "\"; export " + ldpath_name + "; ";
cmd_call += std::string (ldpath_name) + "=\"" + ldpath + "\"; export " + ldpath_name + "; ";
}
#endif

cmd += tl::combine_path (tl::get_inst_path (), "strmrun ") + fp;
tl::info << cmd;
cmd_call += tl::combine_path (tl::get_inst_path (), "strmrun");

{
std::string fp (tl::testsrc ());
fp += "/testdata/bd/strmrun.py";

std::string cmd = cmd_call + " " + fp;
tl::info << cmd;

tl::InputPipe pipe (cmd);
tl::InputStream is (pipe);
std::string data = is.read_all ();
tl::info << data;

EXPECT_EQ (data, "Hello, world (0,-42;42,0)!\n");
}

{
std::string fp (tl::testsrc ());
fp += "/testdata/bd/strmrun.drc";

std::string cmd = cmd_call + " " + fp;
tl::info << cmd;

tl::InputPipe pipe (cmd);
tl::InputStream is (pipe);
std::string data = is.read_all ();
tl::info << data;
tl::InputPipe pipe (cmd);
tl::InputStream is (pipe);
std::string data = is.read_all ();
tl::info << data;

EXPECT_EQ (data, "This is DRC.\n");
}

EXPECT_EQ (data, "Hello, world (0,-42;42,0)!\n");
#endif
}

46 changes: 46 additions & 0 deletions src/buddies/unit_tests/bdStrmxorTests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,52 @@ TEST(1A_Flat)
tl::InputStream stream (output);
db::Reader reader (stream);
reader.read (layout);

EXPECT_EQ (std::string (reader.format ()), "OASIS");
}

db::compare_layouts (this, layout, au, db::NormalizationMode (db::NoNormalization | db::AsPolygons));
EXPECT_EQ (cap.captured_text (),
"Layer 10/0 is not present in first layout, but in second\n"
"Result summary (layers without differences are not shown):\n"
"\n"
" Layer Output Differences (shape count)\n"
" ----------------------------------------------------------------\n"
" 3/0 3/0 30\n"
" 6/0 6/0 41\n"
" 8/1 8/1 1\n"
" 10/0 - (no such layer in first layout)\n"
"\n"
);
}

TEST(1A_FlatWithExplicitOutputFormat)
{
tl::CaptureChannel cap;

std::string input_a = tl::testdata ();
input_a += "/bd/strmxor_in1.gds";

std::string input_b = tl::testdata ();
input_b += "/bd/strmxor_in2.gds";

std::string au = tl::testdata ();
au += "/bd/strmxor_au1.oas";

std::string output = this->tmp_file ("tmp.xxx[oas]");

const char *argv[] = { "x", input_a.c_str (), input_b.c_str (), output.c_str () };

EXPECT_EQ (strmxor (sizeof (argv) / sizeof (argv[0]), (char **) argv), 1);

db::Layout layout;

{
tl::InputStream stream (output);
db::Reader reader (stream);
reader.read (layout);

EXPECT_EQ (std::string (reader.format ()), "OASIS");
}

db::compare_layouts (this, layout, au, db::NormalizationMode (db::NoNormalization | db::AsPolygons));
Expand Down
1 change: 1 addition & 0 deletions src/db/db/db.pro
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ SOURCES = \
gsiDeclDbRecursiveInstanceIterator.cc \
gsiDeclDbRecursiveShapeIterator.cc \
gsiDeclDbRegion.cc \
gsiDeclDbSaveLayoutOptions.cc \
gsiDeclDbShape.cc \
gsiDeclDbShapeProcessor.cc \
gsiDeclDbShapes.cc \
Expand Down
3 changes: 1 addition & 2 deletions src/db/db/dbEdgePairs.cc
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,8 @@ EdgePairs::write (const std::string &fn) const
unsigned int li = layout.insert_layer (db::LayerProperties (0, 0));
insert_into (&layout, top.cell_index (), li);

tl::OutputStream os (fn);
db::SaveLayoutOptions opt;
opt.set_format_from_filename (fn);
tl::OutputStream os (opt.set_format_from_filename (fn).second);
db::Writer writer (opt);
writer.write (layout, os);
}
Expand Down
3 changes: 1 addition & 2 deletions src/db/db/dbEdges.cc
Original file line number Diff line number Diff line change
Expand Up @@ -145,9 +145,8 @@ Edges::write (const std::string &fn) const
unsigned int li = layout.insert_layer (db::LayerProperties (0, 0));
insert_into (&layout, top.cell_index (), li);

tl::OutputStream os (fn);
db::SaveLayoutOptions opt;
opt.set_format_from_filename (fn);
tl::OutputStream os (opt.set_format_from_filename (fn).second);
db::Writer writer (opt);
writer.write (layout, os);
}
Expand Down
23 changes: 18 additions & 5 deletions src/db/db/dbReader.cc
Original file line number Diff line number Diff line change
Expand Up @@ -134,13 +134,26 @@ ReaderBase::check_dbu (double dbu) const
Reader::Reader (tl::InputStream &stream)
: mp_actual_reader (0), m_stream (stream)
{
// Detect the format by asking all reader declarations
for (tl::Registrar<db::StreamFormatDeclaration>::iterator rdr = tl::Registrar<db::StreamFormatDeclaration>::begin (); rdr != tl::Registrar<db::StreamFormatDeclaration>::end () && ! mp_actual_reader; ++rdr) {
m_stream.reset ();
if (rdr->detect (m_stream)) {
if (stream.is_explicit_suffix ()) {

// If an explicit suffix is given for the stream, use it to find the reader
for (tl::Registrar<db::StreamFormatDeclaration>::iterator rdr = tl::Registrar<db::StreamFormatDeclaration>::begin (); rdr != tl::Registrar<db::StreamFormatDeclaration>::end () && ! mp_actual_reader; ++rdr) {
if (tl::match_filename_to_format ("." + stream.suffix (), rdr->file_format ())) {
mp_actual_reader = rdr->create_reader (m_stream);
}
}

} else {

// Detect the format by asking all reader declarations
for (tl::Registrar<db::StreamFormatDeclaration>::iterator rdr = tl::Registrar<db::StreamFormatDeclaration>::begin (); rdr != tl::Registrar<db::StreamFormatDeclaration>::end () && ! mp_actual_reader; ++rdr) {
m_stream.reset ();
mp_actual_reader = rdr->create_reader (m_stream);
if (rdr->detect (m_stream)) {
m_stream.reset ();
mp_actual_reader = rdr->create_reader (m_stream);
}
}

}

if (! mp_actual_reader) {
Expand Down
3 changes: 1 addition & 2 deletions src/db/db/dbRegion.cc
Original file line number Diff line number Diff line change
Expand Up @@ -142,9 +142,8 @@ Region::write (const std::string &fn) const
unsigned int li = layout.insert_layer (db::LayerProperties (0, 0));
insert_into (&layout, top.cell_index (), li);

tl::OutputStream os (fn);
db::SaveLayoutOptions opt;
opt.set_format_from_filename (fn);
tl::OutputStream os (opt.set_format_from_filename (fn).second);
db::Writer writer (opt);
writer.write (layout, os);
}
Expand Down
30 changes: 24 additions & 6 deletions src/db/db/dbSaveLayoutOptions.cc
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include "tlStream.h"
#include "tlExpression.h"
#include "tlInternational.h"
#include "tlGlobPattern.h"

namespace db
{
Expand Down Expand Up @@ -444,16 +445,33 @@ SaveLayoutOptions::get_cells (const db::Layout &layout, std::set <db::cell_index
}
}

bool
std::pair<bool, std::string>
SaveLayoutOptions::set_format_from_filename (const std::string &fn)
{
for (tl::Registrar<db::StreamFormatDeclaration>::iterator fmt = tl::Registrar<db::StreamFormatDeclaration>::begin (); fmt != tl::Registrar<db::StreamFormatDeclaration>::end (); ++fmt) {
if (tl::match_filename_to_format (fn, fmt->file_format ())) {
m_format = fmt->format_name ();
return true;
tl::GlobPattern pat ("(*)\\[(*)\\]");

std::vector<std::string> pat_parts;
if (pat.match (fn, pat_parts) && pat_parts.size () == 2) {

for (tl::Registrar<db::StreamFormatDeclaration>::iterator fmt = tl::Registrar<db::StreamFormatDeclaration>::begin (); fmt != tl::Registrar<db::StreamFormatDeclaration>::end (); ++fmt) {
if (tl::match_filename_to_format ("." + pat_parts[1], fmt->file_format ())) {
m_format = fmt->format_name ();
return std::make_pair (true, pat_parts[0]);
}
}

} else {

for (tl::Registrar<db::StreamFormatDeclaration>::iterator fmt = tl::Registrar<db::StreamFormatDeclaration>::begin (); fmt != tl::Registrar<db::StreamFormatDeclaration>::end (); ++fmt) {
if (tl::match_filename_to_format (fn, fmt->file_format ())) {
m_format = fmt->format_name ();
return std::make_pair (true, fn);
}
}

}
return false;

return std::make_pair (false, fn);
}

}
Expand Down
2 changes: 1 addition & 1 deletion src/db/db/dbSaveLayoutOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ class DB_PUBLIC SaveLayoutOptions
*
* Returns true, if the suffix indicates a known format.
*/
bool set_format_from_filename (const std::string &fn);
std::pair<bool, std::string> set_format_from_filename(const std::string &fn);

/**
* @brief Sets specific options for the given format
Expand Down
Loading
Loading