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> 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     
    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.

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.