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
|
||||
DEFImporter::read_polygon (db::Polygon &poly, double scale)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 ();
|
||||
|
||||
/**
|
||||
* @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
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
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
|
||||
CLASS CORE ;
|
||||
FOREIGN dummy 0.000 0.000 ;
|
||||
ORIGIN 0.000 0.000 ;
|
||||
SIZE 0.384 BY 0.480 ;
|
||||
SYMMETRY X Y ;
|
||||
|
|
|
|||
Loading…
Reference in New Issue