Reputation: 509
if you had a process like this for example:
process (clk)
if (var = '1') then
var2 = '1';
end if;
if (var2 = '1') then
//do something
end if;
end process;
Would the 2nd if statement get executed on the next clock cycle, or would it get executed as soon as var2 = '1' is executed?
Would the below code do exactly the same thing as the code above?
process (clk)
if (var = '1') then
var2 = '1';
end if;
end process;
process (var2)
if (var2 = '1') then
//do something
end if;
end process;
If someone could explain the timing issues that would be great.
Upvotes: 1
Views: 3906
Reputation: 16832
If your var
s are variables, then you can't sensibly do the second option as you can't use variables across processes (in most circumstances, see later). If they are actually signals, then yes you can.
In the first code - if they are variables, then yes, they will update immediately and the second part of the code will run.
If they are signals then the second if
block will only run next time around, as signals are only updated at the end of the process that writes to them.
The second example code will run the second process in the next "delta cycle" after the first one runs, as it is sensitive to the change on var2.
You can use variables between processes, but they have to be specified as shared variable
s. If you do that with "straight" shaed variables, you run the risk of hideous Verilog-like race conditions as the order of reading and updates is undefined.
You should make them of a protected type
which is a bit OO-like and has methods to operate on the values which allows accesses to be atomic across multiple processes.
Upvotes: 3
Reputation: 7755
In your first piece of code - As var2
is a variable it will get the new value immediately. Therefore the if
statement will see the new value, and //do something
would happen in the same time slice.
(//
comments? Really? This is VHDL. We used --
)
Your second piece of code wont work. Variables are scoped to a process, and can't be used to transfer values between processes. You have to use signals, and so the rules change. Consider this code:
signal sig : std_logic := 1;
signal sig2 : std_logic := 0;
process (clk)
if (sig = '1') then
sig2 <= '1';
end if;
if (sig2 = '1') then
-- do something
end if;
end process;
process (sig2)
if (sig2 = '1') then
-- do something else
end if;
end process;
Initial conditions: sig
is 1
and sig2
is 0
, so we're just waiting for a clk
edge.
When the clock edge arrives we enter the first process we see that sig
is 1
and assign 1
to sig2
. All simple so far, but because sig2
is a signal the assignment wont happen until the process completes. Than means than when we compare sig2
to 1
on the next line, it will be false (sig2
is still 0
for now), and we won't -- do something
. We then end the process.
Now, because at the end of the first process sig2
changed value 0 -> 1
the second process will be triggered (it's sensitive to sig2
). It sees that sig2
is 1
and so it will -- do something else
.
When the next clock edge comes (and it could be a negative edge with this code), sig2
is still 1
and so now we'll -- do something
, and we'll do that for every clock edge.
In summary the order of events for this code would be:
Clk : 0->1
Sig2 : 0->1
-- Do Something Else
Clk : 1->0
-- Do Something
Clk : 0->1
-- Do Something
Clk : 1->0
-- Do Something
Clk : 0->1
-- Do Something
.........
When you understand that ordering, you'll understand an important part of how VHDL schedules things.
Upvotes: 2