mirror of https://github.com/KLayout/klayout.git
Some tests added.
This commit is contained in:
parent
42b7290fe5
commit
a90e14b692
|
|
@ -310,7 +310,7 @@ class DB_PUBLIC EqualDeviceParameters
|
|||
public:
|
||||
EqualDeviceParameters ();
|
||||
EqualDeviceParameters (size_t parameter_id, bool ignore = false);
|
||||
EqualDeviceParameters (size_t parameter_id, double relative, double absolute);
|
||||
EqualDeviceParameters (size_t parameter_id, double absolute, double relative);
|
||||
|
||||
virtual bool less (const db::Device &a, const db::Device &b) const;
|
||||
|
||||
|
|
|
|||
|
|
@ -4712,3 +4712,189 @@ TEST(29_EmptySubCircuitsFromSPICE)
|
|||
EXPECT_EQ (comp.compare (&a, &b), true);
|
||||
EXPECT_EQ (comp.compare (&a, &c), false);
|
||||
}
|
||||
|
||||
TEST(30_ComparePrimaryAndOtherParameters)
|
||||
{
|
||||
db::Netlist nl1, nl2;
|
||||
db::DeviceClass *dc1, *dc2;
|
||||
db::Circuit *circuit;
|
||||
db::Device *d;
|
||||
db::Net *n;
|
||||
std::string txt;
|
||||
bool good;
|
||||
|
||||
dc1 = new db::DeviceClassResistor ();
|
||||
dc1->set_name ("RES");
|
||||
nl1.add_device_class (dc1);
|
||||
circuit = new db::Circuit ();
|
||||
circuit->set_name ("X");
|
||||
d = new db::Device ();
|
||||
d->set_device_class (dc1);
|
||||
d->set_name ("D");
|
||||
d->set_parameter_value (db::DeviceClassResistor::param_id_L, 1.0);
|
||||
d->set_parameter_value (db::DeviceClassResistor::param_id_R, 10.0);
|
||||
d->set_parameter_value (db::DeviceClassResistor::param_id_W, 0.25);
|
||||
circuit->add_device (d);
|
||||
n = new db::Net ();
|
||||
circuit->add_net (n);
|
||||
n->set_name ("1");
|
||||
d->connect_terminal (db::DeviceClassResistor::terminal_id_A, n);
|
||||
n->add_pin (db::NetPinRef (circuit->add_pin ("1").id ()));
|
||||
n = new db::Net ();
|
||||
circuit->add_net (n);
|
||||
n->set_name ("2");
|
||||
d->connect_terminal (db::DeviceClassResistor::terminal_id_B, n);
|
||||
n->add_pin (db::NetPinRef (circuit->add_pin ("2").id ()));
|
||||
nl1.add_circuit (circuit);
|
||||
|
||||
dc2 = new db::DeviceClassResistor ();
|
||||
dc2->set_name ("RES");
|
||||
nl2.add_device_class (dc2);
|
||||
circuit = new db::Circuit ();
|
||||
circuit->set_name ("X");
|
||||
d = new db::Device ();
|
||||
d->set_device_class (dc2);
|
||||
d->set_name ("D");
|
||||
d->set_parameter_value (db::DeviceClassResistor::param_id_L, 1.1); // differs
|
||||
d->set_parameter_value (db::DeviceClassResistor::param_id_R, 10.0);
|
||||
d->set_parameter_value (db::DeviceClassResistor::param_id_W, 0.20); // differs
|
||||
circuit->add_device (d);
|
||||
n = new db::Net ();
|
||||
circuit->add_net (n);
|
||||
n->set_name ("1");
|
||||
d->connect_terminal (db::DeviceClassResistor::terminal_id_A, n);
|
||||
n->add_pin (db::NetPinRef (circuit->add_pin ("1").id ()));
|
||||
n = new db::Net ();
|
||||
circuit->add_net (n);
|
||||
n->set_name ("2");
|
||||
d->connect_terminal (db::DeviceClassResistor::terminal_id_B, n);
|
||||
n->add_pin (db::NetPinRef (circuit->add_pin ("2").id ()));
|
||||
nl2.add_circuit (circuit);
|
||||
|
||||
NetlistCompareTestLogger logger;
|
||||
db::NetlistComparer comp (&logger);
|
||||
comp.set_dont_consider_net_names (true);
|
||||
|
||||
good = comp.compare (&nl1, &nl2);
|
||||
|
||||
txt = logger.text ();
|
||||
|
||||
// we did not enable L and W, hence that works
|
||||
EXPECT_EQ (good, true);
|
||||
|
||||
EXPECT_EQ (txt,
|
||||
"begin_circuit X X\n"
|
||||
"match_ambiguous_nets 1 1\n"
|
||||
"match_ambiguous_nets 2 2\n"
|
||||
"match_pins 1 1\n"
|
||||
"match_pins 2 2\n"
|
||||
"match_devices D D\n"
|
||||
"end_circuit X X MATCH"
|
||||
);
|
||||
|
||||
// changing R will make the compare fail
|
||||
|
||||
d->set_parameter_value (db::DeviceClassResistor::param_id_R, 12.0);
|
||||
|
||||
logger.clear ();
|
||||
good = comp.compare (&nl1, &nl2);
|
||||
|
||||
EXPECT_EQ (good, false);
|
||||
|
||||
// if we install a delegate which introduces a tolerance (absolute 1) it will still not match
|
||||
|
||||
dc1->set_parameter_compare_delegate (new db::EqualDeviceParameters (db::DeviceClassResistor::param_id_R, 1.0, 0.0));
|
||||
|
||||
logger.clear ();
|
||||
good = comp.compare (&nl1, &nl2);
|
||||
|
||||
EXPECT_EQ (good, false);
|
||||
|
||||
// if we install a delegate which introduces a tolerance (absolute 2.0) it will match
|
||||
|
||||
dc1->set_parameter_compare_delegate (new db::EqualDeviceParameters (db::DeviceClassResistor::param_id_R, 2.0, 0.0));
|
||||
|
||||
logger.clear ();
|
||||
good = comp.compare (&nl1, &nl2);
|
||||
|
||||
EXPECT_EQ (good, true);
|
||||
|
||||
// removing the comparer will make it non-matching
|
||||
|
||||
dc1->set_parameter_compare_delegate (0);
|
||||
|
||||
logger.clear ();
|
||||
good = comp.compare (&nl1, &nl2);
|
||||
|
||||
EXPECT_EQ (good, false);
|
||||
|
||||
// disabling the parameter will make it match too
|
||||
|
||||
dc1->parameter_definition_non_const (db::DeviceClassResistor::param_id_R)->set_is_primary (false);
|
||||
|
||||
logger.clear ();
|
||||
good = comp.compare (&nl1, &nl2);
|
||||
|
||||
EXPECT_EQ (good, true);
|
||||
|
||||
// enabling the parameter again will make it mismatch again
|
||||
|
||||
dc1->parameter_definition_non_const (db::DeviceClassResistor::param_id_R)->set_is_primary (true);
|
||||
|
||||
logger.clear ();
|
||||
good = comp.compare (&nl1, &nl2);
|
||||
|
||||
EXPECT_EQ (good, false);
|
||||
|
||||
// disabling the parameter in the second netlist will make it match too
|
||||
|
||||
dc2->parameter_definition_non_const (db::DeviceClassResistor::param_id_R)->set_is_primary (false);
|
||||
|
||||
logger.clear ();
|
||||
good = comp.compare (&nl1, &nl2);
|
||||
|
||||
EXPECT_EQ (good, true);
|
||||
|
||||
// enabling the parameter again will make it mismatch again
|
||||
|
||||
dc2->parameter_definition_non_const (db::DeviceClassResistor::param_id_R)->set_is_primary (true);
|
||||
|
||||
logger.clear ();
|
||||
good = comp.compare (&nl1, &nl2);
|
||||
|
||||
EXPECT_EQ (good, false);
|
||||
|
||||
// we can install an ignore handler to make it match again
|
||||
|
||||
dc1->set_parameter_compare_delegate (new db::EqualDeviceParameters (db::DeviceClassResistor::param_id_R, true));
|
||||
|
||||
logger.clear ();
|
||||
good = comp.compare (&nl1, &nl2);
|
||||
|
||||
EXPECT_EQ (good, true);
|
||||
|
||||
// if we enable the L parameter we'll get a mismatch again (but we have to enable it in both netlists)
|
||||
|
||||
dc1->parameter_definition_non_const (db::DeviceClassResistor::param_id_L)->set_is_primary (true);
|
||||
|
||||
logger.clear ();
|
||||
good = comp.compare (&nl1, &nl2);
|
||||
|
||||
EXPECT_EQ (good, true);
|
||||
|
||||
dc2->parameter_definition_non_const (db::DeviceClassResistor::param_id_L)->set_is_primary (true);
|
||||
|
||||
logger.clear ();
|
||||
good = comp.compare (&nl1, &nl2);
|
||||
|
||||
EXPECT_EQ (good, false);
|
||||
|
||||
// until we install another tolerance
|
||||
|
||||
*dynamic_cast<db::EqualDeviceParameters *> (dc1->parameter_compare_delegate ()) += db::EqualDeviceParameters (db::DeviceClassResistor::param_id_L, 0.11, 0.0);
|
||||
|
||||
logger.clear ();
|
||||
good = comp.compare (&nl1, &nl2);
|
||||
|
||||
EXPECT_EQ (good, true);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -183,7 +183,27 @@ module LVS
|
|||
# @synopsis tolerance(device_class_name, parameter_name [, :absolute => absolute_tolerance] [, :relative => relative_tolerance])
|
||||
# See \Netter#tolerance for a description of that function.
|
||||
|
||||
%w(schematic compare join_symmetric_nets tolerance blank_circuit align same_nets same_nets! same_circuits same_device_classes equivalent_pins min_caps max_res max_depth max_branch_complexity consider_net_names).each do |f|
|
||||
# %LVS%
|
||||
# @name ignore_parameter
|
||||
# @brief Specifies whether to ignore a parameter from a given device class for the compare
|
||||
# @synopsis ignore_parameter(device_class_name, parameter_name)
|
||||
# See \Netter#ignore_parameter for a description of that function.
|
||||
|
||||
# %LVS%
|
||||
# @name enable_parameter
|
||||
# @brief Specifies whether to enable a parameter from a given device class for the netlisting and default compare
|
||||
# @synopsis enable_parameter(device_class_name, parameter_name)
|
||||
# See \Netter#enable_parameter for a description of that function.
|
||||
|
||||
# %LVS%
|
||||
# @name disable_parameter
|
||||
# @brief Specifies whether to disable a parameter from a given device class for the netlisting and default compare
|
||||
# @synopsis disable_parameter(device_class_name, parameter_name)
|
||||
# See \Netter#disable_parameter for a description of that function.
|
||||
|
||||
%w(schematic compare join_symmetric_nets tolerance ignore_parameter enable_parameter disable_parameter
|
||||
blank_circuit align same_nets same_nets! same_circuits same_device_classes equivalent_pins
|
||||
min_caps max_res max_depth max_branch_complexity consider_net_names).each do |f|
|
||||
eval <<"CODE"
|
||||
def #{f}(*args)
|
||||
_netter.#{f}(*args)
|
||||
|
|
|
|||
|
|
@ -164,6 +164,83 @@ module LVS
|
|||
|
||||
end
|
||||
|
||||
# %LVS%
|
||||
# @name ignore_parameter
|
||||
# @brief Indicates whether not to compare a specific parameter for a given device class name
|
||||
# @synopsis ignore_parameter(device_class_name, parameter_name)
|
||||
|
||||
def ignore_parameter(device_class_name, parameter_name)
|
||||
|
||||
device_class_name.is_a?(String) || raise("Device class argument of 'ignore_parameter' must be a string")
|
||||
parameter_name.is_a?(String) || raise("Parameter name argument of 'ignore_parameter' must be a string")
|
||||
|
||||
if self._l2n_data
|
||||
# already extracted
|
||||
self._ignore_parameter(self._l2n_data, device_class_name, parameter_name)
|
||||
else
|
||||
@post_extract_config << lambda { |l2n| self._ignore_parameter(l2n, device_class_name, parameter_name) }
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def _ignore_parameter(l2n, device_class_name, parameter_name)
|
||||
|
||||
dc = l2n.netlist.device_class_by_name(device_class_name)
|
||||
if dc && dc.has_parameter?(parameter_name)
|
||||
ep = RBA::EqualDeviceParameters::ignore(dc.parameter_id(parameter_name))
|
||||
if dc.equal_parameters == nil
|
||||
dc.equal_parameters = ep
|
||||
else
|
||||
dc.equal_parameters += ep
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# %LVS%
|
||||
# @name enable_parameter
|
||||
# @brief Indicates whether to enable a specific parameter for a given device
|
||||
# @synopsis enable_parameter(device_class_name, parameter_name)
|
||||
# Enabling a parameter has two effects: first the parameter is netlisted and second
|
||||
# the parameter is compared in the netlist compare - provided it is given in the schematic.
|
||||
# Setting a tolerance or using a custom device comparer will override the last rule.
|
||||
|
||||
# %LVS%
|
||||
# @name disable_parameter
|
||||
# @brief Indicates whether to disable a specific parameter for a given device
|
||||
# @synopsis disable_parameter(device_class_name, parameter_name)
|
||||
# Disabling a parameter has two effects: first the parameter is not netlisted and second
|
||||
# the parameter is compared in the netlist compare - provided it is given in the schematic.
|
||||
# Setting a tolerance or using a custom device comparer will override the last rule.
|
||||
# To disable a parameter for compare only, \ignore_parameter can be used.
|
||||
|
||||
[ :enable_parameter, :disable_parameter ].each do |mn|
|
||||
eval <<"CODE"
|
||||
def #{mn}(device_class_name, parameter_name)
|
||||
|
||||
device_class_name.is_a?(String) || raise("Device class argument of '#{mn}' must be a string")
|
||||
parameter_name.is_a?(String) || raise("Parameter name argument of '#{mn}' must be a string")
|
||||
|
||||
if self._l2n_data
|
||||
# already extracted
|
||||
self._enable_parameter(self._l2n_data, device_class_name, parameter_name, :#{mn} == :enable_parameter)
|
||||
else
|
||||
@post_extract_config << lambda { |l2n| self._enable_parameter(l2n, device_class_name, parameter_name, :#{mn} == :enable_parameter) }
|
||||
end
|
||||
|
||||
end
|
||||
CODE
|
||||
end
|
||||
|
||||
def _enable_parameter(l2n, device_class_name, parameter_name, enable)
|
||||
|
||||
dc = l2n.netlist.device_class_by_name(device_class_name)
|
||||
if dc && dc.has_parameter?(parameter_name)
|
||||
dc.enable_parameter(parameter_name, enable)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# %LVS%
|
||||
# @name align
|
||||
# @brief Aligns the extracted netlist vs. the schematic
|
||||
|
|
|
|||
Loading…
Reference in New Issue