Adding the Hard Way
There are a few new pieces of Verilog in this file. You can think of
reg as variable types. A wire allows you to connect modules together. A reg is like a one-bit variable that remembers what you put in it.
You can think of
dut as a C++-like object instantiation. Here,
dut is just an arbitrary name. The
fulladd is the type and means the test module will include the
initial tells Verilog that it should do the following thing when the simulation (or the real circuit) first starts. You might think of it like a
main() function, but there can be as many of them as you like (remember, things in Verilog occur in parallel). There is a
begin keyword after the
initial so all the things up to the matching end are treated as a single entity.
The keywords that start with
$ are definitely not synthesizable. They are commands to the simulator. As you might guess, the ones that start with
dump are setting up the simulation output file. The
$finish command, not surprisingly, ends the simulation.
If you follow through the code in the initial block, you can see that "variables" get set to different values, and the test bench creates simulations dumps. The "#5" at the start of some lines tells the simulator to pause 5 "ticks" (the unit of simulation time) before continuing. Otherwise, since Verilog is a parallel language, everything would happen at once.
If this were a C program, you'd compile it. A Verilog program isn't much different. The command I used to compile the simulation is:
iverilog -o fulladd_tb fulladd_tb.v fulladd.v
This appears to do nothing, but in this case nothing is a good thing (any output would indicate an error). The output is an executable (
fulladd_tb, as specified by the
-o option). You still have to run the program to get the simulation output. For simple simulations you can just run it, but you should use the Icarus Verilog runtime,
If all goes well you'll get a single line of output informing you that the simulation created the dump file. Now you just need to look at the file (
fulladd_tb.vcd, as named in the
$dumpfile directive) in a meaningful way. That's what GTKWave is for:
You'll see a blank screen with some browsers on the left-hand side. The top browser shows your circuit in a tree-like format. Clicking on a part in the top pane shows you the signals in that part in the lower pane. You can drag those signals into the viewer pane. Here's what it looks like when you drag all the test signals over:
You can verify that the output and the carry output match what you'd expect. This is a good chance to look over the two Verilog files and the output dump and make sure you can follow why everything worked like it did. In true crystal radio fashion, I didn't want to bore you with a lot of theory, but just expose you to how simple it is to get started. If you really want to dig into the details of Verilog, there are plenty of references. Just do a web search for Verilog, Verilog reference, or Verilog tutorial and you'll find plenty of details (maybe too many details).
You might be disappointed that all the logic circuits so far have been very simple combinatorial logic. Most interesting designs need things that contain memory or state of previous events. That's the realm of flip flops and I'll talk about those next time.