Implemented LEF MACRO FOREIGN

This commit is contained in:
Matthias Koefferlein 2020-04-19 12:16:55 +02:00
parent d93ef3ff97
commit 9825245e0c
11 changed files with 201 additions and 60 deletions

View File

@ -65,49 +65,6 @@ DEFImporter::read_lef (tl::InputStream &stream, db::Layout &layout, LEFDEFReader
}
db::FTrans
DEFImporter::get_orient (bool optional)
{
if (test ("N")) {
return db::FTrans (db::FTrans::r0);
} else if (test ("S")) {
return db::FTrans (db::FTrans::r180);
} else if (test ("W")) {
return db::FTrans (db::FTrans::r90);
} else if (test ("E")) {
return db::FTrans (db::FTrans::r270);
} else if (test ("FN")) {
return db::FTrans (db::FTrans::m90);
} else if (test ("FS")) {
return db::FTrans (db::FTrans::m0);
} else if (test ("FW")) {
return db::FTrans (db::FTrans::m45);
} else if (test ("FE")) {
return db::FTrans (db::FTrans::m135);
} else if (optional) {
return db::FTrans (db::FTrans::r0);
} else {
error (tl::to_string (tr ("Invalid orientation specification: ")) + get ());
return db::FTrans (db::FTrans::r0);
}
}
db::Point
DEFImporter::get_point (double scale)
{
double x = get_double ();
double y = get_double ();
return db::Point (db::DPoint (x * scale, y * scale));
}
db::Vector
DEFImporter::get_vector (double scale)
{
double x = get_double ();
double y = get_double ();
return db::Vector (db::DVector (x * scale, y * scale));
}
void
DEFImporter::read_polygon (db::Polygon &poly, double scale)
{

View File

@ -67,7 +67,6 @@ private:
std::map<std::string, ViaDesc> m_via_desc;
std::map<int, db::Polygon> m_styles;
db::FTrans get_orient (bool optional);
void read_polygon (db::Polygon &poly, double scale);
void read_rect (db::Polygon &poly, double scale);
std::pair<Coord, Coord> get_wire_width_for_rule(const std::string &rule, const std::string &ln, double dbu);
@ -84,8 +83,6 @@ private:
void read_components (std::list<std::pair<std::string, db::CellInstArray> > &instances, double scale);
void read_single_net (std::string &nondefaultrule, db::Layout &layout, db::Cell &design, double scale, properties_id_type prop_id, bool specialnets);
void produce_routing_geometry (db::Cell &design, const db::Polygon *style, unsigned int layer, properties_id_type prop_id, const std::vector<db::Point> &pts, const std::vector<std::pair<db::Coord, db::Coord> > &ext, std::pair<db::Coord, db::Coord> w);
db::Point get_point (double scale);
db::Vector get_vector (double scale);
};
}

View File

@ -830,5 +830,48 @@ LEFDEFImporter::create_generated_via (std::vector<db::Polygon> &bottom,
}
db::FTrans
LEFDEFImporter::get_orient (bool optional)
{
if (test ("N")) {
return db::FTrans (db::FTrans::r0);
} else if (test ("S")) {
return db::FTrans (db::FTrans::r180);
} else if (test ("W")) {
return db::FTrans (db::FTrans::r90);
} else if (test ("E")) {
return db::FTrans (db::FTrans::r270);
} else if (test ("FN")) {
return db::FTrans (db::FTrans::m90);
} else if (test ("FS")) {
return db::FTrans (db::FTrans::m0);
} else if (test ("FW")) {
return db::FTrans (db::FTrans::m45);
} else if (test ("FE")) {
return db::FTrans (db::FTrans::m135);
} else if (optional) {
return db::FTrans (db::FTrans::r0);
} else {
error (tl::to_string (tr ("Invalid orientation specification: ")) + get ());
return db::FTrans (db::FTrans::r0);
}
}
db::Point
LEFDEFImporter::get_point (double scale)
{
double x = get_double ();
double y = get_double ();
return db::Point (db::DPoint (x * scale, y * scale));
}
db::Vector
LEFDEFImporter::get_vector (double scale)
{
double x = get_double ();
double y = get_double ();
return db::Vector (db::DVector (x * scale, y * scale));
}
}

View File

@ -705,6 +705,24 @@ protected:
*/
long get_long ();
/**
* @brief Gets an orientation code
* The orientation code is read employing the LEF/DEF convention ("N" for r0 etc.)
*/
db::FTrans get_orient (bool optional);
/**
* @brief Reads a point
* A point is given by two coordinates, x and y
*/
db::Point get_point (double scale);
/**
* @brief Reads a vector
* A vector is given by two coordinates, x and y
*/
db::Vector get_vector (double scale);
/**
* @brief Create a new layer or return the index of the given layer
*/

View File

@ -742,10 +742,8 @@ LEFImporter::read_macro (Layout &layout)
} else if (test ("ORIGIN")) {
double x = get_double ();
double y = get_double ();
origin = get_point (1.0 / layout.dbu ());
expect (";");
origin = db::Point (db::DPoint (x / layout.dbu (), y / layout.dbu ()));
} else if (test ("SIZE")) {
@ -761,11 +759,16 @@ LEFImporter::read_macro (Layout &layout)
std::string dir;
while (! at_end ()) {
if (test ("END")) {
break;
} else if (test ("DIRECTION")) {
dir = get ();
test (";");
} else if (test ("PORT")) {
// produce pin labels
@ -806,6 +809,35 @@ LEFImporter::read_macro (Layout &layout)
expect (pn);
} else if (test ("FOREIGN")) {
std::string cn = get ();
if (cn == mn) {
// rename out macro placeholder cell so we don't create a recursive hierarchy
layout.rename_cell (cell.cell_index (), ("LEF_" + mn).c_str ());
}
db::cell_index_type ci;
std::pair<bool, db::cell_index_type> c = layout.cell_by_name (cn.c_str ());
if (c.first) {
ci = c.second;
} else {
ci = layout.add_cell (cn.c_str ());
layout.cell (ci).set_ghost_cell (true);
}
db::Point origin;
db::FTrans ft;
if (! peek (";")) {
origin = get_point (1.0 / layout.dbu ());
ft = get_orient (true);
}
expect (";");
cell.insert (db::CellInstArray (db::CellInst (ci), (db::Trans (origin - db::Point ()) * db::Trans (ft)).inverted ()));
} else if (test ("OBS")) {
read_geometries (layout, cell, Obstructions);

View File

@ -51,6 +51,11 @@ static db::LEFDEFReaderOptions default_options ()
static void run_test (tl::TestBase *_this, const char *lef_dir, const char *filename, const char *au, const db::LEFDEFReaderOptions &tc, bool priv = true)
{
std::string fn_path (priv ? tl::testsrc_private () : tl::testsrc ());
fn_path += "/testdata/lefdef/";
fn_path += lef_dir;
fn_path += "/";
db::LEFDEFReaderState ld (&tc);
db::Manager m (false);
@ -66,11 +71,7 @@ static void run_test (tl::TestBase *_this, const char *lef_dir, const char *file
if (ex.test ("def:")) {
std::string fn (priv ? tl::testsrc_private () : tl::testsrc ());
fn += "/testdata/lefdef/";
fn += lef_dir;
fn += "/";
std::string f;
std::string fn = fn_path, f;
ex.read_word_or_quoted (f);
fn += f;
@ -79,17 +80,23 @@ static void run_test (tl::TestBase *_this, const char *lef_dir, const char *file
} else if (ex.test ("lef:")) {
std::string fn (priv ? tl::testsrc_private () : tl::testsrc ());
fn += "/testdata/lefdef/";
fn += lef_dir;
fn += "/";
std::string f;
std::string fn = fn_path, f;
ex.read_word_or_quoted (f);
fn += f;
tl::InputStream stream (fn);
imp.read_lef (stream, layout, ld);
} else if (ex.test ("gds:")) {
std::string fn = fn_path, f;
ex.read_word_or_quoted (f);
fn += f;
tl::InputStream stream (fn);
db::Reader reader (stream);
reader.read (layout, db::LoadLayoutOptions ());
} else {
break;
@ -305,3 +312,7 @@ TEST(108_scanchain)
run_test (_this, "scanchain", "def:test.def", "au.oas.gz", default_options (), false);
}
TEST(109_foreigncell)
{
run_test (_this, "foreigncell", "gds:foreign.gds+lef:in_tech.lef+lef:in.lef", "au.oas.gz", default_options (), false);
}

BIN
testdata/lefdef/foreigncell/au.oas.gz vendored Normal file

Binary file not shown.

BIN
testdata/lefdef/foreigncell/foreign.gds vendored Normal file

Binary file not shown.

48
testdata/lefdef/foreigncell/in.lef vendored Normal file
View File

@ -0,0 +1,48 @@
MACRO macro1
CLASS CORE ;
FOREIGN foreign1 0.5 -0.2 W ;
ORIGIN 0.000 0.000 ;
SIZE 0.384 BY 0.480 ;
PIN Z
PORT
LAYER M1 ;
RECT 0.306 0.357 0.318 0.403 ;
RECT 0.318 0.115 0.352 0.403 ;
VIA 0.336 0.167 square ;
VIA 0.336 0.351 square ;
END
END Z
END macro1
MACRO macro2
CLASS CORE ;
FOREIGN foreign2 -0.15 0.25 ;
ORIGIN 0.000 0.000 ;
SIZE 0.384 BY 0.480 ;
PIN Z
PORT
LAYER M1 ;
RECT 0.306 0.357 0.318 0.403 ;
RECT 0.318 0.115 0.352 0.403 ;
VIA 0.336 0.167 square ;
VIA 0.336 0.351 square ;
END
END Z
END macro2
MACRO macro3
CLASS CORE ;
FOREIGN macro3 ;
ORIGIN 0.000 0.000 ;
SIZE 0.384 BY 0.480 ;
PIN Z
PORT
LAYER M1 ;
RECT 0.306 0.357 0.318 0.403 ;
RECT 0.318 0.115 0.352 0.403 ;
VIA 0.336 0.167 square ;
VIA 0.336 0.351 square ;
END
END Z
END macro3

36
testdata/lefdef/foreigncell/in_tech.lef vendored Normal file
View File

@ -0,0 +1,36 @@
LAYER OD
TYPE IMPLANT ;
END OD
LAYER VTS_N
TYPE IMPLANT ;
END VTS_N
LAYER VTS_P
TYPE IMPLANT ;
END VTS_P
LAYER M0OD
TYPE IMPLANT ;
END M0OD
LAYER M0PO
TYPE MASTERSLICE ;
END M0PO
LAYER VIA0
TYPE CUT ;
END VIA0
LAYER M1
TYPE MASTERSLICE ;
END M1
LAYER VIA1
TYPE CUT ;
END VIA1
LAYER M2
TYPE MASTERSLICE ;
END M2
VIA square
LAYER M0PO ;
RECT -0.006 -0.006 0.006 0.006 ;
LAYER VIA0 ;
RECT -0.006 -0.006 0.006 0.006 ;
LAYER M1 ;
RECT -0.006 -0.006 0.006 0.006 ;
END square

View File

@ -1,6 +1,5 @@
MACRO dummy
CLASS CORE ;
FOREIGN dummy 0.000 0.000 ;
ORIGIN 0.000 0.000 ;
SIZE 0.384 BY 0.480 ;
SYMMETRY X Y ;