After running many training courses, Doulos tutors tend to notice certain common problems with debugging. Being good at debugging is really just about practice, and having a certain "state of mind". To help you to achieve that state of mind, here's some advice distilled over the years...
Often when errors occur you will get a great stream of errors. For instance on one of our courses we ask people to find the bugs in a deliberately buggy piece of code. Here is the output of Aldec Active-HDL with the offending code:
# Compile Entity "MUX4_TB" # Compile Architecture "BENCH" of Entity "MUX4_TB" # Error: COMP96_0078: mux4_tb.vhd : (8, 16): Unknown identifier "STD_LOGIC_VECTOR". # Error: COMP96_0064: mux4_tb.vhd : (8, 16): Unknown type. # Error: COMP96_0078: mux4_tb.vhd : (9, 30): Unknown identifier "STD_LOGIC". # Error: COMP96_0064: mux4_tb.vhd : (9, 30): Unknown type. # Error: COMP96_0104: mux4_tb.vhd : (17, 5): Undefined type of expression. # Error: COMP96_0104: mux4_tb.vhd : (13, 5): Undefined type of expression. # Error: COMP96_0104: mux4_tb.vhd : (14, 5): Undefined type of expression. # Error: COMP96_0104: mux4_tb.vhd : (15, 5): Undefined type of expression. # Error: COMP96_0104: mux4_tb.vhd : (16, 5): Undefined type of expression. # Error: COMP96_0104: mux4_tb.vhd : (18, 5): Undefined type of expression. # Compile failure 14 Errors 0 Warnings Analysis time : 16.0 [ms]
A lot of people will see the last error, and look at line 18, which is
F => TF
part of a port map. However you really should look at the first error Unknown identifier "STD_LOGIC_VECTOR". That looks pretty bad, the compiler doesn't even know what std_logic_vector is! The answer turns out to be a missing library and package i.e.:
library IEEE; use IEEE.std_logic_1164.all;
needs to be added in front of the entity. Once that is fixed, all the other errors disappear.
So always fix the first error first.
Unfortunately you can't always ignore warnings. This can be a problem when a tool creates many warnings and it is not clear which are important and which are not.
The best approach, and unfortunately the most tedious, is to understand each warning as it occurs, decide if it is important, and then either fix it, filter it out, or leave it and ignore it.
Here is an important warning from a synthesis tool
Warning (10492): VHDL Process Statement warning at alu.vhd(32): signal "Op" is read inside the Process Statement but isn't in the Process Statement's sensitivity list
This warning is interesting because most synthesis tools will actually automatically "fix" your sensitivity list, that is they will "pretend" that the missing signal is actually there. However simulation tools are not allowed to "pretend", so you will get a mis-match between simulation and synthesis. Your simulation may appear to be doing what you expect, but your hardware will behave differently. Or perhaps even more confusing, your hardware may behave correctly but your simulation will fail!
In that case the fix is easy, and if the consequences are sufficiently bad you should fix the problem.
In synthesis you may be warned about latches - again this is an important warning that you should take notice of it. There is more information about latches in VHDL and Verilog.
Simulators normally have various settings for debugging and optimization. It is a good idea to enable all debugging information, and disable all optimization: at least at first. Once you're confident your code is correct, then turn on the optimization (and turn debugging off) to get higher simulation speed.
Why do this? Because otherwise you will find problems such as:
Sometimes tools go wrong for no apparent reason. Before you send a rude email to the vendor concerned, try completely deleting and recreating your project. Quite often this will fix obscure bugs - unfortunately you don't know if the bug will occur again, but let's hope it doesn't!
If after following all the advice above, you finally find a tool bug, report it to the tool vendor. Vendors can't fix bugs if they don't know about them!
Complaining about the tool on the internet may be satisfying, but it doesn't actually get the problem fixed...