mirror of https://github.com/KLayout/klayout.git
Implemented LEF MACRO FOREIGN
This commit is contained in:
parent
d93ef3ff97
commit
9825245e0c
|
|
@ -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
|
void
|
||||||
DEFImporter::read_polygon (db::Polygon &poly, double scale)
|
DEFImporter::read_polygon (db::Polygon &poly, double scale)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,6 @@ private:
|
||||||
std::map<std::string, ViaDesc> m_via_desc;
|
std::map<std::string, ViaDesc> m_via_desc;
|
||||||
std::map<int, db::Polygon> m_styles;
|
std::map<int, db::Polygon> m_styles;
|
||||||
|
|
||||||
db::FTrans get_orient (bool optional);
|
|
||||||
void read_polygon (db::Polygon &poly, double scale);
|
void read_polygon (db::Polygon &poly, double scale);
|
||||||
void read_rect (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);
|
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_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 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);
|
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);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -705,6 +705,24 @@ protected:
|
||||||
*/
|
*/
|
||||||
long get_long ();
|
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
|
* @brief Create a new layer or return the index of the given layer
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -742,10 +742,8 @@ LEFImporter::read_macro (Layout &layout)
|
||||||
|
|
||||||
} else if (test ("ORIGIN")) {
|
} else if (test ("ORIGIN")) {
|
||||||
|
|
||||||
double x = get_double ();
|
origin = get_point (1.0 / layout.dbu ());
|
||||||
double y = get_double ();
|
|
||||||
expect (";");
|
expect (";");
|
||||||
origin = db::Point (db::DPoint (x / layout.dbu (), y / layout.dbu ()));
|
|
||||||
|
|
||||||
} else if (test ("SIZE")) {
|
} else if (test ("SIZE")) {
|
||||||
|
|
||||||
|
|
@ -761,11 +759,16 @@ LEFImporter::read_macro (Layout &layout)
|
||||||
std::string dir;
|
std::string dir;
|
||||||
|
|
||||||
while (! at_end ()) {
|
while (! at_end ()) {
|
||||||
|
|
||||||
if (test ("END")) {
|
if (test ("END")) {
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
} else if (test ("DIRECTION")) {
|
} else if (test ("DIRECTION")) {
|
||||||
|
|
||||||
dir = get ();
|
dir = get ();
|
||||||
test (";");
|
test (";");
|
||||||
|
|
||||||
} else if (test ("PORT")) {
|
} else if (test ("PORT")) {
|
||||||
|
|
||||||
// produce pin labels
|
// produce pin labels
|
||||||
|
|
@ -806,6 +809,35 @@ LEFImporter::read_macro (Layout &layout)
|
||||||
|
|
||||||
expect (pn);
|
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")) {
|
} else if (test ("OBS")) {
|
||||||
|
|
||||||
read_geometries (layout, cell, Obstructions);
|
read_geometries (layout, cell, Obstructions);
|
||||||
|
|
|
||||||
|
|
@ -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)
|
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::LEFDEFReaderState ld (&tc);
|
||||||
|
|
||||||
db::Manager m (false);
|
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:")) {
|
if (ex.test ("def:")) {
|
||||||
|
|
||||||
std::string fn (priv ? tl::testsrc_private () : tl::testsrc ());
|
std::string fn = fn_path, f;
|
||||||
fn += "/testdata/lefdef/";
|
|
||||||
fn += lef_dir;
|
|
||||||
fn += "/";
|
|
||||||
std::string f;
|
|
||||||
ex.read_word_or_quoted (f);
|
ex.read_word_or_quoted (f);
|
||||||
fn += 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:")) {
|
} else if (ex.test ("lef:")) {
|
||||||
|
|
||||||
std::string fn (priv ? tl::testsrc_private () : tl::testsrc ());
|
std::string fn = fn_path, f;
|
||||||
fn += "/testdata/lefdef/";
|
|
||||||
fn += lef_dir;
|
|
||||||
fn += "/";
|
|
||||||
std::string f;
|
|
||||||
ex.read_word_or_quoted (f);
|
ex.read_word_or_quoted (f);
|
||||||
fn += f;
|
fn += f;
|
||||||
|
|
||||||
tl::InputStream stream (fn);
|
tl::InputStream stream (fn);
|
||||||
imp.read_lef (stream, layout, ld);
|
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 {
|
} else {
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
@ -305,3 +312,7 @@ TEST(108_scanchain)
|
||||||
run_test (_this, "scanchain", "def:test.def", "au.oas.gz", default_options (), false);
|
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);
|
||||||
|
}
|
||||||
|
|
|
||||||
Binary file not shown.
Binary file not shown.
|
|
@ -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
|
||||||
|
|
||||||
|
|
@ -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
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
MACRO dummy
|
MACRO dummy
|
||||||
CLASS CORE ;
|
CLASS CORE ;
|
||||||
FOREIGN dummy 0.000 0.000 ;
|
|
||||||
ORIGIN 0.000 0.000 ;
|
ORIGIN 0.000 0.000 ;
|
||||||
SIZE 0.384 BY 0.480 ;
|
SIZE 0.384 BY 0.480 ;
|
||||||
SYMMETRY X Y ;
|
SYMMETRY X Y ;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue