If I did wait for the clock, what is the 'rule of thumb' for signals changing at the clock edge? For example:
always @(posedge clk or negedge clk)
a <= clk;
always @(posedge clk)
data <= a;
Can I really rely on this that a or data will be the 'new' values 100% of the time?
In this case (and it's bizarre and you'd never do it, but ...), what will happen is clear.
On the rising edge of
clk, we look at the current values of
clk and
a. Assuming an initializer on
a (clearing to 0), and that a rising edge means
clk is 1, this means we schedule an assignment to a of 1, and we schedule an assignment to
data of 0 (the initial value of
a).
The next thing that happens (of interest) is a falling edge on
clk. This schedules a new assignment to
a, of 0. Since the other always block is not sensitive to the falling edge of
clk, it doesn't get triggered.
data remains the same.
Then there's another rising edge of
clk. This again schedules a new assignment of 1 to
a. It also schedules a new assignment to
data. It uses the current value of
a -- which is 0 (from the negedge event).
And so forth. It helps to draw it out on paper.