mirror of https://github.com/KLayout/klayout.git
Bug fixes
This commit is contained in:
parent
de052422d8
commit
36f147bcc1
|
|
@ -230,6 +230,7 @@ DeviceClass &DeviceClass::operator= (const DeviceClass &other)
|
|||
m_supports_serial_combination = other.m_supports_serial_combination;
|
||||
m_supports_parallel_combination = other.m_supports_parallel_combination;
|
||||
m_equivalent_terminal_ids = other.m_equivalent_terminal_ids;
|
||||
m_spice_profiles = other.m_spice_profiles;
|
||||
|
||||
}
|
||||
return *this;
|
||||
|
|
|
|||
|
|
@ -418,62 +418,6 @@ Class<NetlistSpiceReaderDelegateImpl> db_NetlistSpiceReaderDelegate ("db", "Netl
|
|||
gsi::method_ext ("parse_element", &parse_element_fb, "@hide") +
|
||||
gsi::method_ext ("control_statement", &control_statement_fb, "@hide") +
|
||||
gsi::method_ext ("translate_net_name", &translate_net_name_fb, "@hide") +
|
||||
gsi::method ("read_all_parameters", &NetlistSpiceReaderDelegateImpl::read_all_parameters,
|
||||
"@brief Gets a flag indicating whether to read all SPICE parameters\n"
|
||||
"\n"
|
||||
"With this flag set to false, unknown device parameters are ignored. Parameters are declared by the "
|
||||
"device classes present in the netlist, before the reader is used. SPICE profiles can be used to "
|
||||
"configure the parameters accepted by the SPICE reader, in addition to fixed and pre-defined parameters. "
|
||||
"With 'read_all_parameters' set to true, all parameters are read, even if they are not declared as fixed "
|
||||
"parameters by the device classes or as incoming parameters in their SPICE profiles.\n"
|
||||
"\n"
|
||||
"Note, that reimplementing \"element\" may change that behavior. Also, SPICE profiles can choose "
|
||||
"to capture all parameters through a wildcard specification, basically emulation this flag.\n"
|
||||
"\n"
|
||||
"This attribute has been introduced in version 0.31.0."
|
||||
) +
|
||||
gsi::method ("read_all_parameters=", &NetlistSpiceReaderDelegateImpl::set_read_all_parameters, gsi::arg ("f"),
|
||||
"@brief Sets a flag indicating whether to read all SPICE parameters\n"
|
||||
"See \\read_all_parameters for details about this attribute.\n"
|
||||
"\n"
|
||||
"This attribute has been introduced in version 0.31.0."
|
||||
) +
|
||||
gsi::method ("legacy_mode=", &NetlistSpiceReaderDelegateImpl::legacy_mode,
|
||||
"@brief Gets a flag indicating legacy mode\n"
|
||||
"\n"
|
||||
"This flag controls the parsing of SPICE lines in the default\n"
|
||||
"implementation of \"parse_element\". With this flag set to true (default),\n"
|
||||
"the elements are restricted to their original SPICE meaning, i.e. \"R\"\n"
|
||||
"can have two or three nets and a direct value. With this flag set to\n"
|
||||
"false, all elements can have any number of terminals, the last entry\n"
|
||||
"is the model and a direct value is not allowed. In non-legacy mode, all\n"
|
||||
"elements share the same notation and can be bound to devices through\n"
|
||||
"SPICE profiles without restrictions.\n"
|
||||
"\n"
|
||||
"@code\n"
|
||||
"* Allowed always:\n"
|
||||
"R A B MODEL R=1k\n"
|
||||
"\n"
|
||||
"* Allowed with legacy_mode=true (default):\n"
|
||||
"R A B 1k\n"
|
||||
"\n"
|
||||
"* Allowed with legacy_mode=false with a device class named 'MODEL' and\n"
|
||||
"* accepting 4 terminals for the 'R' element in its SPICE profile:\n"
|
||||
"R A B C D MODEL A=17.5 P=105\n"
|
||||
"@/code\n"
|
||||
"\n"
|
||||
"This flag allows configuring the SPICE reading without\n"
|
||||
"need for reimplementing a delegate. Note, that reimplementing\n"
|
||||
"\"parse_element\" may change that behavior.\n"
|
||||
"\n"
|
||||
"This attribute has been introduced in version 0.31.0."
|
||||
) +
|
||||
gsi::method ("legacy_mode=", &NetlistSpiceReaderDelegateImpl::set_legacy_mode, gsi::arg ("f"),
|
||||
"@brief Sets a flag indicating legacy mode\n"
|
||||
"See \\legacy_mode for details about this attribute.\n"
|
||||
"\n"
|
||||
"This attribute has been introduced in version 0.31.0."
|
||||
) +
|
||||
gsi::callback ("start", &NetlistSpiceReaderDelegateImpl::start, &NetlistSpiceReaderDelegateImpl::cb_start, gsi::arg ("netlist"),
|
||||
"@brief This method is called when the reader starts reading a netlist\n"
|
||||
) +
|
||||
|
|
@ -640,6 +584,18 @@ static void set_read_all_parameters (db::NetlistSpiceReader *reader, bool f)
|
|||
}
|
||||
}
|
||||
|
||||
static bool legacy_mode (const db::NetlistSpiceReader *reader)
|
||||
{
|
||||
return reader->delegate () ? reader->delegate ()->legacy_mode () : false;
|
||||
}
|
||||
|
||||
static void set_legacy_mode (db::NetlistSpiceReader *reader, bool f)
|
||||
{
|
||||
if (reader->delegate ()) {
|
||||
reader->delegate ()->set_legacy_mode (f);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Class<db::NetlistSpiceReader> db_NetlistSpiceReader (db_NetlistReader, "db", "NetlistSpiceReader",
|
||||
gsi::constructor ("new", &new_spice_reader, gsi::arg ("profile", std::string ()),
|
||||
|
|
@ -657,20 +613,58 @@ Class<db::NetlistSpiceReader> db_NetlistSpiceReader (db_NetlistReader, "db", "Ne
|
|||
"The profile string argument has been added in version 0.31.0."
|
||||
) +
|
||||
gsi::method_ext ("read_all_parameters", &read_all_parameters,
|
||||
"@brief Gets a flag indicating whether all parameters shall be read\n"
|
||||
"@brief Gets a flag indicating whether to read all SPICE parameters\n"
|
||||
"\n"
|
||||
"With this flag set to false, only those parameters which\n"
|
||||
"are declared in the device classes of the netlist are read.\n"
|
||||
"If set to true (the default), additional parameters are added to the device classes\n"
|
||||
"and their values are stored in the device objects.\n"
|
||||
"Note that this behavior can be changed in reimplementations of the\n"
|
||||
"SPICE reader delegate class.\n"
|
||||
"With this flag set to false, unknown device parameters are ignored. Parameters are declared by the "
|
||||
"device classes present in the netlist, before the reader is used. SPICE profiles can be used to "
|
||||
"configure the parameters accepted by the SPICE reader, in addition to fixed and pre-defined parameters. "
|
||||
"With 'read_all_parameters' set to true, all parameters are read, even if they are not declared as fixed "
|
||||
"parameters by the device classes or as incoming parameters in their SPICE profiles.\n"
|
||||
"\n"
|
||||
"Note, that reimplementing \"element\" may change that behavior. Also, SPICE profiles can choose "
|
||||
"to capture all parameters through a wildcard specification, basically emulation this flag.\n"
|
||||
"\n"
|
||||
"This attribute has been introduced in version 0.31.0."
|
||||
) +
|
||||
gsi::method_ext ("read_all_parameters=", &set_read_all_parameters, gsi::arg ("f"),
|
||||
"@brief Sets a flag indicating whether all parameters shall be read\n"
|
||||
"See \\read_all_parameters for details.\n"
|
||||
"@brief Sets a flag indicating whether to read all SPICE parameters\n"
|
||||
"See \\read_all_parameters for details about this attribute.\n"
|
||||
"\n"
|
||||
"This attribute has been introduced in version 0.31.0."
|
||||
) +
|
||||
gsi::method_ext ("legacy_mode=", &legacy_mode,
|
||||
"@brief Gets a flag indicating legacy mode\n"
|
||||
"\n"
|
||||
"This flag controls the parsing of SPICE lines in the default\n"
|
||||
"implementation of \"parse_element\". With this flag set to true (default),\n"
|
||||
"the elements are restricted to their original SPICE meaning, i.e. \"R\"\n"
|
||||
"can have two or three nets and a direct value. With this flag set to\n"
|
||||
"false, all elements can have any number of terminals, the last entry\n"
|
||||
"is the model and a direct value is not allowed. In non-legacy mode, all\n"
|
||||
"elements share the same notation and can be bound to devices through\n"
|
||||
"SPICE profiles without restrictions.\n"
|
||||
"\n"
|
||||
"@code\n"
|
||||
"* Allowed always:\n"
|
||||
"R A B MODEL R=1k\n"
|
||||
"\n"
|
||||
"* Allowed with legacy_mode=true (default):\n"
|
||||
"R A B 1k\n"
|
||||
"\n"
|
||||
"* Allowed with legacy_mode=false with a device class named 'MODEL' and\n"
|
||||
"* accepting 4 terminals for the 'R' element in its SPICE profile:\n"
|
||||
"R A B C D MODEL A=17.5 P=105\n"
|
||||
"@/code\n"
|
||||
"\n"
|
||||
"This flag allows configuring the SPICE reading without\n"
|
||||
"need for reimplementing a delegate. Note, that reimplementing\n"
|
||||
"\"parse_element\" may change that behavior.\n"
|
||||
"\n"
|
||||
"This attribute has been introduced in version 0.31.0."
|
||||
) +
|
||||
gsi::method_ext ("legacy_mode=", &set_legacy_mode, gsi::arg ("f"),
|
||||
"@brief Sets a flag indicating legacy mode\n"
|
||||
"See \\legacy_mode for details about this attribute.\n"
|
||||
"\n"
|
||||
"This attribute has been introduced in version 0.31.0."
|
||||
),
|
||||
|
|
|
|||
|
|
@ -970,6 +970,118 @@ TEST(27_MoreParameters)
|
|||
);
|
||||
}
|
||||
|
||||
TEST(28_SpiceProfiles1)
|
||||
{
|
||||
db::Netlist nl;
|
||||
|
||||
db::DeviceClass *dc1 = new db::DeviceClassMOS4Transistor ();
|
||||
dc1->set_name ("NMOS");
|
||||
nl.add_device_class (dc1);
|
||||
|
||||
db::DeviceClass *dc2 = new db::DeviceClassMOS4Transistor ();
|
||||
dc2->set_name ("PMOS");
|
||||
nl.add_device_class (dc2);
|
||||
|
||||
db::NetlistSpiceReader reader;
|
||||
|
||||
tl::InputStream is (
|
||||
"text:\n"
|
||||
".subckt TOP\n"
|
||||
"M1 n1 n2 n3 n1 nmos w=1.5u l=0.25u m=2 x=5*16\n"
|
||||
"M2 n5 n2 n3 n5 pmos w=4.0u l=0.25u y=hello\n"
|
||||
".ends\n"
|
||||
);
|
||||
reader.read (is, nl);
|
||||
|
||||
EXPECT_EQ (nl.to_string (),
|
||||
"circuit TOP ();\n"
|
||||
" device NMOS '1' (S=N3,G=N2,D=N1,B=N1) (L=0.25,W=3,AS=0,AD=0,PS=0,PD=0);\n"
|
||||
" device PMOS '2' (S=N3,G=N2,D=N5,B=N5) (L=0.25,W=4,AS=0,AD=0,PS=0,PD=0);\n"
|
||||
"end;\n"
|
||||
);
|
||||
}
|
||||
|
||||
TEST(28_SpiceProfiles2)
|
||||
{
|
||||
db::Netlist nl;
|
||||
|
||||
db::DeviceClass *dc1 = new db::DeviceClassMOS4Transistor ();
|
||||
dc1->set_name ("NMOS");
|
||||
nl.add_device_class (dc1);
|
||||
|
||||
db::DeviceClass *dc2 = new db::DeviceClassMOS4Transistor ();
|
||||
dc2->set_name ("PMOS");
|
||||
nl.add_device_class (dc2);
|
||||
|
||||
db::NetlistSpiceReader reader;
|
||||
reader.delegate ()->set_read_all_parameters (true);
|
||||
|
||||
tl::InputStream is (
|
||||
"text:\n"
|
||||
".subckt TOP\n"
|
||||
"M1 n1 n2 n3 n1 nmos w=1.5u l=0.25u m=2 x=5*16\n"
|
||||
"M2 n5 n2 n3 n5 pmos w=4.0u l=0.25u y=hello\n"
|
||||
".ends\n"
|
||||
);
|
||||
reader.read (is, nl);
|
||||
|
||||
EXPECT_EQ (nl.to_string (),
|
||||
// with "read_all_parameters" we also see the unknown ones
|
||||
"circuit TOP ();\n"
|
||||
" device NMOS '1' (S=N3,G=N2,D=N1,B=N1) (L=0.25,W=3,AS=0,AD=0,PS=0,PD=0,X=80);\n"
|
||||
" device PMOS '2' (S=N3,G=N2,D=N5,B=N5) (L=0.25,W=4,AS=0,AD=0,PS=0,PD=0,Y=HELLO);\n"
|
||||
"end;\n"
|
||||
);
|
||||
}
|
||||
|
||||
TEST(28_SpiceProfiles3)
|
||||
{
|
||||
db::Netlist nl;
|
||||
|
||||
db::DeviceClass *dc1 = new db::DeviceClassMOS4Transistor ();
|
||||
dc1->set_name ("NMOS");
|
||||
|
||||
auto sp = dc1->spice_profile ("");
|
||||
sp.incoming_parameters.insert (std::make_pair ("X", "X?X*2.5:42.0"));
|
||||
sp.incoming_parameters.insert (std::make_pair ("Y", "Y+'!'"));
|
||||
dc1->set_spice_profile ("NON_DEFAULT_PROFILE", sp);
|
||||
|
||||
EXPECT_EQ (dc1->has_spice_profile ("NON_DEFAULT_PROFILE"), true);
|
||||
EXPECT_EQ (dc1->spice_profile ("NON_DEFAULT_PROFILE").incoming_parameters.size (), size_t (9));
|
||||
EXPECT_EQ (dc1->spice_profile ("NON_DEFAULT_PROFILE").terminal_order.size (), size_t (4));
|
||||
|
||||
nl.add_device_class (dc1);
|
||||
|
||||
db::DeviceClass *dc2 = dc1->clone ();
|
||||
|
||||
EXPECT_EQ (dc2->has_spice_profile ("NON_DEFAULT_PROFILE"), true);
|
||||
EXPECT_EQ (dc2->spice_profile ("NON_DEFAULT_PROFILE").incoming_parameters.size (), size_t (9));
|
||||
EXPECT_EQ (dc2->spice_profile ("NON_DEFAULT_PROFILE").terminal_order.size (), size_t (4));
|
||||
|
||||
dc2->set_name ("PMOS");
|
||||
nl.add_device_class (dc2);
|
||||
|
||||
db::NetlistSpiceReader reader;
|
||||
reader.set_profile ("NON_DEFAULT_PROFILE");
|
||||
EXPECT_EQ (reader.profile (), "NON_DEFAULT_PROFILE");
|
||||
|
||||
tl::InputStream is (
|
||||
"text:\n"
|
||||
".subckt TOP\n"
|
||||
"M1 n1 n2 n3 n1 nmos w=1.5u l=0.25u m=2 x=5*16\n"
|
||||
"M2 n5 n2 n3 n5 pmos w=4.0u l=0.25u y=hello\n"
|
||||
".ends\n"
|
||||
);
|
||||
reader.read (is, nl);
|
||||
|
||||
EXPECT_EQ (nl.to_string (),
|
||||
"circuit TOP ();\n"
|
||||
" device NMOS '1' (S=N3,G=N2,D=N1,B=N1) (L=0.25,W=3,AS=0,AD=0,PS=0,PD=0,X=200);\n"
|
||||
" device PMOS '2' (S=N3,G=N2,D=N5,B=N5) (L=0.25,W=4,AS=0,AD=0,PS=0,PD=0,Y=HELLO!);\n"
|
||||
"end;\n"
|
||||
);
|
||||
}
|
||||
|
||||
TEST(100_ExpressionParser)
|
||||
{
|
||||
std::map<std::string, tl::Variant> vars;
|
||||
|
|
|
|||
Loading…
Reference in New Issue