32-bit counter and test bench
Nice with some HDL on Code Review. I'll contribute with my opinions. All-in-all, I find the code all well-written.
Opinions not already covered in previous answers

A more standard way of setting count at reset would be (others =&gt; '0').

That is, as opposed to hard-coding a bit/hex literal - even if you for some reason hard-code the width as you have done, (others =&gt; '0') is more standard in this case.


You might have a good reason for asynchronous reset, but if not, synchronous reset is a better habit.

You often see these asynchronous resets, it is unfortunately a more common habit, since that's what is (or was) most often taught.
See my motivations here: http://www.fpga-dev.com/resets-make-them-synchronous-and-local/



Opinions already covered/partly covered
Somewhat in order of importance (in my subjective opinion).

Define the roll-over behaviour.

The behaviour is actually defined for an unsigned in numeric_std: any carry bits will be ignored so the unsigned will roll-over. However, neither simulators nor synthesis tools should be trusted on following this. (And even less, humans reading the code.) Also; it is good to really think about what behaviour you desire, or is the most stable: roll-over or saturate? I'll take the chance to give two comments on this choice:

For synthesis, roll-over rather than saturation will yield less logic and improved timing. The tool will be able to use a counter macro right-off.
If reaching max count is expected never to happen, add an assertion so a simulation will flag in that case. Then still code the RTL behaviour explicitly to roll-over (less logic, better timing) if there aren't stability reasons to code it to saturate.




Parameterize the width. Put it in a constant or generic.

Generate the clock separately (e.g. clk &lt;= not(clk) after 10 ns;, and make sure to init clk to '1'.

This is more standard and more readable.
Then, when coding your stimuli, do not dead-reckon the time for stimuli assignments, instead, use wait until rising_edge(clk); etc. This makes code more stable, and gives deterministic and proper times for the stimuli changes (not only in regards to time, but also to simulation deltas, which is equally important).


Use entity instantiation

More details and motivation: http://www.fpga-dev.com/leaner-vhdl-with-entity-instantiation/



Simulation performance

There's nothing wrong in coding the RTL of the counter like this, but it could be noted that there is a simulation performance gain possible: Make count a variable, local to the process, do tests and arithmetics on this variable, and in the end of the process drive the variable to a counter signal (defined in the architecture).

Others

Thumbs up for self-checking test benches.