Table of Contents

Language : Verilog

The Verilog language plugin attempts to support the syntax of the Verilog-AMS language.

Not all features of Verilog-AMS are supported, but those that work will work with Verilog-AMS syntax. Wherever possible, Gnucap features will work in Verilog-AMS mode, even if they don't work in Verilog-AMS.

The Verilog mode is case sensitive, and uses “SI” units.

The “SI” units are case sensitive. 1p is 1e-12. 1P is 1e15. 1m is 1e-3. 1M is 1e6.

Comments are preceded by // and extend to the end of the line.

The format is not line oriented. A semicolon terminates a statement. You can extend a line by ending it with \ .

In gnucap, for now, you must have one statement per line. This is non-standard.

From startup, you can set Verilog mode with the command line:

simulator lang=verilog

or

verilog

Components

All components have the same syntax:

type #(parameters) label (port list) ;
resistor #(10K)     Rload (out, 0);         // one unnamed parameter, ports by order
resistor #(.r(10K)) Rload (.p(out), .n(0)); // the same component, parameters by name, ports by name
amp #(.rload(100K)) X1 (.out(out), .in(in), .vcc(vc));

There are some components that exploit the syntax in other languages that are not supported in Verilog mode, but you can use them by switching to a mode that does support that syntax.

// vsource  #(.dc(15)) Vcc (.p(vc), .n(0)); // Spice-style source arguments are not supported.
// vsource  #(.ac(1))  Vin (.p(in), .n(0)); // Spice-style source arguments are not supported.

But you can switch modes, to one that does support the syntax:

// assume it is starting in Verilog mode
spice
* It takes Spice syntax now
Vcc (vc 0) dc 15
Vin (in 0) ac 1
* Commands in Spice mode start with a dot.
.verilog
// Now it is back in Verilog mode.

In addition to this, “attributes” are supported. Attributes store meta-data that may be used by some other application, or in special cases. Attributes are attached to something, like the instance, a parameter, or port. Attributes are name=value pairs, or just names.

(* type=wirelead, rating="1/4 watt" *) resistor #((* color=red *).r(10K)) Rload ((* up *) out, 0);

Top-level blocks

Two top level blocks are supported: module and paramset.

paramset

new/WIP

This relates to task 2a in verilogams. The following is implemented in the modelgen-verilog package and bundled with the device plugins (“mgsim”) therein. See the examples directory in gnucap-modelgen-verilog for various live applications.

A “paramset” statement creates a new type from an existing type. It becomes a “master” that can be instantiated later. It is similar to a spice ”.model”. A paramset must be declared at top level.

The syntax is:

"paramset" newname itsmaster ";"
  declarations
  parameters
"endparamset"
paramset my_resistor resistor;
  parameter R=1;
 .r = R;
endparamset
paramset const_resistor resistor;
 .r = 1;
endparamset

The types my_resistor and resistor are identical, except for the upper case parameter name “R”, and its default value “1”. A const_resistor has no parameters and is always 1 Ohm.

Multiple types by the same name are allowed, and are disambiguated during instanciation. One criterion is parameter names.

paramset thingy resistor;
  parameter real R;
 .r = R;
endparamset
paramset thingy vsource;
  parameter real V;
  .dc = V;
endparamset

module example(1, 2)
  thingy #(.V(1)) v(1, 2); // is a vsource
  thingy #(.R(1)) v(1, 2); // is a resistor
endmodule

Another criterion is parameter ranges.

paramset nfet some_nfet;
  parameter level=1 from [1:1];
  [..]
endparamset
  paramset nfet some_other_nfet;
  parameter level=2 from [2:2];
  [..]
endparamset

module example2(1, 2)
  nfet #(.level(1)) n1(1, 2, 3, 4); // is some_nfet
  nfet #(.level(2)) n1(1, 2, 3, 4); // is some_other_nfet
endmodule

Another one is port names. If port names are used in the instantiation, a matching prototype is required. Another criterion is number of parameters. If two prototypes match, the one with fewer parameters wins. This can be used to optimise out unwanted functionality and overhead.

module example3(1, 2)
  capacitor #(.c(1), .ic(1)) c1(1, 2); // pick a model that has initial conditions
  capacitor #(.c(1))         c2(1, 2); // avoid the overhead
  resistor #(.r(1), .tc1(42.), tc2(17.)) r1(1, 2); // pick a model that has temperature dependency
  resistor #(.r(1))                      r2(1, 2); // avoid the overhead
endmodule

current

This description applies to the default plugin included with the Gnucap package, as of August 2023.

A “paramset” statement sets parameters based on an existing compiled model. This will be extended to cover all “masters”. It becomes a “master” that can be instantiated later. It is equivalent to a spice ”.model”.

The syntax is:

"paramset" newname itsmaster ";"
  parameters
"endparamset"
paramset gp_npn npn;\
  .bf=150;\
endparamset

According to the standard, lines are not significant. In gnucap, for now, all must be on one line or lines extended by ending with “\”.

Note that the parameter syntax in paramset is different from the parameter syntax instantiating a device.

module

The basic building block is called a “module”. Modules are descriptions of individual components. Gnucap directly supports only the structural subset of Verilog, so a “module” here is equivalent to a Spice “subckt”.

Modules take the form:

module amp (out, in, vcc);
  parameter rload=10k;
  resistor  #(.r(1M))   Rb1  (base, vcc);        // 1 megohm
  resistor  #(.r(100K)) Rb2  (base, 0  );
  resistor  #(100K)     Rc   (col,  vcc);
  resistor  #(.r(10K))  Re   (.p(emit), .n(0));
  capacitor #(.c(1m))   Ce   (.p(emit), .n(0));  // 1 millifarad
  capacitor #(.c(1u))   Cin  (base, in );
  gp_npn                Q1   (.c(col), .b(base), .e(emit));
  gp_npn                Q2   (.c(vcc), .b(col), .e(e2));
  resistor  #(.r(1K))   Re2  (e2,  0  );
  capacitor #(.c(10u))  Cout (e2,  out);
  resistor  #(.r(rload))Rload(out, 0 );
endmodule

The following segment shows how the above amp module might be instantiated.

amp      #(.rload(100K)) X1    (.out(out), .in(in), .vcc(vc));
vsource  #(.dc(15))      Vcc   (.p(vc), .n(0));
vsource  #(.ac(1))       Vin   (.p(in), .n(0));
resistor #(10K)          Rload (out, 0);

Attributes are supported. Usually they are just stored for the purpose of interoperation with other software.

(* structural *) module amp (out, in, (* optional *) vcc);
  (* show *) parameter rload=10K;
  ....

Commands

The Verilog language has no concept of commands.

In gnucap, commands are executed at top level the same as the native mode.

Extras

Status

The current implementation in gnucap is a very preliminary subset.