mirror of https://github.com/KLayout/klayout.git
WIP
This commit is contained in:
parent
432b542f3c
commit
40fd350d85
File diff suppressed because it is too large
Load Diff
|
|
@ -127,7 +127,7 @@ public:
|
||||||
* @param nn Out parameter: the net names
|
* @param nn Out parameter: the net names
|
||||||
* @param pv Out parameter: the parameter values (key/value pairs)
|
* @param pv Out parameter: the parameter values (key/value pairs)
|
||||||
*/
|
*/
|
||||||
virtual void parse_element (const std::string &s, const std::string &element, std::string &model, double &value, std::vector<std::string> &nn, std::map<std::string, double> &pv);
|
virtual void parse_element (const std::string &s, const std::string &element, std::string &model, double &value, std::vector<std::string> &nn, std::map<std::string, double> &pv, const std::map<std::string, double> ¶ms);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Produces an error with the given message
|
* @brief Produces an error with the given message
|
||||||
|
|
@ -138,22 +138,22 @@ public:
|
||||||
* @brief Reads a set of string components and parameters from the string
|
* @brief Reads a set of string components and parameters from the string
|
||||||
* A special key "param:" is recognized for starting a parameter list.
|
* A special key "param:" is recognized for starting a parameter list.
|
||||||
*/
|
*/
|
||||||
void parse_element_components (const std::string &s, std::vector<std::string> &strings, std::map<std::string, double> &pv);
|
static void parse_element_components (const std::string &s, std::vector<std::string> &strings, std::map<std::string, double> &pv, const std::map<std::string, double> &variables);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Reads a value from the extractor (with formula evaluation)
|
* @brief Reads a value from the extractor (with formula evaluation)
|
||||||
*/
|
*/
|
||||||
double read_value (tl::Extractor &ex);
|
static double read_value (tl::Extractor &ex, const std::map<std::string, double> &variables);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Tries to read a value from the extractor (with formula evaluation)
|
* @brief Tries to read a value from the extractor (with formula evaluation)
|
||||||
*/
|
*/
|
||||||
bool try_read_value (const std::string &s, double &v);
|
static bool try_read_value (const std::string &s, double &v, const std::map<std::string, double> &variables);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
double read_atomic_value (tl::Extractor &ex);
|
static double read_atomic_value (tl::Extractor &ex, const std::map<std::string, double> &variables);
|
||||||
double read_dot_expr (tl::Extractor &ex);
|
static double read_dot_expr (tl::Extractor &ex, const std::map<std::string, double> &variables);
|
||||||
double read_bar_expr (tl::Extractor &ex);
|
static double read_bar_expr (tl::Extractor &ex, const std::map<std::string, double> &variables);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -169,70 +169,7 @@ public:
|
||||||
virtual void read (tl::InputStream &stream, db::Netlist &netlist);
|
virtual void read (tl::InputStream &stream, db::Netlist &netlist);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
friend class SpiceReaderDict;
|
||||||
class SpiceReaderStream
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
SpiceReaderStream ();
|
|
||||||
~SpiceReaderStream ();
|
|
||||||
|
|
||||||
void set_stream (tl::InputStream &stream);
|
|
||||||
void set_stream (tl::InputStream *stream);
|
|
||||||
void close ();
|
|
||||||
|
|
||||||
std::pair<std::string, bool> get_line();
|
|
||||||
int line_number () const;
|
|
||||||
std::string source () const;
|
|
||||||
bool at_end () const;
|
|
||||||
|
|
||||||
void swap (SpiceReaderStream &other)
|
|
||||||
{
|
|
||||||
std::swap (mp_stream, other.mp_stream);
|
|
||||||
std::swap (m_owns_stream, other.m_owns_stream);
|
|
||||||
std::swap (mp_text_stream, other.mp_text_stream);
|
|
||||||
std::swap (m_line_number, other.m_line_number);
|
|
||||||
std::swap (m_stored_line, other.m_stored_line);
|
|
||||||
std::swap (m_has_stored_line, other.m_has_stored_line);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
tl::InputStream *mp_stream;
|
|
||||||
bool m_owns_stream;
|
|
||||||
tl::TextInputStream *mp_text_stream;
|
|
||||||
int m_line_number;
|
|
||||||
std::string m_stored_line;
|
|
||||||
bool m_has_stored_line;
|
|
||||||
};
|
|
||||||
|
|
||||||
db::Netlist *mp_netlist;
|
|
||||||
db::Circuit *mp_circuit;
|
|
||||||
db::Circuit *mp_anonymous_top_circuit;
|
|
||||||
tl::weak_ptr<NetlistSpiceReaderDelegate> mp_delegate;
|
|
||||||
std::list<SpiceReaderStream> m_streams;
|
|
||||||
SpiceReaderStream m_stream;
|
|
||||||
std::unique_ptr<std::map<std::string, db::Net *> > mp_nets_by_name;
|
|
||||||
std::map<std::string, bool> m_captured;
|
|
||||||
std::vector<std::string> m_global_nets;
|
|
||||||
std::set<std::string> m_global_net_names;
|
|
||||||
std::set<const db::Circuit *> m_circuits_read;
|
|
||||||
|
|
||||||
void push_stream (const std::string &path);
|
|
||||||
void pop_stream ();
|
|
||||||
bool at_end ();
|
|
||||||
bool read_element (tl::Extractor &ex, const std::string &element, const std::string &name);
|
|
||||||
void read_subcircuit (const std::string &sc_name, const std::string &nc_name, const std::vector<db::Net *> &nets);
|
|
||||||
void read_circuit (tl::Extractor &ex, const std::string &name);
|
|
||||||
void skip_circuit (tl::Extractor &ex);
|
|
||||||
bool read_card ();
|
|
||||||
std::string read_name (tl::Extractor &ex);
|
|
||||||
std::string get_line ();
|
|
||||||
void error (const std::string &msg);
|
|
||||||
void warn (const std::string &msg);
|
|
||||||
void finish ();
|
|
||||||
db::Net *make_net (const std::string &name);
|
|
||||||
void ensure_circuit ();
|
|
||||||
bool subcircuit_captured (const std::string &nc_name);
|
|
||||||
void build_global_nets ();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2456,7 +2456,7 @@ class NetlistSpiceReaderDelegateImpl
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NetlistSpiceReaderDelegateImpl ()
|
NetlistSpiceReaderDelegateImpl ()
|
||||||
: db::NetlistSpiceReaderDelegate ()
|
: db::NetlistSpiceReaderDelegate (), mp_variables (0)
|
||||||
{
|
{
|
||||||
// .. nothing yet ..
|
// .. nothing yet ..
|
||||||
}
|
}
|
||||||
|
|
@ -2566,15 +2566,16 @@ public:
|
||||||
ParseElementData parse_element_helper (const std::string &s, const std::string &element)
|
ParseElementData parse_element_helper (const std::string &s, const std::string &element)
|
||||||
{
|
{
|
||||||
ParseElementData data;
|
ParseElementData data;
|
||||||
db::NetlistSpiceReaderDelegate::parse_element (s, element, data.model_name_nc (), data.value_nc (), data.net_names_nc (), data.parameters_nc ());
|
db::NetlistSpiceReaderDelegate::parse_element (s, element, data.model_name_nc (), data.value_nc (), data.net_names_nc (), data.parameters_nc (), variables ());
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void parse_element (const std::string &s, const std::string &element, std::string &model, double &value, std::vector<std::string> &nn, std::map<std::string, double> &pv)
|
virtual void parse_element (const std::string &s, const std::string &element, std::string &model, double &value, std::vector<std::string> &nn, std::map<std::string, double> &pv, const std::map<std::string, double> &variables)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
|
||||||
m_error.clear ();
|
m_error.clear ();
|
||||||
|
mp_variables = &variables;
|
||||||
|
|
||||||
ParseElementData data;
|
ParseElementData data;
|
||||||
if (cb_parse_element.can_issue ()) {
|
if (cb_parse_element.can_issue ()) {
|
||||||
|
|
@ -2588,12 +2589,18 @@ public:
|
||||||
nn = data.net_names ();
|
nn = data.net_names ();
|
||||||
pv = data.parameters ();
|
pv = data.parameters ();
|
||||||
|
|
||||||
|
mp_variables = 0;
|
||||||
|
|
||||||
} catch (tl::Exception &) {
|
} catch (tl::Exception &) {
|
||||||
|
mp_variables = 0;
|
||||||
if (! m_error.empty ()) {
|
if (! m_error.empty ()) {
|
||||||
db::NetlistSpiceReaderDelegate::error (m_error);
|
db::NetlistSpiceReaderDelegate::error (m_error);
|
||||||
} else {
|
} else {
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
} catch (...) {
|
||||||
|
mp_variables = 0;
|
||||||
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2616,6 +2623,12 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::map<std::string, double> &variables () const
|
||||||
|
{
|
||||||
|
static std::map<std::string, double> empty;
|
||||||
|
return mp_variables ? *mp_variables : empty;
|
||||||
|
}
|
||||||
|
|
||||||
gsi::Callback cb_start;
|
gsi::Callback cb_start;
|
||||||
gsi::Callback cb_finish;
|
gsi::Callback cb_finish;
|
||||||
gsi::Callback cb_control_statement;
|
gsi::Callback cb_control_statement;
|
||||||
|
|
@ -2626,6 +2639,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string m_error;
|
std::string m_error;
|
||||||
|
const std::map<std::string, double> *mp_variables;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void start_fb (NetlistSpiceReaderDelegateImpl *delegate, db::Netlist *netlist)
|
static void start_fb (NetlistSpiceReaderDelegateImpl *delegate, db::Netlist *netlist)
|
||||||
|
|
@ -2663,20 +2677,20 @@ static ParseElementData parse_element_fb (NetlistSpiceReaderDelegateImpl *delega
|
||||||
return delegate->parse_element_helper (s, element);
|
return delegate->parse_element_helper (s, element);
|
||||||
}
|
}
|
||||||
|
|
||||||
static tl::Variant value_from_string (NetlistSpiceReaderDelegateImpl *delegate, const std::string &s)
|
static tl::Variant value_from_string (NetlistSpiceReaderDelegateImpl * /*delegate*/, const std::string &s, const std::map<std::string, double> &variables)
|
||||||
{
|
{
|
||||||
tl::Variant res;
|
tl::Variant res;
|
||||||
double v = 0.0;
|
double v = 0.0;
|
||||||
if (delegate->try_read_value (s, v)) {
|
if (db::NetlistSpiceReaderDelegate::try_read_value (s, v, variables)) {
|
||||||
res = v;
|
res = v;
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ParseElementComponentsData parse_element_components (NetlistSpiceReaderDelegateImpl *delegate, const std::string &s)
|
static ParseElementComponentsData parse_element_components (NetlistSpiceReaderDelegateImpl * /*delegate*/, const std::string &s, const std::map<std::string, double> &variables)
|
||||||
{
|
{
|
||||||
ParseElementComponentsData data;
|
ParseElementComponentsData data;
|
||||||
delegate->parse_element_components (s, data.strings_nc (), data.parameters_nc ());
|
db::NetlistSpiceReaderDelegate::parse_element_components (s, data.strings_nc (), data.parameters_nc (), variables);
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2765,6 +2779,13 @@ Class<NetlistSpiceReaderDelegateImpl> db_NetlistSpiceReaderDelegate ("db", "Netl
|
||||||
"\n"
|
"\n"
|
||||||
"This method has been introduced in version 0.27.1\n"
|
"This method has been introduced in version 0.27.1\n"
|
||||||
) +
|
) +
|
||||||
|
gsi::method ("variables", &NetlistSpiceReaderDelegateImpl::variables,
|
||||||
|
"@brief Gets the variables defined inside the SPICE file during execution of 'parse_element'\n"
|
||||||
|
"In order to evaluate formulas, this method allows accessing the variables that are "
|
||||||
|
"present during the execution of the SPICE reader.\n"
|
||||||
|
"\n"
|
||||||
|
"This method has been introduced in version 0.28.7."
|
||||||
|
) +
|
||||||
gsi::callback ("parse_element", &NetlistSpiceReaderDelegateImpl::parse_element_helper, &NetlistSpiceReaderDelegateImpl::cb_parse_element,
|
gsi::callback ("parse_element", &NetlistSpiceReaderDelegateImpl::parse_element_helper, &NetlistSpiceReaderDelegateImpl::cb_parse_element,
|
||||||
gsi::arg ("s"), gsi::arg ("element"),
|
gsi::arg ("s"), gsi::arg ("element"),
|
||||||
"@brief Parses an element card\n"
|
"@brief Parses an element card\n"
|
||||||
|
|
@ -2800,22 +2821,26 @@ Class<NetlistSpiceReaderDelegateImpl> db_NetlistSpiceReaderDelegate ("db", "Netl
|
||||||
"@brief Issues an error with the given message.\n"
|
"@brief Issues an error with the given message.\n"
|
||||||
"Use this method to generate an error."
|
"Use this method to generate an error."
|
||||||
) +
|
) +
|
||||||
gsi::method_ext ("value_from_string", &value_from_string, gsi::arg ("s"),
|
gsi::method_ext ("value_from_string", &value_from_string, gsi::arg ("s"), gsi::arg ("variables", std::map<std::string, double> (), "{}"),
|
||||||
"@brief Translates a string into a value\n"
|
"@brief Translates a string into a value\n"
|
||||||
"This function simplifies the implementation of SPICE readers by providing a translation of a unit-annotated string "
|
"This function simplifies the implementation of SPICE readers by providing a translation of a unit-annotated string "
|
||||||
"into double values. For example, '1k' is translated to 1000.0. In addition, simple formula evaluation is supported, e.g "
|
"into double values. For example, '1k' is translated to 1000.0. In addition, simple formula evaluation is supported, e.g "
|
||||||
"'(1+3)*2' is translated into 8.0.\n"
|
"'(1+3)*2' is translated into 8.0.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"This method has been introduced in version 0.27.1\n"
|
"The variables dictionary defines named variables with the given values.\n"
|
||||||
|
"\n"
|
||||||
|
"This method has been introduced in version 0.27.1. The variables argument has been added in version 0.28.7.\n"
|
||||||
) +
|
) +
|
||||||
gsi::method_ext ("parse_element_components", &parse_element_components, gsi::arg ("s"),
|
gsi::method_ext ("parse_element_components", &parse_element_components, gsi::arg ("s"), gsi::arg ("variables", std::map<std::string, double> (), "{}"),
|
||||||
"@brief Parses a string into string and parameter components.\n"
|
"@brief Parses a string into string and parameter components.\n"
|
||||||
"This method is provided to simplify the implementation of 'parse_element'. It takes a string and splits it into "
|
"This method is provided to simplify the implementation of 'parse_element'. It takes a string and splits it into "
|
||||||
"string arguments and parameter values. For example, 'a b c=6' renders two string arguments in 'nn' and one parameter ('C'->6.0). "
|
"string arguments and parameter values. For example, 'a b c=6' renders two string arguments in 'nn' and one parameter ('C'->6.0). "
|
||||||
"It returns data \\ParseElementComponentsData object with the strings and parameters.\n"
|
"It returns data \\ParseElementComponentsData object with the strings and parameters.\n"
|
||||||
"The parameter names are already translated to upper case.\n"
|
"The parameter names are already translated to upper case.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"This method has been introduced in version 0.27.1\n"
|
"The variables dictionary defines named variables with the given values.\n"
|
||||||
|
"\n"
|
||||||
|
"This method has been introduced in version 0.27.1. The variables argument has been added in version 0.28.7.\n"
|
||||||
),
|
),
|
||||||
"@brief Provides a delegate for the SPICE reader for translating device statements\n"
|
"@brief Provides a delegate for the SPICE reader for translating device statements\n"
|
||||||
"Supply a customized class to provide a specialized reading scheme for devices. "
|
"Supply a customized class to provide a specialized reading scheme for devices. "
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue