A bunch of folks have noticed that they could get timing simulation working but not behavioral. Although timing simulation is ultimately the "final test" that your design works, behavioral is a lot more effective for debugging. Here's the procedure for behavioral; also there are a bunch of useful tips interspersed:
From Quartus, run ModelSim by doing Tools->Run EDA Simluation Tool->EDA RTL Simulation (if you had no troubles running standalone Modelsim then thats fine too).
Create a new ModelSim project pay attention to what you select here:
It's good to pay attention to this and to use consistent and descriptive names. Over time, you accumulate libraries from different
projects you work on in the class, and a common problem is that students use accidentally use old compiled simulation files from previous
labs instead of the one they are working on, and don't realize it. The 00 makes it easy to find your projects in the list.
Then add your *.v
source files to the ModelSim project (note: do not add any .sdo files; those are for timing simulation
only and will result in "Failed to Find Instance" errors.) same ones that were in your Quartus project. Do NOT
add _bb.v or _syn.v files. Using the _bb.v files have caused
high-impedance output issue for students. Also add the .tfw testbench file you want to use.
Here's the big
mystery: You need to add two files to support the macros generated by
MegaWizard. They are:
C:/altera/10.1sp1/quartus/eda/sim_lib/altera_mf.v
C:/altera/10.1sp1/quartus/eda/sim_lib/220model.v
(Note: you may have a more updated version of altera on your system, and should update the version number
in the path accordingly.)
If you see instantiation errors for altsyncram, it's probably because you ommitted these files.
Do not add the _87.v or .vh files!
To simulate, go
to Processes Window; Select Compile->All; fix errors; then Simulate->Start
Simulation...; Click the plus next to 00_<proj>_lib (or whatever your test is called); select
the module name that corresponds to your testbench; hit OK.
It often feels like you are always trying to track down the
right window in ModelSim.
A useful tip is, to switch from
your current window to another one, select Window->(the window you want.)
The most useful ones after you have started your simulation are the
"sim" window and the "wave" window.
When you are initially
debugging your verilog, you will be hunting for things that look wrong;
it often is useful to go to the Sim window, right click on your top level testbench,
and select Add->To Wave->All Items In Region and Below.
This will allow you to look across all of the signals in your design and trace through your
circuit looking for parts in your verilog that are responsible for disconnected and/or red signals.
You want to make sure to look at the waveforms immediately after reset goes low; and only
pay attention to the values at the clk edge. Typically,
you find a signal that should not be red, and then trace it back through the gates that generate it,
until you find the signal that initially caused redness. It is important to do this right after reset,
because one red spreads to your registers, and you have feedback (for instance for your pc_r register),
you will just find that red is spreading from the output of the register to the input.
Later on, when your design is mostly working but you are tracking down specific problems,
you may be more selective in the signals you examine. You can drag items from the
"sim" window over to the left side of the wave window.
This will
show most of your signals, correlated over time. This is the main way that you
debug hard bugs. One of the first things you want to do is make sure you have a
reasonable time scale. You may be zoomed in or out too much. The best way to
calibrate is to look for your clock signal; but to do that, you first need to
simulate for a little. There's a text box that usually starts out as "0
ps"; you can change that to "200 ns" or so, and that will cause
your machine to simulate 10 or so cycles when you push the first button to the
right of the text box (mouse-over and you will see a tooltip that says
"Run"). After you've clicked on that once or twice, then right click
on the wave window to get a menu that will let you zoom in and out. You want to
adjust the zoom so the time scale is in 10's of ns or so, and you can see your
clock waveform.
For your testbench, watch out when your testbench changes inputs to your module via #(delay), where those delays fall on the positive edge of the clock. This can cause race conditions. It's safer to assert inputs on the negative edge of the clock ( You should use the construct @ (negedge clk) inside your initial statements to do this.
Generating hex files. The lab2a.hex file provided should be fine to use. You can also generate a .hex file of your own (in this case the .hex files was just 64 17-bit values, starting at 0 and increasing by 1) inside Quartus via New->Hexadecimal (Intel-Format) File, and then filling in the values you want and saving. This is what I did.
Using hex files. If ModelSim can't find your hex file, it will complain after you first try to step some time in your simulation (see above for how to do that.) You can see the error by choosing Window->Transcript (or sometimes Window->More..->Transcript.)
The restart_i signal serves
as the reset signal for the fetch unit. You will scan for this signal; and then
examine each pipeline stage to
see if the correct data is appearing. Things to check for first are "high impedance"
signals (typically not connected) and the "spread of red". The spread
of red is basically undefined or unitialized signals that propagate through
your circuit. You want to look back and find the earliest signal that is red
that should not be.Then you jump to the
verilog and trace the derivation of that signal back further.
You can add $display statements in your testbench to display state, or even to
print out error messages (see my fifo.v example, which checks for under/over
flow of the fifo). The synopsys translate off tells your synthesizer to ignore
those statements when generating a circuit; but the statements work fine in
behavioral simulation. Note that the output shows up in the
"Transcript" Window. You can also use $monitor statements to print
out values whenever they change. This is nice if you're more into printf-style
debugging than using the waveform viewer (typically for the really hairy timing
related bugs, you need the waveform.)
You probably didn't know this, but in behavioral testbenches, you don't need to
route signals to the top level, you can just traverse the hierarchy with
".". E.g.
$monitor("rptr: %x",UUT.fetch_fifo.rptr_r);
which reads a signal (UUT.fetch_fifo.rptr_r) three modules deep.
After you have debugged your design with behavioral simulation (this is easier because you can see all of the signals inside your design),
then it's time to move to gate-level simulation. This verifies that your design works at the speed that your testbench drives it at.
0. Make sure you've debugged everything in behavioral simulation. Timing simulation is much harder to debug because of lack of visibility.
1. First, in Quartus, make sure Quartus is outputing .svo files (SystemVerilog) and not .vho (VHDL) files. You can do this by going to "EDA
Netlist Writer" (it's in the "Task" pane, beneath Assembler and TimeQuest timing analyzer) Double click on "Edit Settings." For
Simulation, it should say "ModelSim-Altera and System Verilog HDL". If it does not, double click on that line, and fix it.
2. Do a complete compile of your design. Check transcript window for errors. If you used x.y.z to peek inside your module during behavioral
simulation, you will have to guard it with an
`ifdef BEHAVIORAL
`endif
and then do a
`define BEHAVIORAL
when you want to do behavioral simulation and enable that stuff.
2a. Check the resource levels of the compiled design. If frequency is initially very high (e.g. over 150 MHz), or area is very close to zero, it means that there was a synthesis issue and that your design has been compiled away.
3. Click Tools->Run EDA Simulation Tool->EDA Gate Level Simulation... If you gives you some error about a file, it's maybe because you
already have a project open in Modelsim. ModelSim will startup.
4. In ModelSim project pane, File->New->Project.. Enter in good names, see above, use 00_<module>_gate_lib
and 00_<module>_gate_project,
then Click "Add Existing File" and find your .svo file (this is your
entire post-synthesis design compiled into one verilog file), and your .tfw (test bench verilog file).
5. Do a Compile->Compile All. Check transcript window to ensure no errors.
6. Simulate->Start Simulation...
Under libraries, select "browse.." and add C:\altera\10.1sp1\modelsim_ase\altera\verilog\cycloneii (path may be slightly different for you.) Under SDF, click "Add.." and add your
_v.sdo file (I found it in the simulation/modelsim subdirectory of my project), and enter in the box "Apply to Region" /UUT (that's the instance name of your module in the .tfw file, if you see errors about "Failed to find INSTANCE",
this is what's missing.)
Under design tab, select your test bench file (usually under the "work" flippy-plus tab).
7. You should see a flurry of motion from ModelSim. Check the Transcript window to see if there were any errors.
8. Now you are just about ready to simulation -- drag "test" (the module name of your test bench) to the "wave" window. Since this is
gate-level simulation, it will be harder to see signals inside your actual module, so you are mostly restricted to signals outside the
test. Typically, you will only be able to decipher registers, and even then it will be messy, but not impossible. One approach is to wire signals out to the "top-level" so that you can see them. Later in the class, we will show you how you can bundle signals together ina systemverilog struct that will make it easier to add new debug signals and expose to the top level see this page.
9. Apart from these significant hurdles, it's much just like behavioral simulation.