A simulator accepts inputs that you specify and displays what the design's anticipated outputs will be. In this tutorial, we will be doing RTL (register transfer level) simulation, in which the input to the simulator is the compiled Verilog HDL source code. Verilog HDL is a programming language for defining the structural and behavioral description of digital circuits. In RTL simulation, since no delay information is present, the simulation has no delays in it. The simulator that you will be using is the ModelSim simulator, which is available in the Mentor Graphics toolset.
Synthesis is the process of taking human-readable input such as Verilog HDL source code files and creating a low-level description which describes the design in terms of simple gates. The synthesis tool you will be using is Synopsys Design Compiler.
|radix bin||Set the radix to binary.|
|radix unsigned||Set the radix to unsigned.|
|radix hex||Set the radix to hexadecimal.|
|radix decimal||Set the radix to decimal.|
|vdir||List the compiled entities in the work directory.|
|vdel reg||Delete the reg module in the work directory.|
|vlog reg.vl||Compile the file, reg.vl.|
|vsim reg||Load the reg module.|
|do macrofile.do||Execute the macro file, macrofile.do.|
|vsim tb_h4ba -do macrofile.do||Load the module tb_h4ba and execute the macro file, macrofile.do.|
|run 80||Run the simulation for 80 ns.|
|run -all||Run the simulation until a wait statement or breakpoint is executed.|
|restart -f||Restart the simulation.|
|view source||View the source window.|
|view *||View all the ModelSim windows.|
|add wave uut/*||Add all the signals in the uut component to the wave window.|
|add wave uut/sum||Add the sum signal in the uut component to the wave window.|
|pwd||List the name of the directory that you are in.|
|ls||List the contents of the directory.|
You may want to occasionally print out the simulation results that appear in the wave window.  You can use the zoom feature from the wave menu to obtain the proper zoom. To print the wave, from the wave menu, select File > Print Postscript... When the Write Postscript window opens, select File name: and type in a name for the file name, i.e., wave1.ps, and select ok. Only the portion of the wave that is presently viewable will be printed out. If the waveform is long, you will have to use more than one page.  To set the laser printer destination, in a xterm window, use the command, setenv PRINTER printername, where printername is the name of the printer that you want to print to . To view and print out a postscript file, you can use ghostview by typing the command, ghostview wave1.ps in a xterm window, where wave1.ps is the name of your postscript file. To print out the postscript file in ghostview, choose File > Print..., type the printer name in the popup window and select ok.
Note: Simulation can also be performed on the output of the synthesis tool. This is called gate-level simulation as opposed to RTL simulation performed in this tutorial. Gate-level simulation is more accurate, but takes longer than RTL simulation. Gate-level simulation will not be performed in this tutorial.
Your working directory should be ~/tutorial.
The Verilog description of a 4-bit adder using a process with a sensitivity list is p4ba.vl. The sensitivity list is to the right of always@. For an unclocked always block (no clock in the sensitivity list), primary input signals to the unclocked always block should be placed in the sensitivity list. Primary input signals are signals that are read in the always block that are generated outside of the always block. Since the signals, addend_one, addend_two, and carry_in are primary inputs to this unclocked always block, they are included in the sensitivity list. Whenever one of the signals in the sensitivity list changes value, the always block will be executed. The assignment statements in the unclocked process use the blocking assignment operator, =. Signals written to with the blocking assignment operator are updated instantaneously. Combinational logic (unclocked always block (no clock in the sensitivity list)) should be described using the blocking assignment operator. In an unclocked always block, statements are executed sequentially. The other type of Verilog assignment operator is the non-blocking assignment operator, <=. When a signal is written to with the non-blocking assignment operator, it is scheduled to be assigned the new value at the end of the current time unit. Sequential logic (clocked always block (clock in the sensitivity list)) should be described using the nonblocking assignment operator. In a clocked process using only the nonblocking assignment operator, all assignments are executed concurrently and the order does not matter. In a clocked process, only the clock and reset (if the reset is asynchronous) should be included in the sensitivity list.
In the Verilog module, sum, carry_out, and carry are declared to be of type reg because they are assigned to in the always block. No registers will be synthesized as no edge is specified in the event specification list (sensitivity list).
An integer type is used as the for loop index. The integer type is a 32-bit signed number. Use of the integer type should be reserved for testbenches and for use as a for loop index.
The for loop construct should only be used for iteration over space such as to assign to the bits as in this example code. The for loop construct should not be used to try to iterate over time. It's possible for the synthesis tool to not flag use of a for loop to iterate over time as an error; the synthesis tool may just hang in the compile operation. Hence, it's up to the designer to avoid this pitfall. Use of a loop state as one of your states in a state machine that increments a counter each clock cycle is a preferable method to iterate over time. An if statement can be used in the state to synthesize a comparator to check if the count equals the loop upper limit. Try to always think what hardware will result in synthesis from your code.
A sample testbench for the moore module is,
Suppose that you want to view on the wave timing diagram the six signals from the moore state machine: RESET_N, X, CLK, Z, NEXT_STATE, and CURRENT_STATE.
One method to do this is to use a .do macro file. Another method is to use the window menus.
A Synopsys Design Compiler synthesis script file for the moore state machine is moore.script.
The syntax for defining a function is:
function [ range_or_type ] function_identifier ;