The goal here is to move all of the models and devices out of the simulator core, and to allow them to be added and changed by users, without recompiling, relinking, or any other "difficult" method. They are now "plugins", which can be changed at any time, now considered to be data, like the circuit you are simulating.
A variant of modelgen, which will be called "gnucap-verilog" will convert Verilog-AMS into C++, which you will then use your C++ compiler to convert into a shared object file. Then "attach" it. Now you can use it. There will be 3 ways to use such file. One is to compile them in. To do this, just list it in the Makefile. To not compile it in, just remove it. The current plan is that the primitives (resistors, etc.) will be compiled in, but that is not a requirement. The second method is to compile to a shared-object file, which will be stored in a public library area, such as /usr/share/gnucap/lib . When the files are stored here, then can be treated as if they were compiled in, but actually will be linked when needed. The plan is that some models, most likely the ones people expect every simulator to have, will be supplied this way. They will be provided with the simulator. An extension to the second method adds another directory, such as /usr/local/gnucap/lib, where unsupported models can be installed. They too will be accessed transparently, but not supplied with the simulator. A collection of these will be maintained on the gnucap web site, and distributed as a separate tarball. We will accept these without testing. The third method is manual attachment. You would compile it and install it yourself. The file can be anywhere. This method allows you to develop models interactively. Just re-attach to use the new one. The attached files are completely self contained. Their symbol names are not exported, so there will be no clash between modules. The only data that must be unique is the name used to register it. There is no difference in the files, other than the way they are attached. So.. how does it work??? There is a global dispatcher. Actually, there are 3 of them. They are construted before the program signs on, and contain pointers to prototypes of anything you might call up. The 3 dispatchers are for models (MODEL_CARD), devices (CARD), and functions (COMPONENT_COMMON). There will be one more for commands, but that is not in this version. When a module is linked, a prototype of each model, device, or function is constructed as a static, and a pointer to it is entered in the dispatcher. Because it is in global space, where only object declarations are allowed, not executable code, it is necessary to "noun" the action of attachment. This is done with an "INSTALL" object, which uses its constructor to wrap the pointer to install it. This whole thing is built around the C++ "std::map" class, part of the standard library. It provides associative arrays. There is a significant catch, which probably seems obvious: The dispatcher must be constructed before you can put anything in it. This causes a link order dependency. In "globals.cc" we find: DISPATCHER<MODEL_CARD> model_dispatcher; ok ... "model_dispatcher" is an object of type "DISPATCHER<MODEL_CARD>". It is global. In a file being attached,containing a model, we find: // A declaration of the dispatcher, so we can use it: extern DISPATCHER<MODEL_CARD> model_dispatcher; // A prototype of the model being installed. // The name does not matter, // except that we will use it in the next statement. static MODEL_DIODE p1; // Now install it. // The name "p_D" doesn't matter. It is not seen anywhere else. static DISPATCHER<MODEL_CARD>::INSTALL p_D(&model_dispatcher, "D", &p1); // "p_D" here is a INSTALL wrapper object. // It is not used anywhere again, except when it is destructed. // The string "D" is what this model will be known as. // "&p1" is taking the address of the prototype, // which now corresponds to the string. We can now call up this model using the string "D", as in ".model my_diode D is=1e-18" To compile such a module.. If it will be compiled in, nothing special is required. If it will be a separate module, it must be compiled into a "shared object" file, with position independent code. You might do something like this: "g++ -fPIC -shared my_new_diode.cc -o my_new_diode.so" Now to attach it at run time: "attach ./my_new_diode.so". _______________________________________________ Gnucap-devel mailing list [email protected] http://lists.gnu.org/mailman/listinfo/gnucap-devel
