PREV UP NEXT

# SIMULATION

One of the design goals of XSCHEM is the ability to launch a simulation without additional manual file editing. For this purpose XSCHEM stores in a schematic not only the circuit but also the simulator settings and the additional files that are needed. For example there is a `devices/netlist.sym` and `devices/netlist_not_shown.sym` symbol that can be placed in a schematic acting as a container of text files for all the needed SPICE models and any additional information to make the schematic ready for simulation.

The `devices/netlist_not_shown` symbol shown in the picture (with name MODELS) for example contains all the spice models of the components used in the schematic, this makes the schematic self contained, no additional files are needed to run a simulation. After generating the netlist (for example poweramp.spice) the resulting SPICE netlist can be sent directly for simulation (for example `hspice -i poweramp.spice` for the Hspice(TM) simulator).

### VERILOG SIMULATION

This is a tutorial showing how to run a simulation with XSCHEM. The first important thing to note is that XSCHEM is just a schematic editor, so we need to setup valid bindings to simulators in the `~/xschemrc` file. For this tutorial we plan to do a `Verilog` simulation since there is a very good open source simulator available, called Icarus Verilog. There is also a good waveform viewer called gtkwave that is able to show simulator results. Install these two valuable tools and setup installation paths in `xschemrc`:

    ...
    ## icarus verilog
    set iverilog_path $env(HOME)/verilog/bin/iverilog
    set vvp_path $env(HOME)/verilog/bin/vvp
    set iverilog_opts {-g2012}
    ...
    ## gtkwave
    set gtkwave_path $env(HOME)/gtkwave/bin/gtkwave
    ...

In the XSCHEM distribution there is one example design, `examples/greycnt.sch`.
Load this design:

    user:~$ xschem examples/greycnt

This testbench has a 8 bit input vector A[7:0] and two output vectors, B[7:0] and C[7:0]. B[7:0] is a grey coded vector, this mean that if A[7:0] is incremented as a binary number B[7:0] will increment by changing only one bit at a time. The C[7:0] vector is the reverse transformation from grey-code to binary, so at the end if simulation goes well C[7:0] == A[7:0]. In this schematic there are some components, the first one is the `xnor` gate, the second one is the `assign` element. The 'xnor' performs the logical 'Not-Xor' of its inputs, while 'assign' just propagates the input unchanged to the output, optionally with some delay. This is useful if we want to change the name of a net (putting two labels with different names on the same net is not allowed, since this is normally an error, leading to a short circuit).

An Ex-Nor gate can be represented as a verilog primitive, so for the xnor gate we just need to setup a `verilog_format` attribute in the global property string of the `xnor.sym` gate:

the 'assign' symbol is much simpler, in this property string you see the definition for SPICE (`format` attribute), Verilog (`verilog_format`) and VHDL (`vhdl_format`). This shows how a single symbol can be used for different netlist formats.

While showing the top-level testbench `greycnt` set XSCHEM in Verilog mode (menu `Options->Verilog` radio button, or `<Shift>V` key) and press the edit property `'q'` key, you will see some verilog code:

This is the testbench behavioral code that generates stimuli for the simulation and gives instructions on where to save simulation results. If you generate the verilog netlist with the `Netlist` button on the right side of the menu bar (or `<Shift>N` key) a `greycnt.v` file will be generated in the simulation directory (`${HOME}/xschem_library/simulations` is the default path in the XSCHEM distribution, but can be changed with the `set netlist_dir $env(HOME)/simulations` in `xschemrc` file):

    `timescale 1ps/1ps
    module greycnt (
      output wire [7:0] B,
      output wire [7:0] C
    );

    reg [7:0] A  ;

    xnor #(1 , 1 ) x2 ( B[4] , A[5] , A[4] );
    xnor #(1 , 1 ) x3 ( B[5] , A[6] , A[5] );
    xnor #(1 , 1 ) x14 ( B[6] , A[7] , A[6] );
    assign #1 B[7] = A[7] ;
    xnor #(1 , 1 ) x1 ( B[1] , A[2] , A[1] );
    xnor #(1 , 1 ) x4 ( B[2] , A[3] , A[2] );
    xnor #(1 , 1 ) x5 ( B[3] , A[4] , A[3] );
    xnor #(1 , 1 ) x6 ( B[0] , A[1] , A[0] );
    xnor #(1 , 1 ) x7 ( C[4] , C[5] , B[4] );
    xnor #(1 , 1 ) x8 ( C[5] , C[6] , B[5] );
    xnor #(1 , 1 ) x9 ( C[6] , C[7] , B[6] );
    assign #1 C[7] = B[7] ;
    xnor #(1 , 1 ) x10 ( C[1] , C[2] , B[1] );
    xnor #(1 , 1 ) x11 ( C[2] , C[3] , B[2] );
    xnor #(1 , 1 ) x12 ( C[3] , C[4] , B[3] );
    xnor #(1 , 1 ) x13 ( C[0] , C[1] , B[0] );
    initial begin
      $dumpfile("dumpfile.vcd");
      $dumpvars;
      A=0;
    end

    always begin
      #1000;
      $display("%08b %08b", A, B);
      A=A + 1;
      if(A==0) $finish;
    end
    endmodule

you will recognize the behavioral code right after the netlist specifying the connection of nets to the xnor and assign gates and all the necessary verilog declarations. If you press the `Simulation` button the `Icarus Verilog` simulator will be executed to compile (iverilog) and run (vvp) the simulation, a terminal window will show the simulation output, in this case the input vector A[7:0] and the grey coded B[7:0] vectors are shown. You can quit the simulator log window by pressing `'q'`.

If simulation completes with no errors waveforms can be viewed. Press the `Waves` button in the top-right of the menu bar, you may add waveforms in the gtkwave window:

If the schematic contains errors that the simulator can not handle instead of the simulation log a window showing the error messages from the simulator is shown:

To facilitate the debug you may wish to edit the netlist (`Simulation->Edit Netlist`) to locate the error, in the picture below i inserted deliberately a random string to trigger the failure:

As you can see the error is in the behavioral code of the top level greycnt schematic, so edit the global property (`'q'` key with no component selected) and fix the error.