mirror of https://github.com/KLayout/klayout.git
Tests
This commit is contained in:
parent
cd942db09a
commit
a5c730dfc8
|
|
@ -215,7 +215,27 @@ void Device::set_parameter_value (const std::string &name, const tl::Variant &v)
|
|||
void Device::set_parameter_value_create (const std::string &name, const tl::Variant &v, bool primary, const tl::Variant &def_value)
|
||||
{
|
||||
if (device_class ()) {
|
||||
set_parameter_value (mp_device_class->parameter_id_for_name_create (name, primary, def_value), v);
|
||||
|
||||
tl::Variant dv = def_value;
|
||||
|
||||
if (dv.is_nil ()) {
|
||||
if (v.is_a_string ()) {
|
||||
dv = tl::Variant (std::string ());
|
||||
} else if (v.is_double ()) {
|
||||
dv = tl::Variant (0.0);
|
||||
} else if (v.is_bool ()) {
|
||||
dv = tl::Variant (false);
|
||||
} else if (v.can_convert_to_long ()) {
|
||||
dv = tl::Variant ((long) 0);
|
||||
} else if (v.is_list ()) {
|
||||
dv = tl::Variant::empty_list ();
|
||||
} else if (v.is_array ()) {
|
||||
dv = tl::Variant::empty_array ();
|
||||
}
|
||||
}
|
||||
|
||||
set_parameter_value (mp_device_class->parameter_id_for_name_create (name, primary, dv), v);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -307,9 +307,9 @@ public:
|
|||
*
|
||||
* If the name is not valid, the parameter is created with the given primary
|
||||
* flag and default value. The default value also defines the type of the
|
||||
* parameter.
|
||||
* parameter. If not given, the type will be derived from the value v.
|
||||
*/
|
||||
void set_parameter_value_create (const std::string &name, const tl::Variant &v, bool primary, const tl::Variant &def_value);
|
||||
void set_parameter_value_create (const std::string &name, const tl::Variant &v, bool primary, const tl::Variant &def_value = tl::Variant ());
|
||||
|
||||
/**
|
||||
* @brief Used for device combination: join terminals with other device
|
||||
|
|
|
|||
|
|
@ -323,8 +323,8 @@ size_t DeviceClass::parameter_id_for_name_create (const std::string &name, bool
|
|||
pdef.set_id (m_parameter_definitions.size () - 1);
|
||||
|
||||
pdef.set_name (name);
|
||||
pdef.set_default_value (default_value);
|
||||
pdef.set_is_primary (primary);
|
||||
pdef.set_default_value (default_value);
|
||||
|
||||
return pdef.id ();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -790,7 +790,7 @@ std::string Netlist::to_string () const
|
|||
if (p != pd.begin ()) {
|
||||
ps += ",";
|
||||
}
|
||||
ps += p->name () + "=" + tl::sprintf ("%.12g", d->parameter_value (p->id ()));
|
||||
ps += p->name () + "=" + d->parameter_value (p->id ()).to_string ();
|
||||
}
|
||||
res += std::string (" device ") + tl::to_word_or_quoted_string (d->device_class ()->name ()) + " " + device2string (*d) + " (" + ts + ") (" + ps + ");\n";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -395,11 +395,13 @@ Class<db::Device> decl_dbDevice (decl_dbNetlistObject, "db", "Device",
|
|||
"@brief Sets the parameter value for the given parameter name.\n"
|
||||
"If the parameter name is not valid, an exception is thrown."
|
||||
) +
|
||||
gsi::method ("set_parameter_create", (void (db::Device::*) (const std::string &, const tl::Variant &, bool, const tl::Variant &)) &db::Device::set_parameter_value_create, gsi::arg ("param_name"), gsi::arg ("value"), gsi::arg ("primary", true), gsi::arg ("default_value", tl::Variant (0.0), "none"),
|
||||
gsi::method ("set_parameter_create", &db::Device::set_parameter_value_create, gsi::arg ("param_name"), gsi::arg ("value"), gsi::arg ("primary", true), gsi::arg ("default_value", tl::Variant (), "auto"),
|
||||
"@brief Sets the parameter value for the given parameter name and creates a new parameter if no parameter is present with this name.\n"
|
||||
"If a parameter exists already with the given name, the value of that parameter is set to the given value and the other arguments are ignored. "
|
||||
"If no parameter with the given name exists in the device class's parameter table, a new parameter is created. "
|
||||
"\\primary indicates that this parameter will be a primary one and \\default_value is the default value for this parameter. "
|
||||
"The default value also implicitly defines the type of the parameter. A float value will create a float-type parameter, a string value for default will create a string-type parameter.\n"
|
||||
"In this case, \\primary indicates that this parameter will be a primary one and \\default_value is the default value for this parameter. "
|
||||
"The default value also implicitly defines the type of the parameter. A float value will create a float-type parameter, a string value for default will create a string-type parameter, "
|
||||
"hence it should 'fit' to the parameter value. If no default value is given, an automatic default is picked depending on the parameter type."
|
||||
"\n"
|
||||
"This method has been introduced in version 0.31.0."
|
||||
),
|
||||
|
|
|
|||
|
|
@ -379,6 +379,8 @@ TEST(9_DeviceMultipliers)
|
|||
|
||||
{
|
||||
db::NetlistSpiceReader reader;
|
||||
reader.delegate ()->set_read_all_parameters (false);
|
||||
|
||||
tl::InputStream is (path);
|
||||
reader.read (is, nl);
|
||||
|
||||
|
|
@ -424,6 +426,8 @@ TEST(9_DeviceMultipliers)
|
|||
// read once again, this time with known classes (must not trigger issue-652)
|
||||
{
|
||||
db::NetlistSpiceReader reader;
|
||||
reader.delegate ()->set_read_all_parameters (false);
|
||||
|
||||
tl::InputStream is (path);
|
||||
reader.read (is, nl);
|
||||
|
||||
|
|
@ -642,6 +646,8 @@ TEST(17_RecursiveExpansion)
|
|||
std::string path = tl::combine_path (tl::combine_path (tl::testdata (), "algo"), "nreader17.cir");
|
||||
|
||||
db::NetlistSpiceReader reader;
|
||||
reader.delegate ()->set_read_all_parameters (false);
|
||||
|
||||
tl::InputStream is (path);
|
||||
reader.read (is, nl);
|
||||
}
|
||||
|
|
@ -677,6 +683,8 @@ TEST(17_RecursiveExpansion)
|
|||
std::string path = tl::combine_path (tl::combine_path (tl::testdata (), "algo"), "nreader17b.cir");
|
||||
|
||||
db::NetlistSpiceReader reader;
|
||||
reader.delegate ()->set_read_all_parameters (false);
|
||||
|
||||
tl::InputStream is (path);
|
||||
reader.read (is, nl2);
|
||||
}
|
||||
|
|
@ -691,6 +699,8 @@ TEST(18_XSchemOutput)
|
|||
std::string path = tl::combine_path (tl::combine_path (tl::testdata (), "algo"), "nreader18.cir");
|
||||
|
||||
db::NetlistSpiceReader reader;
|
||||
reader.delegate ()->set_read_all_parameters (false);
|
||||
|
||||
tl::InputStream is (path);
|
||||
reader.read (is, nl);
|
||||
|
||||
|
|
@ -725,6 +735,8 @@ TEST(19_ngspice_ref)
|
|||
std::string path = tl::combine_path (tl::combine_path (tl::testdata (), "algo"), "nreader19.cir");
|
||||
|
||||
db::NetlistSpiceReader reader;
|
||||
reader.delegate ()->set_read_all_parameters (false);
|
||||
|
||||
tl::InputStream is (path);
|
||||
reader.read (is, nl);
|
||||
|
||||
|
|
@ -760,6 +772,8 @@ TEST(19b_ngspice_ref)
|
|||
std::string path = tl::combine_path (tl::combine_path (tl::testdata (), "algo"), "nreader19b.cir");
|
||||
|
||||
db::NetlistSpiceReader reader;
|
||||
reader.delegate ()->set_read_all_parameters (false);
|
||||
|
||||
tl::InputStream is (path);
|
||||
reader.read (is, nl);
|
||||
|
||||
|
|
@ -795,6 +809,8 @@ TEST(20_precendence)
|
|||
std::string path = tl::combine_path (tl::combine_path (tl::testdata (), "algo"), "nreader20.cir");
|
||||
|
||||
db::NetlistSpiceReader reader;
|
||||
reader.delegate ()->set_read_all_parameters (false);
|
||||
|
||||
tl::InputStream is (path);
|
||||
reader.read (is, nl);
|
||||
|
||||
|
|
@ -933,6 +949,35 @@ TEST(26_comments)
|
|||
);
|
||||
}
|
||||
|
||||
// String parameters, add unknown parameters
|
||||
TEST(27_MoreParameters)
|
||||
{
|
||||
db::Netlist nl;
|
||||
|
||||
std::string path = tl::combine_path (tl::combine_path (tl::testdata (), "algo"), "nreader27.cir");
|
||||
|
||||
db::NetlistSpiceReader reader;
|
||||
reader.delegate ()->set_read_all_parameters (true);
|
||||
|
||||
tl::InputStream is (path);
|
||||
reader.read (is, nl);
|
||||
|
||||
// "QS" is a string parameter and as we have set "read_all_parameters" to true, the
|
||||
// devices will receive all the new parameters
|
||||
EXPECT_EQ (nl.to_string (),
|
||||
// right now, this instance appears because it is the default incarnation - but not used
|
||||
"circuit 'CHILD(QS=X,QX=1.5,QY=2)' (A=A,B=B);\n"
|
||||
" device NMOS '1' (S=A,G=B,D=A,B=B) (L=100,W=1.7,AS=0,AD=0,PS=0,PD=0,QS=X,QX=3,QY=4);\n"
|
||||
"end;\n"
|
||||
"circuit TOP (N1=N1,N2=N2);\n"
|
||||
" subcircuit 'CHILD(QS=STR_VALUE,QX=17,QY=2)' '1' (A=N1,B=N2);\n"
|
||||
"end;\n"
|
||||
"circuit 'CHILD(QS=STR_VALUE,QX=17,QY=2)' (A=A,B=B);\n"
|
||||
" device NMOS '1' (S=A,G=B,D=A,B=B) (L=100,W=1.7,AS=0,AD=0,PS=0,PD=0,QS=STR_VALUE,QX=18.5,QY=4);\n"
|
||||
"end;\n"
|
||||
);
|
||||
}
|
||||
|
||||
TEST(100_ExpressionParser)
|
||||
{
|
||||
std::map<std::string, tl::Variant> vars;
|
||||
|
|
@ -1058,3 +1103,4 @@ TEST(101_ExpressionParserWithDefScale)
|
|||
EXPECT_EQ (parser.read ("1.75k").to_string (), "1750");
|
||||
EXPECT_EQ (parser.read ("2*A").to_string (), "0.035");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -354,8 +354,8 @@ TEST(1_DeviceTerminalDefinition)
|
|||
dc.add_parameter_definition (ppd2);
|
||||
EXPECT_EQ (ppd2.is_primary (), true);
|
||||
|
||||
EXPECT_EQ (pd2string (dc.parameter_definitions ()[0]), "P1(Parameter 1)=1 #0");
|
||||
EXPECT_EQ (pd2string (dc.parameter_definitions ()[1]), "P2(Parameter 2)=0 #1");
|
||||
EXPECT_EQ (pd2string (dc.parameter_definitions ()[0]), "P1(Parameter 1)=##1 #0");
|
||||
EXPECT_EQ (pd2string (dc.parameter_definitions ()[1]), "P2(Parameter 2)=##0 #1");
|
||||
|
||||
dc.clear_parameter_definitions ();
|
||||
EXPECT_EQ (dc.parameter_definitions ().empty (), true);
|
||||
|
|
@ -1854,7 +1854,7 @@ TEST(27_CombineSmallC)
|
|||
|
||||
EXPECT_EQ (nl.to_string (),
|
||||
"circuit TOP (p1=n1,p2=n3);\n"
|
||||
" device model_name c1 (A=n1,B=n3) (C=3.66666666667e-15,A=0,P=0);\n"
|
||||
" device model_name c1 (A=n1,B=n3) (C=3.66666666666667e-15,A=0,P=0);\n"
|
||||
"end;\n"
|
||||
);
|
||||
}
|
||||
|
|
@ -2015,17 +2015,17 @@ TEST(28_EliminateShortedDevices)
|
|||
|
||||
db::Device *c1 = new db::Device (device, "c1");
|
||||
circuit->add_device (c1);
|
||||
c1->set_parameter_value (db::DeviceClassInductor::param_id_L, 1e-15);
|
||||
c1->set_parameter_value (db::DeviceClassCapacitor::param_id_C, 1e-15);
|
||||
|
||||
db::Device *c2 = new db::Device (device, "c2");
|
||||
circuit->add_device (c2);
|
||||
c2->set_parameter_value (db::DeviceClassInductor::param_id_L, 2e-15);
|
||||
c2->set_parameter_value (db::DeviceClassCapacitor::param_id_C, 2e-15);
|
||||
|
||||
c1->connect_terminal (db::DeviceClassInductor::terminal_id_A, n1);
|
||||
c1->connect_terminal (db::DeviceClassInductor::terminal_id_B, n1);
|
||||
c1->connect_terminal (db::DeviceClassCapacitor::terminal_id_A, n1);
|
||||
c1->connect_terminal (db::DeviceClassCapacitor::terminal_id_B, n1);
|
||||
|
||||
c2->connect_terminal (db::DeviceClassInductor::terminal_id_A, n1);
|
||||
c2->connect_terminal (db::DeviceClassInductor::terminal_id_B, n2);
|
||||
c2->connect_terminal (db::DeviceClassCapacitor::terminal_id_B, n2);
|
||||
|
||||
EXPECT_EQ (nl.to_string (),
|
||||
"circuit TOP (p1=n1,p2=n2);\n"
|
||||
|
|
@ -2042,3 +2042,82 @@ TEST(28_EliminateShortedDevices)
|
|||
"end;\n"
|
||||
);
|
||||
}
|
||||
|
||||
TEST(29_DeviceParametersWithArbitraryNameAndType)
|
||||
{
|
||||
db::Netlist nl;
|
||||
|
||||
db::Circuit *circuit = new db::Circuit ();
|
||||
circuit->set_name ("TOP");
|
||||
nl.add_circuit (circuit);
|
||||
|
||||
db::DeviceClass *device = new db::DeviceClassCapacitor ();
|
||||
device->set_name ("model_name");
|
||||
nl.add_device_class (device);
|
||||
|
||||
db::Net *n1 = new db::Net ("n1");
|
||||
circuit->add_net (n1);
|
||||
|
||||
db::Net *n2 = new db::Net ("n2");
|
||||
circuit->add_net (n2);
|
||||
|
||||
auto p1 = circuit->add_pin ("p1");
|
||||
auto p2 = circuit->add_pin ("p2");
|
||||
|
||||
circuit->connect_pin (p1.id (), n1);
|
||||
circuit->connect_pin (p2.id (), n2);
|
||||
|
||||
db::Device *c1 = new db::Device (device, "c1");
|
||||
circuit->add_device (c1);
|
||||
c1->set_parameter_value (db::DeviceClassCapacitor::param_id_C, 1e-15);
|
||||
|
||||
c1->connect_terminal (db::DeviceClassCapacitor::terminal_id_A, n1);
|
||||
c1->connect_terminal (db::DeviceClassCapacitor::terminal_id_B, n1);
|
||||
|
||||
EXPECT_EQ (nl.to_string (),
|
||||
"circuit TOP (p1=n1,p2=n2);\n"
|
||||
" device model_name c1 (A=n1,B=n1) (C=1e-15,A=0,P=0);\n"
|
||||
"end;\n"
|
||||
);
|
||||
|
||||
c1->set_parameter_value_create ("T", std::string ("tvalue"), false, std::string ("x"));
|
||||
c1->set_parameter_value_create ("N", 17l, true);
|
||||
c1->set_parameter_value_create ("P1", true, false); // bool
|
||||
c1->set_parameter_value_create ("P2", 0.5, false); // double
|
||||
tl::Variant l = tl::Variant::empty_list ();
|
||||
l.push (tl::Variant (0.5));
|
||||
c1->set_parameter_value_create ("P3", l, false); // list
|
||||
tl::Variant a = tl::Variant::empty_array ();
|
||||
a.insert (tl::Variant ("k"), tl::Variant (17l));
|
||||
c1->set_parameter_value_create ("P4", a, false); // array
|
||||
|
||||
const auto *pdt = device->parameter_definition (device->parameter_id_for_name ("T"));
|
||||
EXPECT_EQ (pdt->is_primary (), false);
|
||||
EXPECT_EQ (pdt->default_value ().to_parsable_string (), "'x'");
|
||||
|
||||
const auto *pdn = device->parameter_definition (device->parameter_id_for_name ("N"));
|
||||
EXPECT_EQ (pdn->is_primary (), true);
|
||||
EXPECT_EQ (pdn->default_value ().to_parsable_string (), "#0");
|
||||
|
||||
const auto *pd1 = device->parameter_definition (device->parameter_id_for_name ("P1"));
|
||||
EXPECT_EQ (pd1->is_primary (), false);
|
||||
EXPECT_EQ (pd1->default_value ().to_parsable_string (), "false");
|
||||
|
||||
const auto *pd2 = device->parameter_definition (device->parameter_id_for_name ("P2"));
|
||||
EXPECT_EQ (pd2->is_primary (), false);
|
||||
EXPECT_EQ (pd2->default_value ().to_parsable_string (), "##0");
|
||||
|
||||
const auto *pd3 = device->parameter_definition (device->parameter_id_for_name ("P3"));
|
||||
EXPECT_EQ (pd3->is_primary (), false);
|
||||
EXPECT_EQ (pd3->default_value ().to_parsable_string (), "()");
|
||||
|
||||
const auto *pd4 = device->parameter_definition (device->parameter_id_for_name ("P4"));
|
||||
EXPECT_EQ (pd4->is_primary (), false);
|
||||
EXPECT_EQ (pd4->default_value ().to_parsable_string (), "{}");
|
||||
|
||||
EXPECT_EQ (nl.to_string (),
|
||||
"circuit TOP (p1=n1,p2=n2);\n"
|
||||
" device model_name c1 (A=n1,B=n1) (C=1e-15,A=0,P=0,T=tvalue,N=17,P1=true,P2=0.5,P3=(0.5),P4={k=>17});\n"
|
||||
"end;\n"
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,10 @@
|
|||
|
||||
.subckt child a b qs=x qx=1.5 qy=2
|
||||
* "qx", "qy" and "qs" are new parameters
|
||||
m1 a b a b nmos w=1.7u qs=qs qx=qx+1.5 qy=qy*2
|
||||
.ends
|
||||
|
||||
.subckt top n1 n2
|
||||
x1 n1 n2 child qs=str_value qx=17 qy=2
|
||||
.ends
|
||||
|
||||
Loading…
Reference in New Issue