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 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
|
||||
|
|
@ -138,22 +138,22 @@ public:
|
|||
* @brief Reads a set of string components and parameters from the string
|
||||
* 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)
|
||||
*/
|
||||
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)
|
||||
*/
|
||||
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:
|
||||
double read_atomic_value (tl::Extractor &ex);
|
||||
double read_dot_expr (tl::Extractor &ex);
|
||||
double read_bar_expr (tl::Extractor &ex);
|
||||
static double read_atomic_value (tl::Extractor &ex, const std::map<std::string, double> &variables);
|
||||
static double read_dot_expr (tl::Extractor &ex, const std::map<std::string, double> &variables);
|
||||
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);
|
||||
|
||||
private:
|
||||
|
||||
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 ();
|
||||
friend class SpiceReaderDict;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2456,7 +2456,7 @@ class NetlistSpiceReaderDelegateImpl
|
|||
{
|
||||
public:
|
||||
NetlistSpiceReaderDelegateImpl ()
|
||||
: db::NetlistSpiceReaderDelegate ()
|
||||
: db::NetlistSpiceReaderDelegate (), mp_variables (0)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
|
@ -2566,15 +2566,16 @@ public:
|
|||
ParseElementData parse_element_helper (const std::string &s, const std::string &element)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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 {
|
||||
|
||||
m_error.clear ();
|
||||
mp_variables = &variables;
|
||||
|
||||
ParseElementData data;
|
||||
if (cb_parse_element.can_issue ()) {
|
||||
|
|
@ -2588,12 +2589,18 @@ public:
|
|||
nn = data.net_names ();
|
||||
pv = data.parameters ();
|
||||
|
||||
mp_variables = 0;
|
||||
|
||||
} catch (tl::Exception &) {
|
||||
mp_variables = 0;
|
||||
if (! m_error.empty ()) {
|
||||
db::NetlistSpiceReaderDelegate::error (m_error);
|
||||
} else {
|
||||
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_finish;
|
||||
gsi::Callback cb_control_statement;
|
||||
|
|
@ -2626,6 +2639,7 @@ public:
|
|||
|
||||
private:
|
||||
std::string m_error;
|
||||
const std::map<std::string, double> *mp_variables;
|
||||
};
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
double v = 0.0;
|
||||
if (delegate->try_read_value (s, v)) {
|
||||
if (db::NetlistSpiceReaderDelegate::try_read_value (s, v, variables)) {
|
||||
res = v;
|
||||
}
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
@ -2765,6 +2779,13 @@ Class<NetlistSpiceReaderDelegateImpl> db_NetlistSpiceReaderDelegate ("db", "Netl
|
|||
"\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::arg ("s"), gsi::arg ("element"),
|
||||
"@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"
|
||||
"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"
|
||||
"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 "
|
||||
"'(1+3)*2' is translated into 8.0.\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"
|
||||
"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). "
|
||||
"It returns data \\ParseElementComponentsData object with the strings and parameters.\n"
|
||||
"The parameter names are already translated to upper case.\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"
|
||||
"Supply a customized class to provide a specialized reading scheme for devices. "
|
||||
|
|
|
|||
Loading…
Reference in New Issue