Quartus and ModelSim Tips & Tricks
Here are some things I learned during my time in ECE385 (FPGA Laboratory) and ECE411 (CPU Organization & Design) at UIUC.
You don’t have to re-build in Quartus if you made small changes.
You can just use the ModelSim command line (“Transcript”) and push up until you
see do <PROJECT NAME>_run_msim_rtl_verilog.do
. This will re-compile inside of
ModelSim, saving you the need to close and reopen it.
Set the radix to hexadecimal
385 teaches you to do it through a GUI. The equivalent command (for ModelSim’s
command window) is radix -h
or ra h
. You can try setting it to default
to this, but I never got it working.
Memory diffing debugging approach (useful for MP3)
During my semester, 411 taught us how to pull out signals to the memory list (View -> List).
We took it a step further; we compiled a known-good MP1 and a buggy MP3 and compared their memory writes. In the case of correct execution, they should be equivalent; by comparing writes from the CPU to the D-cache, we could identify the first point at which memory diverged. Then we could trace that back to a specific time in Modelsim, and then use the PC to find the instruction in the source code. We identified our final two bugs with this: a forwarding issue and a stalling issue.
This is useful if: You have a processor that does not correctly execute, and a processor that does correctly execute (i.e. MP1 and MP3). The code should also write to memory — if it only exists in the register, just pull the regfiles out instead and compare those.
You should produce two of these: one for each processor.
# In Transcript
# radix -h
ra h
# change these to your signals or drag them in from the modules window
add list dut/dmem_addr
add list dut/dmem_wdata
add list dut/dmem_write
# to remove items:
# delete list *
run -all
Note that this updates the List on every change. We’re now going to set a conditional statement that only reports changes on dmem_writes.
- List > List Preferences
- Use Gating Expression: Check the box.
- Use Expression builder:
- Click Selected Signal.
- Pick your write signal.
- Type
== 1
. - Hit Okay on all the windows.
Save: (File > Export > Tabular List).
Your .lst
will look like this. You will want to copy these before you start
the next step.
ps /testbench2/dut/dmem_addr
delta /testbench2/dut/dmem_wdata
/testbench2/dut/dmem_write
1000000 +2 83ffffe8 00000000 1
1105000 +4 83fffffc 00000000 1
1115000 +4 83ffffec 00000000 1
1525000 +4 83fff860 00000000 1
2285000 +4 83fff5d8 00000000 1
(truncated by me)
You’ll probably want to manipulate it into a nicely diff
-able format. I used Vim
macros, Python’s parse
module or Bash’s tr
might also be useful. You may
wish to save the original file, so that you still have time information.
83ffffe8 00000000 1
83fffffc 00000000 1
83ffffec 00000000 1
83fff860 00000000 1
83fff5d8 00000000 1
From here, diff a.lst b.lst
. The first line is the first divergence, i.e., the
first place you should look for a bug.
ModelSim (just ModelSim) broke because EWS changed a shared lib
This was a specific bug that we had our year (shortly before a deadline). It’s not likely to come up again (but who knows!)
It looks like ModelSim refusing to start up from Quartus.
cd
wget https://sourceforge.net/projects/freetype/files/freetype2/2.4.12/freetype-2.4.12.tar.bz2/download
tar xjvf download
cd freetype-2.4.12
./configure --build=i686-pc-linux-gnu "CFLAGS=-m32" "CXXFLAGS=-m32" "LDFLAGS=-m32"
make -j8
# now run this command in your shell every time you want to run ModelSim.
# you may need to alter it if you downloaded/compiled the library somewhere else.
export LD_LIBRARY_PATH=~/freetype-2.4.12/objs/.libs/:$LD_LIBRARY_PATH
Use Python to automatically compile RISC-V, SystemVerilog, and check runtimes
I modified some of the existing grading code provided by course staff to tighten up my debug loop. It’s available on GitHub here.