Not quite. VHDL is fundamentally a simulation language, which, when
written using certain common styles, allow it to be used as a source
language for hardware synthesis. This code really could have two ways
to interpret it: one in a simulation environment, which is exactly
what the official language definition explains, and one interpretation
as a hardware description, which is fuzzier. The idea behind using
certain common coding styles is to make sure the behaviour of your
code in simulation and synthesis are the same. That's what's meant by
"synthesis/simulation mismatch".
For simulation purposes, a process with a sensitivity list will run
exactly once at initialization (although in no particular order w.r.t.
other processes' initialization steps), and when the signal changes.
If you specify the wrong sensitivity list by accident, your process
won't respond as you expect (either ignoring events on the signal you
wanted to use, or firing at apparently random other times).
Generally, if you just want a process that responds asynchronously,
immediately, to a set of signals, (like if you're writing a simple
logic gate or an asynchronous memory read), you can skip the
sensitivity list altogether and the compiler will figure out the right
sensitivity list automatically, by looking at every signal that gets
read in the process. You want to either specify every signal correctly
or specify no signals at all in the sensitivity list. Otherwise
there's a good chance that you messed up.
Your question about "comparator in hardware" doesn't quite catch the
idea. If you wanted to follow this analogy, think of a process as
specifying some kind of piece of logic that might be a mixture of
clocked and combinatorial. The sensitivity list defines those inputs
which, if they have an event on them, may cause the output to change.
This means that those signals are either directly connected to the
circuit output through gates, or are used as clock input edges. (This
is admittedly a sloppy analogy.)
When you want to write something behind a clocked register (like a
counter, state machine, etc), you typically _only_ specify the clock
signal in the sensitivity list. Then you put the entire body of the
process inside an "if rising_edge(clk)..." statement. The combination
of these two things tells the synthesizer to generate the
combinatorial logic specified inside the "if" statement, with a flop
on each output signal you assign to. This again, is admittedly a
sloppy description of the synthesis process
If you write processes that don't follow one of these three styles
(clocked, combinatorial with no sensitivity, or combinatorial with
complete sensitivity), you're either doing the wrong thing (if you're
a beginner) or are trying to do something fancy (if you're a more
advanced user). If you're trying to be fancy as an advanced user,
there's still a good chance you're wrong, at least the first few
times
And so as to make sure to answer your last question:
process(port_a)
blah blah...
will run in simulation at initialization and when any subelement on
port_a (or port_a in its entirety) changes. In hardware, as long as
port_a is the only signal you look at inside your process, you should
be generating a simple combinatorial function of port_a. If
"blah_blah_bah" reads signals _other_ than port_a, or doesn't have the
complete sensitivity list (as in the 4 vs 5 signal discrepancy Mike
pointed out), you're most likely generating something which you didn't
want, regardless of whether you're simulating or synthesizing.
Hope this helps,
- Kenn