eecs 470 tutorial (and tools reference for winter 2013)€¦ ·  · 2014-01-10eecs 470 tutorial...

16
EECS 470 Tutorial (and tools reference for Winter 2013) Getting Ready 1) Log onto a CAEN machine running Linux with your login and password. (You may have to reboot a windows machine) 2) You now want to load up an xterm so that you can issue commands from the command-line. You can do this by left clicking on the screen. A small menu should appear with “Open Terminal” listed near the top, click on that. You should now have an xterm on the screen ready for commands. 3) In this class it is very easy to use vast quantities of disk space. When you run out of disk space many bad things happen. Though this tutorial will be unlikely to exhaust your disk space unless it is almost full already, please check your disk quota via this command: fs quota We will be happy to help you find files to delete if you find you have a problem. 4) Now we need to retrieve the files that will be used during the tutorial. We have put these files in the class web space. They can be retrieved via a web browser, or via the wget utility which downloads files without using a browser. The wget command to execute is: wget www.eecs.umich.edu/courses/eecs470/tools/470tut.tar.gz To start a web browser, execute: firefox& The & causes mozilla to be run in the background so that you can have mozilla up and execute more commands in this shell at the same time. If you ever forget to run something in the background you can hit <Ctrl Z> (when the shell is the focus) and then execute: bg 6) Now that you have the files in tar format you need to untar them using this command: tar -xzvf 470tut.tar.gz 7) Now change into the 470tut directory by typing: cd 470tut Among others, this should create the files Makefile, tut_mod.v, tut_test.v, and tut_synth.tcl in the current directory. Please verify that the files were created by executing: ls

Upload: doandan

Post on 06-May-2018

217 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: EECS 470 Tutorial (and tools reference for Winter 2013)€¦ ·  · 2014-01-10EECS 470 Tutorial (and tools reference for Winter 2013) ... Feel free to add commands if you think they

EECS 470 Tutorial (and tools reference for Winter 2013)

Getting Ready

1) Log onto a CAEN machine running Linux with your login and password. (You may have to reboot a windows

machine)

2) You now want to load up an xterm so that you can issue commands from the command-line. You can do this by

left clicking on the screen. A small menu should appear with “Open Terminal” listed near the top, click on that.

You should now have an xterm on the screen ready for commands.

3) In this class it is very easy to use vast quantities of disk space. When you run out of disk space many bad things

happen. Though this tutorial will be unlikely to exhaust your disk space unless it is almost full already, please check

your disk quota via this command:

fs quota

We will be happy to help you find files to delete if you find you have a problem.

4) Now we need to retrieve the files that will be used during the tutorial. We have put these files in the class web

space. They can be retrieved via a web browser, or via the wget utility which downloads files without using a

browser. The wget command to execute is:

wget www.eecs.umich.edu/courses/eecs470/tools/470tut.tar.gz

To start a web browser, execute:

firefox&

The & causes mozilla to be run in the background so that you can have mozilla up and execute more commands in

this shell at the same time. If you ever forget to run something in the background you can hit <Ctrl Z> (when the

shell is the focus) and then execute:

bg

6) Now that you have the files in tar format you need to untar them using this command:

tar -xzvf 470tut.tar.gz

7) Now change into the 470tut directory by typing:

cd 470tut

Among others, this should create the files Makefile, tut_mod.v, tut_test.v, and tut_synth.tcl in the current directory.

Please verify that the files were created by executing:

ls

Page 2: EECS 470 Tutorial (and tools reference for Winter 2013)€¦ ·  · 2014-01-10EECS 470 Tutorial (and tools reference for Winter 2013) ... Feel free to add commands if you think they

Verilog from the command line

1) To simplify dealing with the command line, we have created a Makefile for this tutorial. In this class we use the

Makefile to create shortcuts for complicated commands and to standardize these commands. You will be required to

supply a Makefile with a standard user interface that will handle whatever files you use to accomplish your projects.

The Makefile that we are providing implements these standard interfaces and most of it can be reused without

modification for each of your projects. Let's have a look at the contents of the Makefile so you're comfortable with

modifying it when the time comes. Use your favorite text editor to load the file called "Makefile" or if you're not

familiar with unix text editors, you can just issue the following command for a gui text editor with syntax

highlighting for Makefiles, verilog, and c files that is commonly used here, however it will be beneficial if you learn

a more powerful editor in the future (vim or emacs come to mind):

nedit Makefile&

2) Looking at the Makefile there are several things you'll want to pay attention to. First of all, the comments at the

top list the commands and what they do. These may not make much sense yet, but if you forget what does what,

have a glance there. Secondly, and this is important for when you modify this Makefile for later projects, notice the

lines that begin with “TESTBENCH =”, “SIMFILES =” and “SYNFILES=” these lines specify the filenames of

your verilog files.

The “SIMFILES =” line should contain the filenames of all of the synthesizable verilog files you are

working with.

The “TESTBENCH =” specifies all of the files that contribute to your testbench and are not synthesized.

The “SYNFILES=” specifies the verilog files that are a result of the synthesis and any other files needed to

compile them. These files are named <module>.vg and correspond to each module, not file.

If you scroll down further you will see the actual commands executed. Feel free to add commands if you think they

will make things easier on you.

3) Now that we've looked at the Makefile, let's try to actually compile and run the provided verilog code. There are

some problems in the code provided. The reasoning behind this is that you wouldn't need very many verilog tools if

your code always worked perfectly. Most of the tools are there to help you debug broken code or to verify that your

code works. It's a useful way to demonstrate the tools and to show some examples of what you will see when you

run into these common bugs. Let's start out now by trying to compile and run the code on the command line. This

can be done by typing the following command:

make

You should notice that the code failed to compile. Looking at the error, you should notice there is a syntax error on

line 7 of tut_mod.v. There is a typo, "regg" should be "reg". You need to load up this file in your favorite text

editor to make the change. Fix the error, save your changes, and let's go ahead and run "make" again. You should

now see a successful compile and the values printed from the testbench (tut_test.v). The Makefile also puts the

output into a file called program.out. This file may be useful to compare results, to refer to during editing of the

verilog code, or for seeing the entire output when the output is very long.

Page 3: EECS 470 Tutorial (and tools reference for Winter 2013)€¦ ·  · 2014-01-10EECS 470 Tutorial (and tools reference for Winter 2013) ... Feel free to add commands if you think they

Debugging

Because verilog is a hardware description language, the normal concept of a debugger (which allows one to step

through the execution of a program from line to line) does not make sense. Instead, we use a waveform viewer

which has more in common with electronics tools. This tool allows you to graphically view how the signals change

over time

The debugger: DVE

The Makefile command for compiling your code and running this tool is the following, go ahead and run it :

make dve

The TopLevel.1 window should appear as shown in the figure

to the left. In the TopLevel.1 window various panes will be

already present. You can also open different panes yourself

using the Windows → Panes → …option.

1)Module Hierarchy Pane

The pane on the left hand side is the Module Hierarchy

window. This window is used for finding the signals and

modules you are interested in viewing in other windows.

This pane contains a hierarchical view of modules that

instantiate other modules. In this case, our testbench instantiates

one other module.If you click the "+" next to testbench, all of

the modules instantiated by testbench will become visible. In

this case, there's only one such module called tbp. If there were

more they would be listed below it.

tbp? What is tbp? There is no module named tbp in the code

we gave you. Actually, tbp is the name of the instantiation of

module two_bit_pred in testbench. This is why using

meaningful identifiers for these otherwise meaningless names

can be important.

2) Data Pane

The data pane lists the signals contained in the currently

selected module in the module hierarchy pane. You can select

the particular signals for which you want to view the waveform

in this window. Use Shift or Ctrl key to select multiple signals.

Once you have selected the signals that you want, right click on

any one of the selected signals and choose Add to Waves →

Recent. A new TopLevel.2 window will open with the

waveform viewer pane.

You can go back to the original window and add more signals

to the waveform viewer using the same method as described

above. For this tutorial, you should add all the signals present in

the testbench to the waveform viewer.

Page 4: EECS 470 Tutorial (and tools reference for Winter 2013)€¦ ·  · 2014-01-10EECS 470 Tutorial (and tools reference for Winter 2013) ... Feel free to add commands if you think they

3) The waveform viewer

The waveform viewer is the primary part of the debugger. Once you have added some signals into the waveform

viewer, click on Simulator→ Start. This will run the program until the end. You must choose the signals you

wish to view before you start the simulation. That is because the only signals that will be stored during the

execution are those signals that are in the waveform viewer. If during your debugging you discover that you need

some other signals, add them to the waveform viewer (they will show up as gray which indicates that the values

were not logged), and choose Simulator→ Terminate and then Simulator→ Start.

As said before, the waveform window is supposed to help facilitate your debugging by allowing you to see how

signals are changing in relation to each other as time progresses. Underneath the actual waveforms is a scrollbar

that will allow you to move to different time values. Go ahead and scroll right until you get to the end. This is

where the simulation ended. This is not a very large simulation, so it might make sense to want to zoom out so you

can see more of what's going on in a single window. On the toolbar at the top of the waveform window, you will

find different zooming options. Alternatively, you can find zooming options in View→ Zoom. Practice zooming in

and out for a few seconds. Try zooming out so the whole simulation is one 1 screen.

There are many different types of things you can see appear in the waveform window as a signal. The most obvious

and probably most common would be a normal 1 bit signal, which is represented by lines and edges moving up and

down as time progresses (where up is a value of 1 and down is a value of 0), "transition" is this kind of signal.

Another possibility is that the value of the signal is unknown, that its value could not be determined, and is usually

the sign of a bug in your program. An example of this is "prediction" from time 25 on. These can be seen quite

clearly by the amount of red that it shows and the value is represented as "x". Seeing a lot of these can be a good

indication of a problem (though sometimes it is not a problem). Another possibility is a high Z value. These are

shown as a gold line and indicate that nothing is driving the signal, that nothing ever sets its value. "taekn" is an

example of this. These could occur as a result of a typo or forgetting to instantiate a module properly. The last kind

of signal is one that consists of more than 1 bit. In this case, "bigsignal" is 16 bits wide. Its value is not shown with

rising and falling lines, but with separations between textual values.

For signals greater than 1 bit, the value is displayed in the wave. Sometimes it's convenient to have this value

displayed as hex, binary, 2s complement decimal, whatever. Notice the signal named "bigsignal" is a 16 bit value

and should currently be displaying its hex value of 0xdead. You can change how it is displayed by right clicking its

current value which is in the list to the right of the name. There you should see a menu with the Radix option. Try

changing it to binary or 2s compliment.

Page 5: EECS 470 Tutorial (and tools reference for Winter 2013)€¦ ·  · 2014-01-10EECS 470 Tutorial (and tools reference for Winter 2013) ... Feel free to add commands if you think they

Left clicking on the waveform itself will set the current position and display a vertical line at that position. The

number on the top is the time and the values on the left will reflect that time. Try selecting time 50. Notice that

values displayed have changed from the initial values to different values. To go to the next time clock changes, left

click to highlight clock and right click on the waveform and select “next edge”.

It is also generally useful to rearrange the values so that the signals you are most interested in are grouped together.

You can do this by dragging the signal names to different positions. Signals you are simply not interested in can be

removed via the edit menu or by pressing the delete key when they are selected. Try placing transition just below

clock and removing bigsignal.

4) The source pane

The source pane allows you to quickly and easily see the source

code of any of your modules. This is useful when you see some

suspicious behavior in the waveform viewer and you would like

to see what is affecting the value of a variable. It can also be

useful for making sure the file you've been editing to fix a bug is

actually the file being compiled. You can load the source file by

dragging a module from the hierarchy window to the source

window. Try dragging the "tbp" module over to see the source

code.

You can also drag specific signals from the hierarchy pane to the

source pane or between the waveform window and the source

pane. Try dragging the state variable from the source window to

the waveform window and then drag the prediction signal from

the waveform window to the source window. Note that the

source window highlights the definition of the signal.

To view the values of variables in the source window, you should

right click on the source window and then click on Annotate

Values option. Now all values shown by the source window will

be from the time selected in the waveform window.

5) Finding the bug

Now that we've gone through much of the tools, we should try to determine if there's a bug in our code. The output

of this branch prediction module is the signal named "prediction." As we mentioned before, from time 25 on the

value is unknown despite the fact that the input signals are known. This means there is a bug, but where is it? For

the signal to be unknown, a signal that it relies on to determine its state must be either unknown or unconnected. So,

we need to start by looking at how "prediction" gets set. The source for "tbp" should already be open, so let's use

that to trace back to where the problem is. Let's also add the "tbp" module signals to the waveform viewer so we

can see the signals in that module. Looking at the source, we can see that "prediction" is simply set equal to a bit of

signal "state." Looking at the waveform viewer, we see that, as expected, "state" is unknown at the same times.

Now we want to check the signals that define "state." We can see that "state" either takes on a known value of 01,

or it takes on the value of "next_state." So again, now we need to trace back to which values set "next_state."

Looking at this, we can see that "next_state" is determined by "state" and "taken." We already know state is broken,

so we need to look at "taken." On the waveform viewer, we see that "taken" is always in high Z state, that it has

never been set. Because "taken" is an input into this module, we know the problem is in how the testbench is

connecting to this module. Now let's drag the "testbench" module into the source viewer so we can look for the

problem. Looking at where tbp is instantiated, we can see that there was a typo. ".taken(taekn)" should have been

".taken(taken)" on line 9. The compiler assumed "taekn" was just a wire not being driven and although it gave a

warning, it did not give a compiler error on this. These little bugs can often be very annoying to deal with.

Page 6: EECS 470 Tutorial (and tools reference for Winter 2013)€¦ ·  · 2014-01-10EECS 470 Tutorial (and tools reference for Winter 2013) ... Feel free to add commands if you think they

Now that we've found the bug, we want to save the waveform viewer configuration so we can just easily reload

them when we run the waveform viewer again. It may not seem to be a big deal right now, but eventually when

you're working with hundreds of signals, only a few of which are related to a problem you're trying to debug, it can

be very annoying to try to find and place them on the waveform viewer every time. To do this, on the waveform

viewer go to File → Save Session. Type in a filename, like View1.tcl or, in the future, any name you want. It will

be useful to keep the names descriptive as there may be different sets of signals to look at for different parts of a

module you're testing. Now exit DVE.

Use your favorite text editor to fix that typo in "tut_test.v". When you're finished, type make clean and then

make dve to recompile and reload the waveforms so we can double check that it's working properly now. Now on

the TopLevel.1 window, go to File → Load Session. Select your View1.tcl file and press OK. The waveform

viewer, complete with the original signals, should appear. Run the simulation again. Here we can see, that

everything is working properly now.

6) Back to thewaveform viewer

So far we’ve been treating the simulation as a post-

processing problem. We can also debug a running

simulation, much like one debugs a C program, allowing

you to debug even when you get an infinite loop and to

recompile within the gui. Only some basic useful features

will be explained here. Feel free to explore more advanced

features on your own.

To begin, open up the Makefile with your favorite editor

and change the SIMFILES field from tut_mod.v to

tut_mod2.v. This module has an infinite loop in it

(circular combinational logic). In a small file like this, it

would be fairly easy to just open up the .v file and find the

source of the infinite loop, but in larger systems

pinpointing the source of the problem will be a lot more

difficult.

Try running the simulator by running make.

You’ll notice that it hangs while making the simv

file. Press ctrl-C to break the process.

Do a make clean to remove any output files

that may have been created. Now we will use the

interactive compiler to find where our problem is.

Start it with the commandmake dve.

The TopLevel.1 window should appear. Now let’s find that infinite loop. Add the signals to the waveform viewer.

To find out where it is, click Simulator→ Start. The waveform viewer should hang and a red dot in the toolbox

above should get enabled. Now click on Simulator→ Terminate. You can now see that the simulation was hung at

time 25. The problem must be around here somewhere. We are now at time 30. Now let’s find out where we’re

looping. Click Simulator→ Step/Next → Next a few times and look at the tbp source code. We seem to be going

between tut_mod2.v:11 and tut_mod2.v:12. That means that lines 11 and 12 of tut_mod2.v are causing the problem.

We now know that the problem is in our module (not our testbench). In the tbp source, right click and

selectAnnotate Values to monitor the values of each wire. We want to see how we got to this stateIf we look at the

source window, we can see that lines 11 and 12 are assignments to loop1 and loop2. If we click next a few times

and watch the values, we can see that both loop1 and loop2 keep changing even though no time is actually passing.

This is a sure sign of circular logic. Since loop1 is dependent on loop2, and loop2 is dependent on loop1, the

circular path is fairly obvious in this case.

Page 7: EECS 470 Tutorial (and tools reference for Winter 2013)€¦ ·  · 2014-01-10EECS 470 Tutorial (and tools reference for Winter 2013) ... Feel free to add commands if you think they

But if we weren’t sure, a visual depiction of our module might help. Right click on the tbp module in the hierarchy

pane and click on Show Schematic to open up the Schematic pane. We can see a diagram of our Verilog module. If

you make your window wide enough, you should be able to see a circular loop of wires in the general area of the

loop1 and loop2 assign statements

If this were an actual design, we would now have enough information to fix the bug. In this example, there’s

nothing to really fix, since the loop1 and loop2 variables are not used for anything, so we can just leave the design

alone and finish up.

There are a number of other useful features in the waveform viewer. Feel free to explore and try other things on your

own.

The Virsim debugger presented in the next section was traditionally used with EECS 470. However, Synopsys (the

company that makes VCS and VirSim) stopped supporting VirSim in 2006. A better and newer debugger is the

DVE debugger, which comes with newer versions of Synopsys VCS.

Page 8: EECS 470 Tutorial (and tools reference for Winter 2013)€¦ ·  · 2014-01-10EECS 470 Tutorial (and tools reference for Winter 2013) ... Feel free to add commands if you think they

Cleaning up

Sometimes some of the tools may fail in strange fashions. If this happens or if you are in need of disk space, we

have provided a Makefile command that will hopefully help. This command removes all of the intermediate files

generated during compilation and simulation. The command is:

make clean

This should not interfere with any of the files generated during our next topic, synthesis, so you may want to use

some of the other cleaning commands provided as well. Those commands will be described in the next section.

Synthesis (the short version)

In this class we require that your hardware designs really represent hardware and we judge your final project on the

overall speed of your design. To accomplish this you will need to synthesize your verilog code. The synthesis tool

attempts to create an actual circuit level design of your verilog code. This circuit level design is actually a verilog

file itself, but it is structural verilog and uses a library of standard cells that another tool can lay out on a real chip.

One benefit of the output being a verilog file is that we can simulate the circuit level design in the same way we

simulate your behavioral design. Thus, we can test your synthesized design and if it does not behave properly your

code is not considered to be synthesizable and is therefore incorrect (though we do give partial credit).The clock

speed of the circuit that it generates will be the clock speed we use for your design. We won’t go into great detail

about synthesis in this tutorial but we will show you the basics.

1) The synthesis script

tut_synth.tcl is a script of commands for the synthesis tool. Please open it using your editor of choice. For the time

being you should only have to modify the four lines near the top under the comment, “The following four lines must

be updated for every new design”. We will attempt to explain the rest of the magic in the script to you later. The

first line tells the tool to read your specific synthesizable verilog files. The second line tells the tool the name of

your top level module. In this case we only have one synthesizable module so it is the verilog name of that module.

The next line must also properly reflect the name of the clock signal in your design. If you do not have a clock in

your design just leave these as they are. The final line tells the tool the clock period you are aiming for. A higher

period will generally yield a slower synthesized design but will take less time to synthesize. Since speed does not

matter yet, leave this at a nice high number.

2) Synthesizing

In order for the Makefile to operate properly you need to add a rule for the .vg file you will be creating. Open

Makefile in your favorite editor. After the SYNFILES = two_bit_pred… line insert the following code:

two_bit_pred.vg: tut_mod.v tut_synth.tcl

dc_shell–t –f tut_synth.tcl | tee synth.out

Note: Do not copy and paste these two lines into your Makefile. Type it instead. The special characters are not

copied correctly when you do copy and paste.

Be careful to put a single tab after the : and a single tab before dc_shell. Makefiles are very particular about white

space. For each module you will create you must add it to the SYNFILES line as well as add a make option. Save

the file and exit the editor.

Now you are ready to run the synthesis script and generate the synthesized verilog please execute this command:

make syn

The synthesis process can take a long time. Since this design is so small it shouldn’t be too bad but be prepared for

some long waits. The synthesis script generates a number of files. the “db” files are binary files that are not

interesting to look at. Please edit the following files to see what they look like.

Page 9: EECS 470 Tutorial (and tools reference for Winter 2013)€¦ ·  · 2014-01-10EECS 470 Tutorial (and tools reference for Winter 2013) ... Feel free to add commands if you think they

two_bit_pred.rep This file tells you about the properties of the synthesized circuit. The important things to

look for at this point are any violations (search for “VIOLATED” or “no violated”) and

the minimum value for slack (search for “slack”).

two_bit_pred.chk This file should be empty. If it is not empty it will contain warnings and/or error

messages that can help you determine what is going wrong.

two_bit_pred.vg This is the verilog code for the synthesized design. Do not feel any need to understand

this horrible code. There is a reason we do not write this code directly.

3) Running the synthesized code

All of the Makefile shortcuts defined for your original code have corollaries for your synthesized code.

4) Cleaning up from synthesis

To remove absolutely all of the files that result from synthesis, compilation, and simulation (including the

synthesized verilog files, the synthesis reports), which is a very scary thing to do, use this command:

make nuke

Page 10: EECS 470 Tutorial (and tools reference for Winter 2013)€¦ ·  · 2014-01-10EECS 470 Tutorial (and tools reference for Winter 2013) ... Feel free to add commands if you think they

Trying it yourself

At this point we would like you to try writing and debugging a design from scratch (well, you should feel free use

any of the code we have provided for templates).

1) Design the hardware

As discussed in discussion, design the hardware and identify what the registers, inputs, outputs, and combinational

logic blocks are at a high level. You should implement a Moore state machine for an arbiter (which conceptually

will be connected to two requestors A and B at a higher level and should provide signals to each indicating whether

control has been granted to it. The state machine is described by this state transition diagram:

2) Write the verilog code

Write verilog code for the module (arbiter.v) and for a testbench (arbiter_test.v) for the module. Ideally, you should

try to write a testbench that produces the correct/incorrect output that will be required for projects, but for this

tutorial that is not vital.

3) Make sure it works

Compile, run, and debug your verilog using the tools described in this tutorial. Note that you may need to modify

the Makefile.

4) Synthesize your design

You will probably need to modify the tut_synth.tcl script (possibly making a copy of it) to do this.

5) Make sure the synthesis worked

This means both looking at the report file and testing the synthesized code.

6) Have one of the GSI’s check off your lab by next Thursday’s office hours.

Congratulations, you have finished the tutorial.

Grant

to

neither

Grant

to A

Grant

to B

A requesting

A requesting

B not

requesting

B requesting

A not

requesting

B requesting

but A not

neither

requesting

Page 11: EECS 470 Tutorial (and tools reference for Winter 2013)€¦ ·  · 2014-01-10EECS 470 Tutorial (and tools reference for Winter 2013) ... Feel free to add commands if you think they

APPENDIX-the OLD debugger.

the debugger (interactive waveform viewer)

Because verilog is a hardware description language, the normal concept of a debugger (which allows one to step

through the execution of a program from line to line) does not make sense. Instead, we use a waveform viewer

which has more in common with electronics tools. This tool allows you to graphically view how the signals change

over time. The Makefile command for compiling your code and running this tool is the following, go ahead and run

it:

make int

1) The interactive window

The interactive window should appear. From here you can control

the simulation interactively, much like a debugger. To recompile

your code after making changes go to Sim->Rebuild and Re-exec.

The interactive window has a number of useful features, but we

need a few other tools before we can make effective use of it.

Now select “Hierarchy” from the Window menu.

2) The hierarchy window

The hierarchy window should appear. This window is used for

finding the signals and modules you are interested in viewing in

other windows.

The left pane contains a hierarchical view of modules that

instantiate other modules. In this case, our testbench instantiates

one other module. If you click the "+" next to testbench, all of the

modules instantiated by testbench will become visible. In this case,

there's only one such module called tbp. If there were more they

would be listed below it. tbp? What is tbp? There is no module

named tbp in the code we gave you. Actually, tbp is the name of the instantiation of module two_bit_pred in

testbench. This is why using meaningful identifiers for these

otherwise meaningless names can be important.

The right pane lists the signals contained in the currently selected

module.

The window menu is used to bring up the other windows. Select

“Waveform” from the window menu now.

3) The waveform window

The waveform window should appear. This window is where

most of the action is. The signals under investigation are

displayed in this window.

The easiest way to display signals in the waveform window is to

drag them from the hierarchy window (using the middle mouse

button) to the waveform window. First, left click on the

"testbench" module on the left side of the hierarchy window to

select it. Now middle click on it, holding down the middle

mouse button, and move your cursor over to the waveform

window and release when the cursor is green. You should now

see all of the signals within the testbench module displayed.

Page 12: EECS 470 Tutorial (and tools reference for Winter 2013)€¦ ·  · 2014-01-10EECS 470 Tutorial (and tools reference for Winter 2013) ... Feel free to add commands if you think they

Individual signals can also be selected and dragged in the same way.

Once you have dragged some signals into the Waveform window, press the “Continue” button on the interactive

window. This will run the program until the end. You must choose the signals you wish to view before you press

continue. That is because the only signals that will be stored during the execution are those signals that are in the

waveform viewer. If during your debugging you discover that you need some other signals, add them to the

waveform viewer (they will show up as gray which indicates that the values were not logged), and choose Sim->Re-

exec.

As said before, the waveform window is supposed to help facilitate your debugging by allowing you to see how

signals are changing in relation to each other as time progresses. Underneath the actual waveforms is a scrollbar

that will allow you to move to different time values. Go ahead and scroll right until you get to the end. This is

where the simulation ended. This is not a very large simulation, so it might make sense to want to zoom out so you

can see more of what's going on in a single window. On the toolbar at the top of the waveform window, you will

find a big Z, and smaller z, and a z%. The big Z zooms you in, the little z zooms you out, and the z% let's you pick

how much of the simulation you want to fit on a single screen. Practice zooming in and out for a few seconds. Try

zooming out so the whole simulation is one 1 screen.

There are many different types of things you can see appear in the waveform window as a signal. The most obvious

and probably most common would be a normal 1 bit signal, which is represented by lines and edges moving up and

down as time progresses (where up is a value of 1 and down is a value of 0), "transition" is this kind of signal.

Another possibility is that the value of the signal is unknown, that its value could not be determined, and is usually

the sign of a bug in your program. An example of this is "prediction" from time 25 on. These can be seen quite

clearly by the amount of red that it shows and the value is represented as "x". Seeing a lot of these can be a good

indication of a problem (though sometimes it is not a problem). Another possibility is a high Z value. These are

shown as a gold line and indicate that nothing is driving the signal, that nothing ever sets its value. "taekn" is an

example of this. These could occur as a result of a typo or forgetting to instantiate a module properly. The last kind

Page 13: EECS 470 Tutorial (and tools reference for Winter 2013)€¦ ·  · 2014-01-10EECS 470 Tutorial (and tools reference for Winter 2013) ... Feel free to add commands if you think they

of signal is one that consists of more than 1 bit. In this case, "bigsignal" is 16 bits wide. Its value is not shown with

rising and falling lines, but with separations between textual values.

For signals greater than 1 bit, the value is displayed in the wave. Sometimes it's convenient to have this value

displayed as hex, binary, 2s complement decimal, whatever. Notice the signal named "bigsignal" is a 16 bit value

and should currently be displaying its hex value of 0xdead. You can change how it is displayed by right clicking its

current value which is in the list to the right of the name. There you should see a menu with lots of choices. Try

changing it to binary or 2s compliment.

Left clicking on the waveform itself will set the current position and display a vertical line at that position. The

number on the top is the time and the values on the left will reflect that time. Try selecting time 50. Notice that

values displayed have changed from the initial values to different values. To go to the next time clock changes, left

click to highlight clock and right click on the waveform and select “next edge”

It is also generally useful to rearrange the values so that the signals you are most interested in are grouped together.

You can do this by middle-dragging the signal names to different positions. Signals you are simply not interested in

can be removed via the edit menu or by pressing the delete key when they are selected. Try placing transition just

below clock and removing bigsignal.

4) The source window

The source viewer allows you to

quickly and easily see the source code

of any of your modules. This is

useful when you see some suspicious

behavior in the waveform viewer and

you would like to see what is

affecting the value of a variable. It

can also be useful for making sure the

file you've been editing to fix a bug is

actually the file being compiled. You

can load the source file by dragging

with the middle mouse button a

module from the hierarchy window to

the source window. Try dragging the

"tbp" module over to see the source

code.

You can also middle drag specific

signals from the hierarchy window to

the source window or between the

waveform window and the source

window. Try dragging the state

variable from the source window to

the waveform window and then drag

the prediction signal from the

waveform window to the source

window. Note that the source

window highlights the definition of

the signal and puts the signal name in

the “Find” dialog at the bottom right of the source window. Pressing the arrow buttons next to that dialog will

search the source for that text.

To view the values of variables in the source window, you should first “link” the source window and the waveform

window to be in lock-step. Left click on the chains in the upper right corner of the source window and select the

same letter that is shown next to those chains for the waveform window. Now all values shown by the source

window will be from the time selected in the waveform window. To actually display the values, select “Display

Page 14: EECS 470 Tutorial (and tools reference for Winter 2013)€¦ ·  · 2014-01-10EECS 470 Tutorial (and tools reference for Winter 2013) ... Feel free to add commands if you think they

Values” from the display menu of the source window. Specific times can also be entered into the “Time” dialog at

the bottom left of the source window.

5) Finding the bug

Now that we've gone through much of the tools, we should try to determine if there's a bug in our code. The output

of this branch prediction module is the signal named "prediction." As we mentioned before, from time 25 on the

value is unknown despite the fact that the input signals are known. This means there is a bug, but where is it? For

the signal to be unknown, a signal that it relies on to determine its state must be either unknown or unconnected. So

we need to start by looking at how "prediction" gets set. The source for "tbp" should already be open, so let's use

that to trace back to where the problem is. Let's also drag the "tbp" module signals to the waveform viewer so we

can see the signals in that module. Looking at the source, we can see that "prediction" is simply set equal to a bit of

signal "state." Looking at the waveform viewer, we see that, as expected, "state" is unknown at the same times.

Now we want to check the signals that define "state." We can see that "state" either takes on a known value of 01,

or it takes on the value of "next_state." So again, now we need to trace back to which values set "next_state."

Looking at this, we can see that "next_state" is determined by "state" and "taken." We already know state is broken,

so we need to look at "taken." On the waveform viewer, we see that "taken" is always in high Z state, that it has

never been set. Because "taken" is an input into this module, we know the problem is in how the testbench is

connecting to this module. Now let's drag the "testbench" module into the source viewer so we can look for the

problem. Looking at where tbp is instantiated, we can see that there was a typo. ".taken(taekn)" should have been

".taken(taken)" on line 9. The compiler assumed "taekn" was just a wire not being driven and although it gave a

warning, it did not give a compiler error on this. These little bugs can often be very annoying to deal with.

Now that we've found the bug, we want to save the waveform viewer configuration so we can just easily reload

them when we run the waveform viewer again. It may not seem to be a big deal right now, but eventually when

you're working with hundreds of signals, only a few of which are related to a problem you're trying to debug, it can

be very annoying to try to find and place them on the waveform viewer every time. To do this, on the waveform

viewer go to file->save configuration. Type in a filename, replacing default.cfg with 470tut.cfg or, in the future, any

name you want. It will be useful to keep the names descriptive as there may be different sets of signals to look at for

different parts of a module you're testing. Now exit the waveform viewer by choosing file->exit

Use your favorite text editor to fix that typo in "tut_test.v". When you're finished, type make int to recompile

and reload the waveforms so we can double check that it's working properly now. Now on the hierarchy window,

go to file->load configuration. Select your 470tut.cfg and press OK. Your waveform window, complete with

signals, should appear. Here we can see everything is working properly now.

6) Back to the interactive waveform viewer

So far we’ve been treating the simulation as a post-processing problem. We can also debug a running simulation,

much like one debugs a C program, allowing you to debug even when you get an infinite loop and to recompile

within the gui. Only some basic useful features will be explained here. Feel free to explore more advanced features

on your own.

To begin, open up the Makefile with your favorite editor and change the SIMFILES field from tut_mod.v to

tut_mod2.v. This module has an infinite loop in it (circular combinational logic). In a small file like this, it would

be fairly easy to just open up the .v file and find the source of the infinite loop, but in larger systems pinpointing the

source of the problem will be a lot more difficult.

Try running the simulator by running make. You’ll notice that it hangs while making the simv file. Press

ctrl-C to break the process.

Do a make clean to remove any output files that may have been created. Now we will use the

interactive compiler to find where our problem is.

Start it with the commandmake int

The interactive window should appear. Now let’s find that infinite loop. To find out where it is, click “continue”.

The history should reach time 25 and then hang. The problem must be around here somewhere. Press ctrl-C to

interrupt the simulation where it stopped. We are now at time 30. Now let’s find out where we’re looping. Click

next a few times and look at the history window. We seem to be going between tut_mod2.v:11 and tut_mod2.v:12.

That means that lines 11 and 12 of tut_mod2.v are causing the problem.

Page 15: EECS 470 Tutorial (and tools reference for Winter 2013)€¦ ·  · 2014-01-10EECS 470 Tutorial (and tools reference for Winter 2013) ... Feel free to add commands if you think they

Click on Window and open up a Hierarchy window, a Waveform window, and a Source window. We know the

problem is in our module (not our testbench), so use the middle mouse button to drag tbp to the source window and

waveform window. In the source window, click Display->Show Values to monitor the values of each wire. We

want to see how we got to this state, so click on Sim->Re-exec to start over. Now, click Continue again and then

ctrl-C to interrupt the simulation. Let’s see what we have.

If we look at the source window, we can see that lines 11 and 12 are assignments to loop1 and loop2. If we click

next a few times and watch the values, we can see that both loop1 and loop2 keep changing even though no time is

actually passing. This is a sure sign of circular logic. Since loop1 is dependent on loop2, and loop2 is dependent on

loop1, the circular path is fairly obvious in this case.

But if we weren’t sure, a visual depiction of our module might help. Click on Window -> Logic to open up the

Logic window. Now drag the tbp module into this window, and we can see a diagram of our Verilog module. If you

make your window wide enough, you should be

able to see a circular loop of wires in the general

area of the loop1 and loop2 assign statements. If

you want to see how the values are changing,

click the left and right pink arrows to track

individual changes. You can also select a

specific wire and click the green arrows to track

changes on that signal.

If this were an actual design, we would now

have enough information to fix the bug. In this

example, there’s nothing to really fix, since the

loop1 and loop2 variables are not used for

anything, so we can just leave the design alone

and finish up.

There are a number of other useful features in

the interactive waveform viewer. Feel free to

explore and try other things on your own.

Page 16: EECS 470 Tutorial (and tools reference for Winter 2013)€¦ ·  · 2014-01-10EECS 470 Tutorial (and tools reference for Winter 2013) ... Feel free to add commands if you think they