This goes to the fundamentals of how VHDL works (and Verilog for that matter). First of all, you need to know the difference between signals and variables:
1. Signals are only updated when a process suspends, and will take the last assignment given to them
2. Variables are updated immediatly.
So for the following two bits of code give different results:
Code:
signal s : integer := 0;
variable v : integer := 0;
.....
--clocked process
s <= s + 1;
s <= s + 1;
s <= s + 1;
v := v + 1;
v := v + 1;
v := v + 1;
Here, s will increment by 1 on every clock cycle, because it takes the final assignment only, and v will increment by 3 as it's value is updated imediatly.
This is important, as it allows you to model pipelines and other registers inside a clocked process:
Code:
--clocked process
a <= input
b <= a;
c <= b;
op <= c;
so as each signal is only updated when process suspends, each value is assigned the "old" value of the previous signal, meaning you get a pipeline delay of 4 clock between input and output. If you did the same thing with variables:
Code:
--clocked process
a := ip;
b := a;
c := b;
op <= c;
The output would only have a 1 clock latency, as the variables are all updated immediatly. Just to confuse you more - think about what this does:
Code:
process(clk)
begin
if rising edge(clk) then
op <= c;
c := b;
b := a;
a := ip;
end if;
end process;
Now, also asside from this, the simulation doesnt run in absolute time, it runs in delta cycles. A delta cycle is an infinitesimal time step. Signals are scheduled to update within a specific delta cycle, and a signal assignment takes a single delta to complete. So consider the following unclocked code:
Code:
--outside a process
a <= ip;
b <= a;
c <= b;
op <= c;
for the input to get to the output will take 4 delta cycles in simulation, as a will update when ip updates, b when a updates, finally propogating through to updating the output. HDL is a language of consequences, so updating one signal will cause other signals to get updated. And because the time step is a single delta, it can model signal propgation through wires, logic etc. The register comes in with a clock - the rising edge of the clock causes the clocked processes to update the signal assignments in them, which in turn will cause any other logic to update if it is unclocked.
The reason we can model flip-flips is that all clocked signals are updated within the same delta. Because the clock then does not rise again for N ns, and clocked processes are only sensitive to the clock, the signals are not updated again until the next clock.