Introduction
GDSII is an industry standard for data exchange of integrated circuits (IC) layout artwork. It is a binary file format representing planar geometric shapes, text labels, and other information about the layout in hierarchical form. The manual can be found in here. The parser consists of three parts, reader, writer and database for full chip parsing. GdsParser::GdsReader provides API to read GDSII files (.gds or .gds.gz with Boost and Zlib support). GdsParser::GdsWriter provides API to write GDSII files (.gds or .gds.gz with Boost and Zlib support). These two parts are basic functionalities for read and write in GDSII format. GdsParser::GdsDB is a database to store layout elements and provides easy API to read, write and flatten full layouts.
Examples
Stream Reader
See documented version: test/parsers/gdsii/test_reader.cpp
#include <iostream>
using std::cout;
using std::endl;
{
{
cout << "constructing AsciiDataBase" << endl;
}
virtual void bit_array_cbk(
const char* ascii_record_type,
const char* ascii_data_type, vector<int>
const& vBitArray)
{
cout << __func__ << endl;
this->
general_cbk(ascii_record_type, ascii_data_type, vBitArray);
}
virtual void integer_2_cbk(
const char* ascii_record_type,
const char* ascii_data_type, vector<int>
const& vInteger)
{
cout << __func__ << endl;
this->
general_cbk(ascii_record_type, ascii_data_type, vInteger);
}
virtual void integer_4_cbk(
const char* ascii_record_type,
const char* ascii_data_type, vector<int>
const& vInteger)
{
cout << __func__ << endl;
this->
general_cbk(ascii_record_type, ascii_data_type, vInteger);
}
virtual void real_4_cbk(
const char* ascii_record_type,
const char* ascii_data_type, vector<double>
const& vFloat)
{
cout << __func__ << endl;
this->
general_cbk(ascii_record_type, ascii_data_type, vFloat);
}
virtual void real_8_cbk(
const char* ascii_record_type,
const char* ascii_data_type, vector<double>
const& vFloat)
{
cout << __func__ << endl;
this->
general_cbk(ascii_record_type, ascii_data_type, vFloat);
}
virtual void string_cbk(
const char* ascii_record_type,
const char* ascii_data_type,
string const& str)
{
cout << __func__ << endl;
this->
general_cbk(ascii_record_type, ascii_data_type, str);
}
{
cout << __func__ << endl;
this->
general_cbk(ascii_record_type,
"", vector<int>(0));
}
template <typename ContainerType>
void general_cbk(
string const& ascii_record_type,
string const& ascii_data_type, ContainerType
const& data)
{
cout << "ascii_record_type: " << ascii_record_type << endl
<< "ascii_data_type: " << ascii_data_type << endl
<< "data size: " << data.size() << endl;
if (ascii_record_type == "UNITS")
{
}
else if (ascii_record_type == "BOUNDARY")
{
}
else if (ascii_record_type == "LAYER")
{
}
else if (ascii_record_type == "XY")
{
cout << data.size() << endl;
}
else if (ascii_record_type == "ENDEL")
{
}
}
};
{
{
cout << "constructing EnumDataBase" << endl;
}
{
cout << __func__ << endl;
}
{
cout << __func__ << endl;
}
{
cout << __func__ << endl;
}
{
cout << __func__ << endl;
}
{
cout << __func__ << endl;
}
{
cout << __func__ << endl;
}
{
cout << __func__ << endl;
this->
general_cbk(record_type, GdsParser::GdsData::NO_DATA, vector<int>(0));
}
template <typename ContainerType>
{
<< "data size: " << data.size() << endl;
switch (record_type)
{
case GdsParser::GdsRecords::UNITS:
break;
case GdsParser::GdsRecords::BOUNDARY:
break;
case GdsParser::GdsRecords::LAYER:
cout << "LAYER = " << data[0] << endl;
break;
case GdsParser::GdsRecords::XY:
for (typename ContainerType::const_iterator it = data.begin(); it != data.end(); ++it)
cout << *it << " ";
cout << endl;
cout << data.size() << endl;
break;
case GdsParser::GdsRecords::ENDEL:
break;
default:
break;
}
}
};
int main(
int argc,
char** argv)
{
if (argc > 1)
{
}
else cout << "at least 1 argument is required" << endl;
return 0;
}
Compiling and running commands (assuming LIMBO_DIR is exported as the environment variable to the path where limbo library is installed)
1 g++ -o test_reader test_reader.cpp -I $LIMBO_DIR/include -L $LIMBO_DIR/lib -lgdsparser
3 ./test_reader benchmarks/test_reader.gds
If BOOST_DIR and ZLIB_DIR have been defined as environment variables when building Limbo library, one can compile with support to compression files.
1 g++ -o test_reader test_reader.cpp -I $LIMBO_DIR/include -L $LIMBO_DIR/lib -lgdsparser -L $BOOST_DIR/lib -lboost_iostreams -L $ZLIB_DIR -lz
2 # read a compressed file
3 ./test_reader benchmarks/test_reader_gz.gds.gz
Stream Writer
See documented version: test/parsers/gdsii/test_writer.cpp
#include <vector>
int main(
int argc,
char *argv[] )
{
int
x[5],
y[5];
if (argc < 2)
{
printf("need a output file name\n");
return 1;
}
gw.create_lib("dogs", 0.001, 1.0e-9);
gw.gds_write_bgnstr( );
gw.gds_write_strname( "hotdogs" );
gw.gds_write_boundary( );
gw.gds_write_layer( 10001 );
gw.gds_write_datatype( 0 );
x[0] = 0; y[0] = 0;
x[1] = 0; y[1] = 500;
x[2] = 1000; y[2] = 500;
x[3] = 1000; y[3] = 0;
x[4] = 0; y[4] = 0;
gw.gds_write_xy( x, y, 5 );
gw.gds_write_endel( );
std::vector<int> vx(4);
std::vector<int> vy(4);
vx[0] = 0; vy[0] = 0;
vx[1] = 0; vy[1] = 500;
vx[2] = 1000; vy[2] = 500;
vx[3] = 1000; vy[3] = 0;
gw.write_boundary(10002, 0, vx, vy, false);
for (int i = 0; i < 1; ++i)
gw.write_box(10003, 0, 10, 10, 20, 20);
gw.gds_write_text( );
gw.gds_write_layer( 1 );
gw.gds_write_texttype( 0 );
gw.gds_write_presentation( 0, 1, 1 );
gw.gds_write_width( 500 );
gw.gds_write_strans( 1, 0, 0 );
x[0] = 2000;
y[0] = 2000;
gw.gds_write_xy( x, y, 1 );
gw.gds_write_string( "reflected" );
gw.gds_write_endel( );
gw.gds_create_text( "not reflected", 2000, 1500, 2, 500 );
gw.gds_write_path( );
gw.gds_write_layer( 3 );
gw.gds_write_datatype( 4 );
gw.gds_write_pathtype( 2 );
gw.gds_write_width( 200 );
x[0] = 2000; y[0] = 3000;
x[1] = 2000; y[1] = 4000;
x[2] = 2500; y[2] = 3500;
gw.gds_write_xy( x, y, 3 );
gw.gds_write_endel( );
gw.gds_write_box( );
gw.gds_write_layer( 6 );
gw.gds_write_boxtype( 12 );
x[0] = 3000; y[0] = 0;
x[1] = 3000; y[1] = 500;
x[2] = 4000; y[2] = 500;
x[3] = 4000; y[3] = 0;
x[4] = 3000; y[4] = 0;
gw.gds_write_xy( x, y, 5 );
gw.gds_write_endel( );
gw.gds_write_endstr( );
gw.gds_write_bgnstr( );
gw.gds_write_strname( "sausage" );
gw.gds_write_sref( );
gw.gds_write_sname( "hotdogs" );
gw.gds_write_mag( 5.0 );
gw.gds_write_angle( 15.4 );
x[0] = 2000;
y[0] = -2000;
gw.gds_write_xy( x, y, 1 );
gw.gds_write_endel( );
gw.gds_write_endstr( );
gw.gds_write_bgnstr( );
gw.gds_write_strname( "meatball" );
gw.gds_write_aref( );
gw.gds_write_sname( "sausage" );
gw.gds_write_colrow( 2, 5 );
x[0] = 5000; y[0] = 5000;
x[1] = 85000; y[1] = 5000;
x[2] = 5000; y[2] = 205000;
gw.gds_write_xy( x, y, 3 );
gw.gds_write_endel( );
gw.gds_write_endstr( );
gw.gds_write_endlib( );
printf( "\nDone. Look at %s\n\n", argv[1] );
return 0;
}
Compiling and running commands (assuming LIMBO_DIR is exported as the environment variable to the path where limbo library is installed)
1 g++ -o test_writer test_writer.cpp -I $LIMBO_DIR/include -L $LIMBO_DIR/lib -lgdsparser
3 ./test_writer test_writer.gds
If BOOST_DIR and ZLIB_DIR have been defined as environment variables when building Limbo library, one can compile with support to compression files.
1 g++ -o test_writer test_writer.cpp -I $LIMBO_DIR/include -L $LIMBO_DIR/lib -lgdsparser -L $BOOST_DIR/lib -lboost_iostreams -L $ZLIB_DIR -lz
2 # write to a compressed file
3 ./test_writer test_writer_gz.gds.gz
Stream GDSII Database
See documented version: test/parsers/gdsii/test_gdsdb.cpp
#include <iostream>
int main(
int argc,
char** argv)
{
if (argc > 2 && argc <= 4)
{
for (std::vector<GdsParser::GdsDB::GdsCell>::const_iterator it = db.
cells().begin(); it != db.
cells().end(); ++it)
std::cout << "cell: " << it->name() << std::endl;
gw(argv[2]);
std::cout << "4 arguments to test flatten: input gds, output gds, flat output gds, flat cell name" << std::endl;
}
else if (argc > 4)
{
flatGw(argv[3]);
}
else std::cout << "at least 4 arguments are required: input gds, output gds, flat output gds, flat cell name" << std::endl;
return 0;
}
Compiling and running commands (assuming LIMBO_DIR is exported as the environment variable to the path where limbo library is installed)
1 g++ -o test_gdsdb test_gdsdb.cpp -I $LIMBO_DIR/include -I $BOOST_DIR/include -L $LIMBO_DIR/lib -lgdsparser -lgdsdb
2 # read a file and test flatten
3 ./test_gdsdb benchmarks/test_reader.gds test_gdsdb.gds test_gdsdb_flat.gds TOPCELL
If BOOST_DIR and ZLIB_DIR have been defined as environment variables when building Limbo library, one can compile with support to compression files.
1 g++ -o test_gdsdb test_gdsdb.cpp -I $LIMBO_DIR/include -I $BOOST_DIR/include -L $LIMBO_DIR/lib -lgdsparser -lgdsdb -L $BOOST_DIR/lib -lboost_iostreams -L $ZLIB_DIR -lz
2 # read a compressed file and test flatten
3 ./test_gdsdb benchmarks/test_reader_gz.gds.gz test_gdsdb_gz.gds.gz test_gdsdb_gz_flat.gds.gz TOPCELL
All Examples
References