The Verilog-XL digital simulator will simulate the behaviour of a digital circuit provided that a Verilog HDL model file exists for that circuit. The creation of such a model file is described elsewhere; this page describes the simulation process assuming that the model already exists.
Because of it's complexity, Verilog is best described by example. We will consider the simulation of a number of simple circuits starting with an RS flip-flop:
The Verilog HDL model file for this circuit is rs_flipflop.v. |
The following file, rs_flipflop_stim1.v, is a simple stimulus file for the RS flip-flop:
`timescale 100ps / 10ps // stimulus file for RS flip flop module rs_flipflop_stim1; reg notR, notS; wire Q; rs_flipflop rs_instance1 ( Q, notR, notS ); // stimulus information initial begin notR = 1; notS = 1; #1000 notR = 0; #1000 notR = 1; #1000 notS = 0; #1000 notS = 1; #1000 notR = 0; #1000 notR = 1; #1000 $finish; end // probe information // - generic verilog commands initial begin $monitor( "Time:",$time, " notR: %b", notR, " notS: %b", notS, " Q: %b", Q ); end endmodule
This should exist at the top of each Verilog file. It declares the units for time delays within the file and also the maximum resolution for such delays.
Inputs to the model under test are declared as registers.
Outputs from the model under test are declared as wires.
The stimulus information section contains a single "initial begin end" construct containing a number of input signal assignments "signal = X" and a number of time delays "#xxxx".
All inputs are initially defined, after which an input need only be mentioned when it changes.
The last command within the construct is always "$finish;".
The "$monitor();" system task causes changing values to be displayed in text form. The arguments are grouped with a format specifying string followed by the appropriate number of signals for display in each group.
Ensure that you are logged in to a machine which runs verilog1.
Type the following at the unix command prompt:
verilog rs_flipflop_stim1.v rs_flipflop.vor
modelsim_batch rs_flipflop_stim1.v rs_flipflop.v
The simulator output is in the form of a value for Time, notR, notS and Q printed each time that one of the inputs or outputs changes. It should look something like this:
Time: 0 notR: 1 notS: 1 Q: x Time: 1000 notR: 0 notS: 1 Q: 0 Time: 2000 notR: 1 notS: 1 Q: 0 Time: 3000 notR: 1 notS: 0 Q: 1 Time: 4000 notR: 1 notS: 1 Q: 1 Time: 5000 notR: 0 notS: 1 Q: 0 Time: 6000 notR: 1 notS: 1 Q: 0
Try both simulation commands and check that you get the same result with each.
A new stimulus file, rs_flipflop_stim2.v, illustrates some of the more advanced monitoring features available using Verilog:
.... module rs_flipflop_stim2; .... .... #1000 $display("\n Simulation complete\n"); $stop; $finish; end // probe information // - generic verilog commands initial begin $display(" Time Inputs Outputs"); $display(" notR notS Q"); $display(" ==== ========== ======="); $monitor($time," %b %b %b", notR, notS, Q); end // probe information // - Verilog-XL specific commands initial begin $timeformat(-10); $gr_position( "waves", 0,0,600,200); $gr_waves( "not R", notR, "not S", notS, "Q", Q, "not Q", rs_instance1.not_q); end // probe information // - ModelSim specific commands //VSIM COMMAND: view wave -x 0 -y 300 -width 800 -height 300 //VSIM COMMAND: add wave -label "not R" notR -label "not S" notS //VSIM COMMAND: add wave -label "Q" Q //VSIM COMMAND: add wave -label "not Q" rs_instance1/not_q //VSIM COMMAND: run -all endmodule
The stimulus information section now includes a "$display();" system task which is used to inform the user of the status of the simulation - in this case Simulation Complete.
The "$finish;" task is preceded by a "$stop;" task. This prevents the simulator from terminating before the user gets a chance to look at the WAVES window.
The "$monitor();" system task is now preceded by a number of "$display();" tasks which provide header information making the text output easier to read.
The "$gr_waves();" task results in the opening of a waveform window and the display of waveforms for listed signals.
The "$gr_position();" task allows the position and size of the WAVES window to be specified in order to improve the user interface.
The "$timeformat(-10);" task sets the format on the waveform display to units of 100ps in line with the timescale directive.
In this example the "$gr_waves();" task displays the value of "not Q" which is not a true output from the RS flip-flop. This is done by prefixing the name of the signal with the name of the instance in which it occurs. Hence "rs_instance1.not_q" refers to signal "not_q" in a submodule with an instance name "rs_instance1". This facility helps us to debug a system without bringing all the signals explicitly to the top of the hierarchy.
ModelSim does not support verilog system tasks to control waveform windows. Instead the commands that should be typed for an interactive ModelSim simulation are included as comments (e.g. //VSIM COMMAND: run -all). If ModelSim is invoked via the "modelsim" script, then the commands included as comments will be executed as if typed. In the example above, the following ModelSim interactive commands are executed:
view wave -x 0 -y 300 -width 800 -height 300 add wave -label "not R" notR -label "not S" notS add wave -label "Q" Q add wave -label "not Q" rs_instance1/not_q run -all
The "view wave" command results in the opening of a waveform window in the specified position and with the specified size.
The "add wave" command adds one or more waveforms to the wave window with the specified labels. If not preceded by a "view wave" command, the "add wave" command will cause a waveform window to be opened with default size in the default position. Note that the "rs_instance1.not_q" signal is referred to here as "rs_instance1/not_q".
The "run -all" causes the simulation to start and continue until ether a $stop; or $finish; is reached.
Type the following at the unix command prompt:
verilog_xl rs_flipflop_stim2.v rs_flipflop.vor
modelsim rs_flipflop_stim2.v rs_flipflop.v
Here we use different versions of the simulators; "verilog_xl" contains support for the Verilog-XL graphics tasks while "modelsim" runs the graphical version of the ModelSim simulator allowing multiple windows to be opened for display of graphical information.
Either simulator should provide this formatted text output:
Time Inputs Outputs notR notS Q ==== ========== ======= 0 1 1 x 1000 0 1 0 2000 1 1 0 3000 1 0 1 4000 1 1 1 5000 0 1 0 6000 1 1 0 Simulation complete
and a graphical waveform window which will depend on the simulator:
Instead of terminating (which would close the WAVES window), you are left at the interactive verilog prompt.
From the interactive prompt you can request a hard copy by typing:
$ps_waves("rs_flipflop.ps", "Hard Copy Test", 0, 6000);
A new file, rs_flipflop.ps, will be created in your current directory.
You can then terminate the simulation by typing:
$finish;
The following command typed at the unix prompt should send the hard copy file to a suitable PostScript printer:
lp -d <printername> rs_flipflop.ps
In order to see the full waveforms you will need to select Zoom -> Zoom Full from the pull down menus of the wave window.
With this waveform window you need only use the File -> Print Postscript... dialog to print (remember to set a suitable printer name):
File -> Print Postscript... Write Postscript Printer [x] Printer Command: [ lp -d <printername> ] [OK]
You can then terminate the simulation by typing the following command in the main ModelSim window:
run -all
To illustrate further functionality we will consider the simulation of a simple up/down counter:
The Verilog HDL model file for this circuit is up_down_count.v. |
The following file, up_down_count_stim.v, is a stimulus file for the up/down counter:
`timescale 100ps / 10ps //stimulus file for an up/down counter module up_down_count_stim; reg Up, Down, nReset, Clock; wire [3:0] Count; up_down_count instance1 ( Count, Up, Down, Clock, nReset ); always begin Clock = 0; #250 Clock = 1; #500 Clock = 0; #250 Clock = 0; end initial begin nReset = 1; Up = 0; Down = 0; #1000 nReset = 0; #1000 nReset = 1; #1000 Up = 1; #15000 Up = 0; #1000 $stop; Down = 1; #15000 Down = 0; #2000 $stop; Up = 1; Down = 0; #4000 Up = 0; Down = 1; #7000 Up = 1; Down = 0; #23000 $stop; $finish; end // probe information // - Verilog-XL specific commands initial begin $timeformat(-10); $gr_position( "waves", 20,20,1000,320); $gr_waves( "Clock", Clock, "nReset", nReset, "Up", Up, "Down", Down, "Count_3", Count[3], "Count_2", Count[2], "Count_1", Count[1], "Count_0", Count[0], "Count %d", Count ); $gr_position( "regs", 20,380,400,200); $gr_regs( "Register Window For UP/DOWN Counter", "===================================", " Direction of count %s", direction(Up,Down), " Count (binary) %b", Count, " Count (decimal) %d", Count, " Count (hexadecimal) %h", Count ); end // probe information // - ModelSim specific commands // the following two lines are needed for ModelSim since we // can only observe the values of signals (e.g. directStr) // not expressions (e.g. direction(Up,Down)) as with // Verilog-XL $gr_regs(); wire [6*8:1] directStr; assign directStr = direction(Up,Down); //VSIM COMMAND: add wave -label "Clock" Clock -label "nReset" nReset //VSIM COMMAND: add wave -label "Up" Up -label "Down" Down //VSIM COMMAND: add wave -label "Count" -unsigned -expand Count //VSIM COMMAND: view list -x 0 -width 400 //VSIM COMMAND: add list -label "Direction of count" -ascii directStr //VSIM COMMAND: add list -label "Count (hexadecimal)" -hexadecimal Count //VSIM COMMAND: add list -label "Count (decimal)" -unsigned Count //VSIM COMMAND: add list -label "Count (binary)" -binary Count //VSIM COMMAND: run -all // function declarations function [6*8:1] direction; input up, down; if ({up,down} == 2'b10) direction = "Up"; else if ({up,down} == 2'b01) direction = "Down"; else if ({up,down} == 2'b11) direction = "Reset"; else direction = "Hold"; endfunction endmodule
Here an "always begin end" construct is used to create a repetitive clock with a cycle time of 1000 units (100ps per unit). The "initial begin end" construct is used for changes in the stimulus signals which don't repeat.
The "$gr_waves();" task here includes a bus signal with a format specifier which tells us that we would like the annotation of the waveform display to be in decimal.
The new "$gr_regs();" task results in the opening of a window in which a snapshot of the system can be seen. The arguments for this task are very similar to those for the "$monitor();" task. This task is particularly useful in the simulation of large digital systems where we need to keep track of the state of many multibit registers and buses. Note the variety of formats available for display of multibit values.
In this stimulus section we call "$gr_position();" once each for the WAVES window and the REGS window.
The "add wave" command also allows us to specify the format for bus signals:
-unsigned | gives unsigned decimal format |
-signed or -decimal | gives signed decimal format |
-binary | gives unsigned binary format |
-hexadecimal | gives unsigned hexadecimal format |
-ascii | gives ascii string format |
The nearest that ModelSim has to a REGS window is provided by the "view list" and "add list" commands which provide a graphically enhanced $monitor(); type facility.
The last part of the probe section introduces two new concepts; the first is the declaration of a function and the second is the interpretation of a multibit value as a string. The result is a REGS display that not only reports the state of the system but is also able to interpret the results it gets - it knows whether the counter is counting up or down and tells us so.
For a more detailed description of the Verilog constructs used, see the cdsdoc on-line manual.
Type the following at the unix command prompt:
verilog_xl up_down_count_stim.v up_down_count.vor
modelsim up_down_count_stim.v up_down_count.v
For this simulation the WAVES window shows the output bus of the counter as individual lines and also as a bus with decimal annotation of values:
(click on small picture to get an enlargement)
We now also have a new REGS window which shows a snapshot of selected signals including multibit registers and busses at a time specified by the time cursor.:
The time cursor in the REGS window follows that in the WAVES window. This can be illustrated by using a system task which sets the time cusor in both windows:
$gr_jumptotime(13750);
The result is shown below:
Alternatively you can use the mouse to interact with the WAVES window to get the same effect.
Since the stimulus section contains several $stop; statements it is possible to continue the simulation from one $stop; statement to the next. Simply type
.at the interactive verilog prompt.
Continuing beyond the last $stop; will take you to a $finish; statement in the stimulus file thereby terminating the simulation.
In this case to advance from one $stop; to the next, type
run -allin the main ModelSim window. Again you can repeat this command several times until the $finish; command terminates the simulation.
In this lab you should have seen Verilog-XL with its lightweight interface and ModelSim with its more modern graphical user interface (GUI).
There is a third interface available, a modern GUI for Verilog-XL. This can be invoked using the "verilog +gui" command. Unfortunately this GUI doesn't support the REGS window which turns out to be very useful for processor development and visualisation.
Both modern GUIs support an interactive debugging style that you may be familiar with from programming. If you want to experiment with this, the ModelSim version is probably better integrated.
All Verilog documentation is available on-line via cdsdoc. Type the following at the unix command prompt in order to invoke cdsdoc:
cdsdoc &
On-line manuals of particular interest to this tutorial are:
1The verilog program runs on the ISS Solaris sever (ironwood) and on the ECS CAD server (salvador). If you are logged into one of these machines you can check the availability of verilog by typing:
which verilog_xl
If you get a "verilog_xl: Command not found." message you should check your account configuration.
If you need only the non-graphics implementation of the simulator you can run
verilog on a verilog capable machine when remotely logged in from any
other machine using telnet.
If you need graphical output, then you must be sitting at a machine with X-windows
running and correctly configured. The best way to be sure of X-windows capability
is to sit at a verilog capable machine.
Iain McNally
22-12-2003