# VAMS netlister README

## VAMS netlister

    date: 10 october 2000
    gEDA: gnetlist vams mode
    first unrevised vams mode documentation

    Written by: Martin Lehmann
    -------------------------------------------------------------------------

    VHDL-AMS support for the gEDA gnetlist tool
    -------------------------------------------

    CONTENT:

       1. functionality
          1. ARCHITECTURE generation
          2. ENTITY generation
          3. automatisate gnetlist calls

       2. implementation
          1. the vams mode of gEDA gnetlist
    	 1. scheme
    	    1. settings and new definition
    	    2. gnet-vams.scm
    	       1. routines main structure
    	    3. helpfully setting in gEDA gschem environment

    	 2. new c-code
    	    1. routines
    	    2. code-adaptation

          2. automatic generating gnetlist calls in gEDA gschem
    	 1. generated gEDA gnetlist calls
    	 2. scheme
    	    1. generate_netlist.scm
    	    2. settings

    	 3. new c-code
    	    1. routines
    	    2. code-adaptation

       The purpose of our endevour, is that gEDA gnelist completly
       supportted VHDL-AMS (VHDL Analog and Mixed-Signal) netlist
       generation.

       The VHDL-AMS netlist support mode is called vams.

       1. FUNCTIONALITY

       gEDA gnetlist in vams mode allow it to generate a VHDL-AMS
       ARCHITECTURE or an ENTIY declaration. Which of both tasks is
       performed, dependends on the generate-mode variable. This variable
       is defined in the gnetlist command or will be set default.

       If generate-mode=1 (default) gnetlist creates a netlist as an
       VHDL-AMS ARCHITECTURE of the current schematic. Otherwise
       (generate-mode=2), it creates an VHDL-AMS ENTITY declaration of the
       selected component (this task needs information from gEDA gschem,
       see below).

       Now follows a stepwise discription of the program run in both
       submodes.

       We presuppose that you are familiar with the structure of gEDA
       gnetlist usage (otherwise try gnetlist -help) and that you have
       ever seen an VHDL-AMS ARCHITECTURE with its belonging ENTITY. If
       you does not then the following distription will be seems very
       strange to you. Maybe the syntax files (syntax_entity.txt,
       syntax_architeture.txt) can helps you further.

       ==================================================================

       1.1. ARCHITECTURE GENERATION

       We suppose generate-mode is equal to 1, from this it follows that
       vams creates a netlist as an ARCHITECTURE (saved to
       <value-of-toplevel-attribute-entity>_arc.<output-fileextension>).

         ARCHITECTURE <architecture-identifier> OF <entity-identifier> IS

       The architecture-identifier we are getting from the toplevel
       attribute architecture, which we have introduced. If it is not
       defined, we are setting architecture-identifier default
       (default_architecture).  The same have we doing with the
       entity-identifier (toplevel attribute entity, default_entity).

         {<subnet-object> <subnet-name> : subnet-kind;}

       In the signal declaration part all subnets of the schematic will be
       declarated. A subnet declaration consists of an net-object, a
       net-name and a net-kind. All subnets are connected to various
       components pins. If this pins have all the same port-object and the
       same port-kind it is ok, but if one of them different, the net is
       faulty, and will be not declarated. Moreover, if the subnet-object
       a quantity, then it will be checked, whether the subnet consists
       exactly one output pin (port-mode), else the subnet is faulty too.
       The three net attributes (object, kind, mode) we are getting from
       the pin attribs, port_kind, port_object and port_mode (which we
       have introduced newly) of a component pin.

         BEGIN

       Ok. it's only marks the start of the architecture body.

         {<label> : ENTITY <entity> [(<architecture>)]
    	    [GENERIC MAP (<set generic> => <generic-value>
    			 {; <set-generic=> <generic-value>})]
                PORT MAP ( <pin-name> => <subnet-name>{; <.. => ..>});}

       We only support component instantiation statements, like this
       above, because we generate simple VHDL-AMS netlists. The label of
       an instance is defined from the uref of the instanciated
       component. Watch out, this label must be unique,it is not checked
       anywhere. The entity variable is not the same as the
       entity-identifier, it is the value of the device attribute which on
       its part identifies the precompiled ENTITY of this special
       component. Similar is the architecture variable belonging to the
       instanciated components ARCHITECTURE (note: one ENTITY can have more
       ARCHITECTURES), hence we are getting it from the component
       attribute ARCHITECTURE (newly introduced).

       All generics of the generic-list are component parameters, which
       are different from its default values (set in its ENTITY
       declaration). How can we distinguish them?  All defined generics
       are attached to the component and looks like :

    	   <attribute-name>=?<default-value> <- default, not in
    					        generic-list

       And if you want to change a parameter, you only must delete the
       ?-character and replace the default-value with your wanted value,
       like this :

               <attribute-name>=<new-value> <- element of generic list

       If you do it this way, the new assigned value and its attribute-name
       will be appear in the GENERIC MAP (set-generic=attribute-name and
       generic-value=new-value).

       The PORT MAP consists of all pins of a component and which nets
       them connected to. The pin-name is getting from the pin# attribute
       of the pin and the subnet-name means the value of the label
       attribute of a net (mostly default named), which the pin is
       connected to. If the pin directly wired to a PORT component (=
       component, which device attribute =PORT), then we assign the uref
       of this component to subnet-name.

         END ARCHITECTURE <architecture-identifier>;

       I think, this line needs no more explanation. The
       architecture-identifier is the same like in the first line of
       ARCHITECTURE declaration. Hence, the ARCHITECTURE part ends here.

       ==================================================================

       1.2. ENTITY GENERATION

       Now, we suppose generate-mode is equal to 2, from this it follows
       that vams creates an ENTITY declaration of a component (save to
       <component-device>.vhdl). If there no component selected (empty
       top-attribs list) then it will be created an toplevel ENTITY of the
       current schematic (save to
       <value-of-toplevel-attribute-entity>.vhdl).

         LIBRARY <library-identifier>{,<library-identifier>};
         USE     <package-identidier>{,<package-identifier>};

       Well, the context clause part is not very ingenious. All libraries
       and packages you needs for your simulation you must insert staticly
       (a library contents precompiled ENTITIES, ARCHITECTURES and
       PACKAGES, which are needed from base components [base of the
       hierachical netlist] of your schematic. a package contents
       predefined types, constants, ...).  We are searching for a better
       usability of this part.

         ENTITY <entity-identifier> IS
    	 [genric_clause]
    	 [port_clause]
         END ENTITY;

       If you want generate a toplevel ENTITY of your current schematic
       then the entity-identifier is defined from the toplevel attribute
       entity of the schematic-file. Moreover, there are no generic_clause
       and no port_clause.

       In case of an component based ENTITY declaration, the
       entity-identifier is getting from the device attribute of the
       selected component (this attribute is included in top-attribs list,
       which is defined in the automatic generated gnetlist command .. more
       about this, later).

         generic_clause :=
    	       GENERIC ( <generic-identifier> : REAL := <default-value>
    	                {;<generic-identifier> : REAL := <default-value>});

       All needed generic-identifiers and it default-values are getting
       from the top-attribs list. Note: all attached attributes of a
       component appears in the generic_clause, only special attributes,
       like uref, source and architecture, are taked out. The values of
       this attributes are taked from the top-attribs list, too, but it
       does not matter whether the value starts with a ?-character or not
       (?-character always will be deleted, if it exist in front of a
       value).

         port_clause :=
                PORT (<port-kind> <port-identifier> : [<port-mode>] <port-type>
    	          {;<port-kind> <port-identifier> : [<port-mode>] <port-type>});

       All variables of this clause are grabbed from the symbol of the
       selected component. Port-kind corresponds with the value of the
       port_kind attribute of the pin, which pin# attribute value is equal
       to port-identifier. Just as corresponds port-type with the the
       value of the pin attribute port_type and port-mode with the value
       of port_mode.

       ===================================================================

       1.3. AUTOMATISATING gnetlist CALLS

       Because it is very arduous to type the whole gnetlist command,
       which all its parameters, per hand into the terminal, we are
       implement an automatisation of this process in gEDA gschem. This
       makes it possible to create a VHDL-AMS ARCHITECTURE or ENTITY
       whitout any commandline actions. The only thing you must do, is to
       use one of the following hotkeys:

    	    <g e> for generating an ENTITY
    	    <g n> for genarating an ARCHITECTURE.

    	NOTE to <g e> - hotkey : If one component of the schematic
    				 selected then the ENTITY generation
    				 will be applied to this component !!

       ===================================================================

       2. IMPLEMENTATION

       At this section it will be explained the basic concept of the
       implementation, which is splited in two sections. The first one
       aimed to the gnelist implementation and the second to the gschem
       implementation.

       2.1. THE VAMS MODE OF gEDA gnetlist

       To realize gnetlist VHDL-AMS support, it was necessary to create
       new scheme and c stuff.

       2.1.1. SCHEME

       The scheme implementation contents two parts. On one hand the new
       file gnet-vams.scm, which realize the VHDL-AMS-code generation, and
       on the other hand some settings in rc-files.

       2.1.1.1. SETTINGS AND NEW DEFINITIONS

       The following lines insert in your gschemrc, or wherever you want,
       but it must be loaded at gnetlist startup.

    	   - load two modules, which we needs in our new implementation.

    	     (define-module (ice-9 ls) :use-module (ice-9 common-list)
    		                       :use-module (ice-9 string-fun))

               - load main file for VHDL-AMS support, which contents the
    	     startup procedure vams.

    	     (load "<path_of_gnet-vams.scm>/gnet-vams.scm")

       2.1.1.2. gnet-vams.scm

       This file contents all necessary scheme-functions to generate
       VHDL-AMS-code. Especially, the main procedure vams, which can be
       execute from the gnetlist command.

    	 For example :

    		gnetlist -g vams schematic_filename.sch

          ...

       2.1.2.1. ROUTINES MAIN STRUCTURE

       the mainly functions structure looks like:

       - (vams output-filename)

         ARCHITECTURE generation

    	- (vams:write-secondary-unit architecture entity  output-port)

    	    - (vams:write-architecture-declarative-part output-port)
    		  - (vams:write-signal-declarations output-port)

    	    - (vams:write-architecture-statement-part packages output-port)
    	          - (vams:write-generic-map output-port package)
    		  - (vams:write-port-map package output-port)

         ENTITY declaraction

    	 - (vams:write-primary-unit entity port-list generic-list output-port)

    	     - (vams:write-context-clause output-port)

    	     - (vams:write-generic-clause generic-list output-port)
    		  - (vams:write-generic-list generic-list output-port)

    	     - (vams:write-port-clause port-list output-port)
    		  - (vams:write-port-list port-list output-port)

       2.1.1.3 HELPFULLY SETTING IN THE gEDA gschem ENVIRONMENT

       This settings are not absolutly necessary, but they makes work
       easier.

    	- set in .gEDA/gschemrc or wherever you want, but place it
    	  right.

    	   	(attribute-promotion "enable")
    		(promote-invisible "enable")
    		(enforce-hierarchy "disabled")

    		(attribute-name "port_object")
    		(attribute-name "port_type")
    		(attribute-name "port_mode")
    		(attribute-name "entity")
    		(attribute-name "architecture")

       2.1.2. NEW C - CODE

       To got all informations, which we needed for currently netlist
       generation, we must implemented two new c - functions.

       2.1.2.1 NEW ROUTINES (saved in vams_misc.c)

         SCM vams_get_package_attributes(SCM scm_uref)

       The first function gets all attribute names (not its values) of a
       component. This routine requires the name a component (package),
       especially the uref of it, and returns a list of all attribute
       names which are attached to this package.

       We needs this functionality to produce a currectly
       VHDL-AMS GENERIC MAP.

         char* vams_get_attribs_list
    	   (OBJECT *object, SCM *list, OBJECT **return_found)

       It exists only for the support of the first function.

       2.1.2.2. CODE ADAPTATION

       To place this new functions at gnetlist scheme's disposal, you must
       perform the following actions.

         (1) gnetlist/src/g_register.c

    	   gh_new_procedure1_0
    	       ("gnetlist:vams-get-package-attributes",
    	         vams_get_package_attributes);

         (2) gnetlist/include/prototype.h

    	   SCM vams_get_package_attributes(SCM scm_uref);

         (3) edit gnetlist/src/Makefile.in or directly in Makefile

    	 (if you have edited Makefile.in you must run make config of
    	 course)

    	  - add "vams_misc.c" to gnetlist_SOURCES - variable
    	  - add "vams_misc.o" to gnetlist_OBJECTS - variable

         (4) copy vams_misc.c to gEDA/gnetlist/src/

         (5) compile your code newly

       ===================================================================

       2.2. AUTOMATIC GENERATING gnetlist CALLS IN gEDA gschem

       To realize this new feature it was necessary to put more
       information from the schematic to the scheme world of gEDA gschem.
       Concretly, we needs the filename of the current schematic, because
       gEDA gnetlist required it, and the attached attributes of a
       selected component for creating an VHDL-AMS ENTITY.  Hence, the
       gnetlist command is mutated to an unidirectional interface between
       the world of gschem scheme and the world of gnetlist scheme.

       There are three important things, which transfer through this
       interface:

    	(1) the source-file, which contents the complett filename
    	    (with path) of the current schematic.

    	(2) the top-attribs list, which contents all attached
                attributes of the selected component.

    	(3) the generate-mode, which is defined by the users actions.

       2.2.1. STRUCTURE OF gEDA gnetlist CALLS FROM COMMANDLINE OR FROM gEDA
    	  gschem.

         typical commandline call :

    		gnetlist [-o <output-filename>]
    			 -g vams
    			 <schematic-file>

       There are nothing to explain. The top-attribs list and the
       generate-mode variable are default defined ('() and 1).

       calls from gEDA gschem (3 possible variations) :

       Note: vhdl-path is a predefined variable, which is set in
    	 generate_netlist.scm first times. You can it simple redefine
    	 in your local gschemrc file, which is loading everytimes you
    	 starts gEDA gschem.

         (1) hot-key-stroke: - g n  (generate netlist)

    	 --> generates a netlist of the current schematic.

    	     gnetlist -o <vhdl-path>/<target-file>
    		      -g vams
    		      <source-file>

              The source-file variable is equate to the complett
              path+filename of the current schematic, which we get with
              help of a self coded c function. If you cut out the filename
              of the source-file variable (source-file without path) then
              you are getting the target-file.generate-mode and
              top-attribs are default again.

          (2) hot-key-stroke: - g e (generate-entity)
    	  and no component is selected.

    	  --> generates an toplevel ENTITY of the current
    	      schematic.

    	      gnetlist -c <scheme-comm>
    		       -o <vhdl-path>/<target-file>
    		       -g vams
    		       <source-file>

    		  scheme-comm="(define top-attribs '<top-attribs>)
    			       (define generate-mode '2)"

    	   Source-file needs no comment, because it is the same as in
    	   (1). To get all attributes of a selected component, we are
    	   must write a new c function again. The values, which we get
    	   from this new function are saved in top-attribs. The sense
    	   of the scheme-comm command is to put top-attribs and
    	   generate-mode from the gschem to the gnetlist environment.
    	   At last, the target-file consists of the pure basefilename
    	   of the source-file and an .vhdl extention.

           (3) hot-key-stroke: - g e (generate-entity)
    	   and only one component is selected.

    	   --> generates an ENTITY of the selected schematic.

    	       commandline is the same as in (2).

    	   Differences: The target-file is different, but it does not
    	   matter, because gnetlist generate an new output-filename in
    	   in this case (<device-name-of-selected-component>.vhdl,
    	   normally).But one fact is very important: the top-attribs
    	   variable includes all attached attributes of the selected
    	   component now.

       2.2.2. SCHEME

       The gnetlist command is generating from two scheme functions, which
       are saved in generate_netlist.scm. This functions starts if the
       gschem user is typing one of the specified hot-keys ([g e] starts
       generate-entity and [g n] starts generate-netlis). Both routines
       puts the whole gnetlist command together and execute it. The syntax
       you see above.

       2.2.2.1. generate_netlist.scm

       2.2.2.2. SETTINGS

       If you want use the new feature then you must do some entries in one
       of your gEDA gschem rc-files

         necessary defines:

    	 - in system-gschemrc

    		    ("g" . gnetlist-keymap)

    	   Edit your global-keymap and if "g" always defined then find
    	   out an other free hot-key-stroke.

    	   Note: the documentation supports the "g" - key only.

             - in one of the gschem startup files

     	     (define gnetlist-keymap
    	       '(("n" . generate-netlist)
    		 ("e" . generate-entity)))

         loads :

    	    (load "/home/fliser3/.gEDA/generate_netlist.scm")

       2.2.3. NEW C-CODE

       The c-code makes it possible to get directly informations from the
       gschem tool, which is necessary for the online execution of
       gnetlist.

       2.2.3.1. ROUTINES

       It exists two new c-functions. Both are put down in
       misc_for_gnetlist.c.

         SCM get_selected_filename(gpointer data,
    			  guint callback_action,
    			  GtkWidget *widget)

       This function returns the whole filename of the current schematic,
       which is picked from the w_current->page_current->page_filename
       string.

         SCM get_selected_component_attributes(gpointer data,
    				      guint callback_action,
    				      GtkWidget *widget)

       How the name is saying, this functions returns all attributes of
       the selected component. It is realized with a simple while loop
       over all objects of the schematic, which picked out all elements
       where the selected flag is set.

       2.2.3.2. CODE-ADAPTATION

       Here are some actions you must conclude to makes the software
       runable.

       (1) new lines in /gschem/src/g_register.c

    	gh_new_procedure0_0 ("get-selected-filename",g_get_selected_filename);

       (2) new lines in /gschem/include/prototype.h

    	SCM g_get_selected_filename();

       (3) copy the file misc_for_gnetlist.c to gschem/src

       (4) add in file /gschem/src/Makefile.in or directly in Makefile.

           (if you have edited Makefile.in you must run make config of
           course)

    	- add "misc_for_gnetlist.c" to gschem_SOURCES - variable
    	- add "misc_for_gnetlist.o" to gschem_OBJECTS - variable

       (5) add new lines in /gschem/src/g_key.c

    	 SCM g_get_selected_filename(void)
    	 {
    	   return (get_selected_filename(window_current, 0, NULL));
    	 }

       (6) compile your changed c-code newly

## VAMS netlister syntax architecture

    ARCHITECTURE <architecture-identifier> OF <entity-identifier> IS

          {<subnet-object> <subnet-name> : subnet-kind;}

    BEGIN

      {<label> : ENTITY <entity> [(<architecture>)]
    	    [GENERIC MAP (<set-generic> => <generic-value>
    			 {; <set-generic=> <generic-value>})]
                PORT MAP ( <pin-name> => <subnet-name>{; <.. => ..>});}

    END ARCHITECTURE <architecture-identifier>;

## VAMS netlister syntax entity

    LIBRARY <library-identifier>{,<library-identifier>};
    USE     <package-identidier>{,<package-identifier>};

    ENTITY <entity-identifier> IS
       [GENERIC ( <generic-identifier> : REAL := <default-value>
    	    {;<generic-identifier> : REAL := <default-value>}); ]
       [PORT (<port-kind> <port-identifier> : [<port-mode>] <port-type>
    	{;<port-kind> <port-identifier> : [<port-mode>] <port-type>});]
    END ENTITY;