On a pure simulation semantics point of view, your first form is a real rising edge detector if and only if:
- there is only
clk
in the sensitivity list (your case)
- and the type of
clk
is bit
and clk
is not declared with initial value '1'
like in:
signal clk: bit := '1';
If this holds, your -- do something
will be executed only on rising edges of the clk
. To understand why we need to look at the equivalent process with wait
statement (yes, sensitivity lists are just a short hand for more general processes):
signal clk: bit;
...
process is
begin
if(clk = '1') then
--Do Something
end if;
wait on clk;
end process;
If clk
is of type bit
, the simulator initializes it with the leftmost value of enumerated type bit
at the beginning of the simulation. As bit
is declared:
type bit is ('0', '1');
its leftmost value is '0'
and clk
is initialized to '0'
. On the first execution of the process the if
test fails and the process suspends on the wait
statement. From now on, it will resume only on value changes of clk
. If the value change is a falling edge ('1'
to '0'
) the if
test fails and the process suspends on the wait
statement. If the value change is a rising edge ('0'
to '1'
) the if
test passes, your -- do something
is executed and the process suspends on the wait
statement.
Because the conditions I listed above are quite constraining (especially the two first ones), and because many logic synthesizer don't really do semantics analyses but syntactic analyses (they "recognize" synchronous processes if they match certain coding patterns), your second form with rising_edge
is preferable. It is standard since a long time, enough for being supported by all logic synthesizers I know.
A bit more explanation about the condition "there is only clk
in the sensitivity list": as explained by Matthew, as soon as you have more than one signal in the sensitivity list (asynchronous set or reset, for example) you must use something else to express the condition. The event
signal attribute is a possibility:
process(clk, reset)
begin
if clk = '1' and clk'event then
This really says that an event just occurred on clk
and that the new value of clk
is '1'
. While with:
process(clk, reset)
begin
if clk = '1' then
the if
test passes if an event happens on reset
while clk
is high. Usually not what you want.
Most synthesizers will do what you want with if clk = '1' and clk'event
but it is not the whole story. If the type of clk
is not bit
but a multi-valued type like std_ulogic
, for instance, the test passes for any transition of clk
that ends with '1'
. Like 'X'
to '1'
or 'U'
to '1'
. Usually not what you want, at least during simulations. This is where the rising_edge
function becomes handy: it does the right thing. It uses the current value of its signal parameter s
, plus s'event
and s'last_value
. It returns true only for transitions that you would consider as a true rising edge:
'0' -> '1'
'L' -> '1'
'0' -> 'H'
'L' -> 'H'
Your simulations work as expected and all logic synthesizers are happy with that because it is one of the patterns they recognize.