Transition from SPICE to Verilog

In the not so distant past, people migrated from Fortran to C. But, as rewriting Fortran code does not always pay off, there are means to intergrate Fortran libraries into modern systems. Now close to everyone is running Fortran code, most without even noticing. We are in a very similar situation with SPICE and Verilog. Here are some examples that show how to connect the worlds. These build on verilog_basics.

From a users perspective, a testbench can be the entry point for analysing a circuit. A circuit model is represented by a prototype such as rclp, and any other will appear with the same interface.

module rclp(in, out, ref);
  resistor #(.r(1)) R1(.p(in), .n(out));
  capacitor #(.c(1)) C1(.p(out), .n(ref));
endmodule
circuit in verilog, testbench in spice

The “spice” command is a shorthand for option lang=spice. it passes control of the input to the spice language plugin. (NB: language plugins are user defined, so here you can use your own Spice flavour if so required.)

gnucap> verilog
verilog> [paste rclp declaration here]
verilog> rclp #() mylp(.in(in), .ref(0), .out(out));
verilog> spice
spice> V1 in 0 sin amplitude=1 frequency=1
spice> .print tran v(nodes)
spice> .tran 1

This presentation exposes the “spice style behavioural modelling” described here.

circuit in verilog, testbench cleaned up

While SPICE is built on letter to device mapping (V means voltage source) and some implmentation defined modelling extensions (here: sin), Verilog-AMS defines a list of standard primitives that ought to behave identical across platforms.

For example, vsine provides a voltage source controlled by a time dependent sine wave with ports p and n, and the expected parameters (see LRM). This allows us to refactor the test bench into a portable presentation.

We define a simple wrapper

gnucap> spice
spice> .subckt vsine p n
spice> parameter ampl
spice> parameter freq
spice> V1 p n sin amplitude=ampl frequency=freq
spice> .ends

And move on as follows.

spice> .verilog
[paste rclp declaration here]
rclp #() mylp(.in(in), .ref(0), .out(out));
vsine #(.ampl(1) .freq(1)) vsin(.p(in), .n(0));
print tran v(nodes)
tran 1
native primitives

In the above section, the instanciation of vsine pulls in the spice wrapper subcircuit. Such devices can as well be compiled directly from portable behavioural code. In this case, the code will look approximately like this.

`include "disciplines.h"
module vsine(p, n);
  parameter ampl;
  parameter freq;
  electrical p, n;
  inout p, n;
  analog begin
    V(p, n) <+ ampl * sin(freq * $time * `some_constant);
  end
endmodule

A (growing) primitive library is now contained in the modelgen-verilog package. Precompiled modules are installed with it; load all with load vams, or load individually, e.g. load vams/vsine.so.