To define custom element class we should use ::SpiceGenTcl::Device class as a superclass. Why we need this? One simple example is custom Verilog-A device, that could have arbitary number of pins and parameters. Let's try to define new element for next Verilog-A device:
This model is taken from designers-guide, that contains many Verilog-AMS models.
In this block of code we define instance class of core. Let's go through the each line. First line is class definition:
It is good convention to start class name from capital letter.
First argument is name of instance, then positive node and negative node names, args accepts model value after -model key and all optional parameters of device.
In these few lines we process args variable with argparse package:
List [list len area ms a k alpha c] contains all parameters we have in core verilog-a model. Due to these line we can pass parameters to element in forms -paramName $paramValue $paramQual, for example: -area 1e-4 or -area l*m -eq.
Possible qualificator is -eq - it means that parameter should be inserted into SPICE netlist as paramName={expression}
In the next few lines we build parameter list that will be passed to ::SpiceGenTcl::Device constructor:
The last but not the least is step of passing arguments to ::SpiceGenTcl::Device constructor:
This superclass accept arguments in form constructor {name pins modelName instParams}. So, we pass string n$name as device name, n is reference designator for verilog-a devices in ngspice. Secondly we pass list of nodes [list "p $pNode" "n $nNode"] in form of {{Name0 NodeName} {Name1 NodeName} {Name2 NodeName} ...}. And the last is list of parameters in form {{model Value -posnocheck} {Name Value ?-eq?} {Name Value ?-eq?} {Name Value ?-eq?} ...}.
So, after that we can create a new instance of newly created class: