Some refactoring of Spice reader with the goal to simplify delegate implementation, removing static instance of default delegate

This commit is contained in:
Matthias Koefferlein 2023-03-12 17:03:15 +01:00
parent db8f9d5bcb
commit 55dbf85b4b
5 changed files with 73 additions and 19 deletions

View File

@ -1203,9 +1203,9 @@ SpiceNetlistBuilder::build_global_nets ()
NetlistSpiceReader::NetlistSpiceReader (NetlistSpiceReaderDelegate *delegate) NetlistSpiceReader::NetlistSpiceReader (NetlistSpiceReaderDelegate *delegate)
: mp_delegate (delegate), m_strict (false) : mp_delegate (delegate), m_strict (false)
{ {
static NetlistSpiceReaderDelegate std_delegate;
if (! delegate) { if (! delegate) {
mp_delegate.reset (&std_delegate); mp_default_delegate.reset (new NetlistSpiceReaderDelegate ());
mp_delegate.reset (mp_default_delegate.get ());
} }
} }

View File

@ -32,6 +32,7 @@
#include <map> #include <map>
#include <string> #include <string>
#include <memory>
namespace db namespace db
{ {
@ -64,6 +65,7 @@ public:
private: private:
tl::weak_ptr<NetlistSpiceReaderDelegate> mp_delegate; tl::weak_ptr<NetlistSpiceReaderDelegate> mp_delegate;
std::unique_ptr<NetlistSpiceReaderDelegate> mp_default_delegate;
bool m_strict; bool m_strict;
}; };

View File

@ -99,7 +99,7 @@ NetlistSpiceReaderOptions::NetlistSpiceReaderOptions ()
// ------------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------------
NetlistSpiceReaderDelegate::NetlistSpiceReaderDelegate () NetlistSpiceReaderDelegate::NetlistSpiceReaderDelegate ()
: mp_netlist (0) : mp_netlist (0), m_options ()
{ {
// .. nothing yet .. // .. nothing yet ..
} }
@ -109,6 +109,22 @@ NetlistSpiceReaderDelegate::~NetlistSpiceReaderDelegate ()
// .. nothing yet .. // .. nothing yet ..
} }
void NetlistSpiceReaderDelegate::set_netlist (db::Netlist *netlist)
{
m_options = NetlistSpiceReaderOptions ();
mp_netlist = netlist;
}
void NetlistSpiceReaderDelegate::do_start ()
{
start (mp_netlist);
}
void NetlistSpiceReaderDelegate::do_finish ()
{
finish (mp_netlist);
}
void NetlistSpiceReaderDelegate::start (db::Netlist * /*netlist*/) void NetlistSpiceReaderDelegate::start (db::Netlist * /*netlist*/)
{ {
// .. nothing yet .. // .. nothing yet ..
@ -609,12 +625,27 @@ bool NetlistSpiceReaderDelegate::element (db::Circuit *circuit, const std::strin
} else { } else {
continue; continue;
} }
device->set_parameter_value (i->id (), pv / i->si_scaling () * pow (m_options.scale, i->geo_scaling_exponent ())); device->set_parameter_value (i->id (), pv);
} }
apply_parameter_scaling (device);
return true; return true;
} }
void
NetlistSpiceReaderDelegate::apply_parameter_scaling (db::Device *device) const
{
if (! device || ! device->device_class ()) {
return;
}
const std::vector<db::DeviceParameterDefinition> &pd = device->device_class ()->parameter_definitions ();
for (auto i = pd.begin (); i != pd.end (); ++i) {
double pv = device->parameter_value (i->id ());
device->set_parameter_value (i->id (), pv / i->si_scaling () * pow (m_options.scale, i->geo_scaling_exponent ()));
}
}
tl::Variant tl::Variant
NetlistSpiceReaderDelegate::read_value (tl::Extractor &ex, const std::map<std::string, tl::Variant> &variables) NetlistSpiceReaderDelegate::read_value (tl::Extractor &ex, const std::map<std::string, tl::Variant> &variables)
{ {

View File

@ -66,15 +66,15 @@ public:
/** /**
* @brief Gets the reader options * @brief Gets the reader options
*/ */
NetlistSpiceReaderOptions &options () const NetlistSpiceReaderOptions &options () const
{ {
return m_options; return m_options;
} }
/** /**
* @brief Gets the reader options * @brief Gets the reader options (non-const)
*/ */
const NetlistSpiceReaderOptions &options () const NetlistSpiceReaderOptions &options ()
{ {
return m_options; return m_options;
} }
@ -162,26 +162,22 @@ public:
/** /**
* @brief External interface for start * @brief External interface for start
*/ */
void do_start () void do_start ();
{
start (mp_netlist);
}
/** /**
* @brief External interface for finish * @brief External interface for finish
*/ */
void do_finish () void do_finish ();
{
finish (mp_netlist);
}
/** /**
* @brief Sets the netlist * @brief Sets the netlist
*/ */
void set_netlist (db::Netlist *netlist) void set_netlist (db::Netlist *netlist);
{
mp_netlist = netlist; /**
} * @brief Applies SI and geometry scaling to the device parameters
*/
void apply_parameter_scaling (db::Device *device) const;
private: private:
db::Netlist *mp_netlist; db::Netlist *mp_netlist;

View File

@ -2769,6 +2769,16 @@ Class<ParseElementData> db_ParseElementData ("db", "ParseElementData",
"This helper class has been introduced in version 0.27.1. Starting with version 0.28.6, named parameters can be string types too.\n" "This helper class has been introduced in version 0.27.1. Starting with version 0.28.6, named parameters can be string types too.\n"
); );
static double get_delegate_scale (const db::NetlistSpiceReaderDelegate *delegate)
{
return delegate->options ().scale;
}
static void apply_parameter_scaling (const db::NetlistSpiceReaderDelegate *delegate, db::Device *device)
{
delegate->apply_parameter_scaling (device);
}
Class<NetlistSpiceReaderDelegateImpl> db_NetlistSpiceReaderDelegate ("db", "NetlistSpiceReaderDelegate", Class<NetlistSpiceReaderDelegateImpl> db_NetlistSpiceReaderDelegate ("db", "NetlistSpiceReaderDelegate",
gsi::method_ext ("start", &start_fb, "@hide") + gsi::method_ext ("start", &start_fb, "@hide") +
gsi::method_ext ("finish", &finish_fb, "@hide") + gsi::method_ext ("finish", &finish_fb, "@hide") +
@ -2846,6 +2856,21 @@ 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 ("get_scale", &get_delegate_scale,
"@brief Gets the scale factor set with '.options scale=...'\n"
"This method has been introduced in version 0.28.6."
) +
gsi::method_ext ("apply_parameter_scaling", &apply_parameter_scaling, gsi::arg ("device"),
"@brief Applies parameter scaling to the given device\n"
"Applies SI scaling (according to the parameter's si_scaling attribute) and "
"geometry scaling (according to the parameter's geo_scale_exponent attribute) to "
"the device parameters. Use this method of finish the device when you have created "
"a custom device yourself.\n"
"\n"
"The geometry scale is taken from the '.options scale=...' control statement.\n"
"\n"
"This method has been introduced in version 0.28.6."
) +
gsi::method_ext ("value_from_string", &value_from_string, gsi::arg ("s"), gsi::arg ("variables", db::NetlistSpiceReader::parameters_type (), "{}"), gsi::method_ext ("value_from_string", &value_from_string, gsi::arg ("s"), gsi::arg ("variables", db::NetlistSpiceReader::parameters_type (), "{}"),
"@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 "