lessons learned
General lessons
- Synchronous means: only clk in the sensitivity list, and all code within an if(rising_edge(clk)). EDIT: NOPE. you can have synch processes with async set/reset, and then those will be in the sensitivity list, and you'll have more than an if. also maybe other signals if you're trying to make a latch??
- Variables are bad and cause spooky things and make people who understand vhdl better than I do complain. Probably avoid them, unless it's just for a constant. EDIT: According to the book: "variables should only be used as iteration counters in loops or as temporary values when executing an algorithm that performs some type of calculation. It is possible to use variables outside of these areas, but it should be avoided." -p110
- Identifying Moore vs Mealy SMs: According to the book, if your output is assigned unconditionally (not inside an if/elsif/else) in the different states, that's a Moore. If you see an if/elsif/else with the states assigned there, that's Mealy. So our FSM is a mealy because the next_state is determined by those if conditions (that depend on count and rise/fall).
Common compilation errors
- Make sure only 1 process drives each signal (I think this is just for unresolved types, which is all we should use unless we really know what we're doing, which we don't).
- For AXI FSM READ, issues were solved by adding more states. Instead of having 1 waiting state with an IF that set the output depending on the address, it helped us to determine which state to go to before with an if, and then setting different outputs in these states. I don't know why.
Synthesis issues
-
If it's read as input in a combinatorial process, it needs to be in the sensitivity list. Outputs should not be in the sensitivity list.
-
All signals need drivers.
-
If possible, connect all ports. Meaning, if you say something takes all 32 pins in, use all 32 of them. Otherwise make it only take as input the pins it needs.
-
Initializations outside of the begin/end of the process don't work when actually synthesizing. These are "before the beginning of time".
-
Good practice is to initialize all output (to constants or signals from synchronous processes, see 6) right after the begin of your combinatorial process. You should also set the value of any constants here too.
-
Remove inferred latches. To find them, look at your combinatorial process. If you are reading as input and assigning anything that isn't a constant and didn't come out of synchronous process, it's a latch. remove it by using the synchronous process to remember stuff, or storing only constants - and, if storing only constants, make sure every possible branch (use an else) stores the constant.