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)
: mp_delegate (delegate), m_strict (false)
{
static NetlistSpiceReaderDelegate std_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 <string>
#include <memory>
namespace db
{
@ -64,6 +65,7 @@ public:
private:
tl::weak_ptr<NetlistSpiceReaderDelegate> mp_delegate;
std::unique_ptr<NetlistSpiceReaderDelegate> mp_default_delegate;
bool m_strict;
};

View File

@ -99,7 +99,7 @@ NetlistSpiceReaderOptions::NetlistSpiceReaderOptions ()
// ------------------------------------------------------------------------------------------------------
NetlistSpiceReaderDelegate::NetlistSpiceReaderDelegate ()
: mp_netlist (0)
: mp_netlist (0), m_options ()
{
// .. nothing yet ..
}
@ -109,6 +109,22 @@ NetlistSpiceReaderDelegate::~NetlistSpiceReaderDelegate ()
// .. 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*/)
{
// .. nothing yet ..
@ -609,12 +625,27 @@ bool NetlistSpiceReaderDelegate::element (db::Circuit *circuit, const std::strin
} else {
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;
}
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
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
*/
NetlistSpiceReaderOptions &options ()
const NetlistSpiceReaderOptions &options () const
{
return m_options;
}
/**
* @brief Gets the reader options
* @brief Gets the reader options (non-const)
*/
const NetlistSpiceReaderOptions &options () const
NetlistSpiceReaderOptions &options ()
{
return m_options;
}
@ -162,26 +162,22 @@ public:
/**
* @brief External interface for start
*/
void do_start ()
{
start (mp_netlist);
}
void do_start ();
/**
* @brief External interface for finish
*/
void do_finish ()
{
finish (mp_netlist);
}
void do_finish ();
/**
* @brief Sets the netlist
*/
void set_netlist (db::Netlist *netlist)
{
mp_netlist = netlist;
}
void set_netlist (db::Netlist *netlist);
/**
* @brief Applies SI and geometry scaling to the device parameters
*/
void apply_parameter_scaling (db::Device *device) const;
private:
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"
);
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",
gsi::method_ext ("start", &start_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"
"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 (), "{}"),
"@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 "