@@ -136,6 +136,83 @@ static lay::NetlistObjectPath second (const lay::NetlistObjectsPath *pp)
136136 return pp->second ();
137137}
138138
139+ namespace {
140+
141+ struct First
142+ {
143+ lay::NetlistObjectsPath operator () (const lay::NetlistObjectPath &p)
144+ {
145+ return lay::NetlistObjectsPath::from_first (p);
146+ }
147+ };
148+
149+ struct Second
150+ {
151+ lay::NetlistObjectsPath operator () (const lay::NetlistObjectPath &p)
152+ {
153+ return lay::NetlistObjectsPath::from_second (p);
154+ }
155+ };
156+
157+ }
158+
159+ template <class Which >
160+ static lay::NetlistObjectsPath from (const lay::NetlistObjectPath &p)
161+ {
162+ return Which () (p);
163+ }
164+
165+ template <class Which >
166+ static lay::NetlistObjectsPath from_net (const db::Net *net)
167+ {
168+ if (! net) {
169+ return lay::NetlistObjectsPath ();
170+ }
171+
172+ lay::NetlistObjectPath p;
173+ p.root = net->circuit ();
174+ p.net = net;
175+ return Which () (p);
176+ }
177+
178+ template <class Which >
179+ static lay::NetlistObjectsPath from_device (const db::Device *device)
180+ {
181+ if (! device) {
182+ return lay::NetlistObjectsPath ();
183+ }
184+
185+ lay::NetlistObjectPath p;
186+ p.root = device->circuit ();
187+ p.device = device;
188+ return Which () (p);
189+ }
190+
191+ template <class Which >
192+ static lay::NetlistObjectsPath from_circuit (const db::Circuit *circuit)
193+ {
194+ if (! circuit) {
195+ return lay::NetlistObjectsPath ();
196+ }
197+
198+ lay::NetlistObjectPath p;
199+ p.root = circuit;
200+ return Which () (p);
201+ }
202+
203+ template <class Which >
204+ static lay::NetlistObjectsPath from_subcircuit (const db::SubCircuit *subcircuit)
205+ {
206+ if (! subcircuit) {
207+ return lay::NetlistObjectsPath ();
208+ }
209+
210+ lay::NetlistObjectPath p;
211+ p.root = subcircuit->circuit ();
212+ p.path .push_back (subcircuit);
213+ return Which () (p);
214+ }
215+
139216Class<lay::NetlistObjectsPath> decl_NetlistObjectsPath (" lay" , " NetlistObjectsPath" ,
140217 gsi::method_ext (" first" , &first,
141218 " @brief Gets the first object's path.\n "
@@ -146,6 +223,67 @@ Class<lay::NetlistObjectsPath> decl_NetlistObjectsPath ("lay", "NetlistObjectsPa
146223 " @brief Gets the second object's path.\n "
147224 " In cases of paired netlists (LVS database), the first path points to the schematic netlist object.\n "
148225 " For the single netlist, the second path is always a null path."
226+ ) +
227+ gsi::method (" from_first" , &from<First>, gsi::arg (" p" ),
228+ "@brief Creates a path from given first coordinates.\n"
229+ "Use this constructor to create a paired path from a first set of coordinates (net, circuit, device).\n"
230+ "For single-sided databases (i.e. extracted netlist or schematic only), use the first coordinates. "
231+ "For two-sided database (i.e. LVS cross references), use the first coordinates when you refer to "
232+ "layout netlist objects.\n"
233+ "\n"
234+ "In this version, the minimum requirement for the path is to have a root.\n"
235+ "\n"
236+ "This constructor has been added in version 0.30.8."
237+ ) +
238+ gsi::method (" from_first" , &from_net<First>, gsi::arg (" net" ),
239+ "@brief Creates a path from a given net in the first netlist space.\n"
240+ "\n"
241+ "This constructor has been added in version 0.30.8."
242+ ) +
243+ gsi::method (" from_first" , &from_device<First>, gsi::arg (" device" ),
244+ "@brief Creates a path from a given device in the first netlist space.\n"
245+ "\n"
246+ "This constructor has been added in version 0.30.8."
247+ ) +
248+ gsi::method (" from_first" , &from_circuit<First>, gsi::arg (" circuit" ),
249+ "@brief Creates a path from a given circuit in the first netlist space.\n"
250+ "\n"
251+ "This constructor has been added in version 0.30.8."
252+ ) +
253+ gsi::method (" from_first" , &from_subcircuit<First>, gsi::arg (" subcircuit" ),
254+ "@brief Creates a path from a given subcircuit in the first netlist space.\n"
255+ "\n"
256+ "This constructor has been added in version 0.30.8."
257+ ) +
258+ gsi::method (" from_second" , &from<Second>, gsi::arg (" p" ),
259+ "@brief Creates a path from given second coordinates.\n"
260+ "Use this constructor to create a paired path from a second set of coordinates (net, circuit, device).\n"
261+ "For two-sided database (i.e. LVS cross references), use the second coordinates when you refer to "
262+ "schematic netlist objects.\n"
263+ "\n"
264+ "In this version, the minimum requirement for the path is to have a root.\n"
265+ "\n"
266+ "This constructor has been added in version 0.30.8."
267+ ) +
268+ gsi::method (" from_second" , &from_net<Second>, gsi::arg (" net" ),
269+ "@brief Creates a path from a given net in the second netlist space.\n"
270+ "\n"
271+ "This constructor has been added in version 0.30.8."
272+ ) +
273+ gsi::method (" from_second" , &from_device<Second>, gsi::arg (" device" ),
274+ "@brief Creates a path from a given device in the second netlist space.\n"
275+ "\n"
276+ "This constructor has been added in version 0.30.8."
277+ ) +
278+ gsi::method (" from_second" , &from_circuit<Second>, gsi::arg (" circuit" ),
279+ "@brief Creates a path from a given circuit in the second netlist space.\n"
280+ "\n"
281+ "This constructor has been added in version 0.30.8."
282+ ) +
283+ gsi::method (" from_second" , &from_subcircuit<Second>, gsi::arg (" subcircuit" ),
284+ "@brief Creates a path from a given subcircuit in the second netlist space.\n"
285+ "\n"
286+ "This constructor has been added in version 0.30.8."
149287 ),
150288 "@brief An object describing the instantiation of a single netlist object or a pair of those.\n"
151289 "This class is basically a pair of netlist object paths (see \\NetlistObjectPath). When derived from a single netlist view, "
@@ -156,7 +294,16 @@ Class<lay::NetlistObjectsPath> decl_NetlistObjectsPath ("lay", "NetlistObjectsPa
156294 "If the selected object isn't a matched one, either the first or second path may be a null or a partial path without a final net or device object "
157295 "or a partial path.\n"
158296 "\n"
159- "This class has been introduced in version 0.27.\n"
297+ "To create a paired path from an existing object (net, device, circuit, subcircuit), use \\from_first and \\from_second.\n"
298+ "Use \\from_first, if the object belongs to the first netlist of the database (' netlist' , layout netlist in the LVS context).\n"
299+ "Use \\from_second, if the object belongs to the second netlist of the database (' reference' , schematic netlist in the LVS context).\n"
300+ "\n"
301+ "It is also possible to create a paired path from a full path object (including root, a subcircuit path and a target object), either "
302+ "for the first or second side. Use \\from_first and \\from_second with a \\NetlistObjectPath argument in that case.\n"
303+ "A minimum requirement in that case is to set the root (the origin of the path). If no subcircuit path is "
304+ "given (see \\NetlistObjectPath#path), a suitable path leading from the target object (net or device) to the root will be constructed.\n"
305+ "\n"
306+ "This class has been introduced in version 0.27 and has been extended in version 0.30.8.\n"
160307);
161308
162309static lay::NetlistObjectPath current_path_first (lay::NetlistBrowserDialog *dialog)
@@ -226,6 +373,8 @@ Class<lay::NetlistBrowserDialog> decl_NetlistBrowserDialog ("lay", "NetlistBrows
226373 " Changing the selection will update the highlights and navigate to the location depending on the "
227374 " settings. An \\ on_selection_changed signal is not emitted.\n "
228375 " \n "
376+ " To get a suitable path, see the \\ NetlistObjectsPath#from_first and \\ NetlistObjectsPath#from_second generators.\n "
377+ " \n "
229378 " This setter has been introduced in version 0.30.8.\n "
230379 ) +
231380 gsi::method (" selected_paths" , &lay::NetlistBrowserDialog::selected_paths,
0 commit comments