-2

so what is the difference between these two vhdl programs:

process(clk)

begin

if(clk=1)

q<=d;

end if;end process;

and this one:

process(clk)

begin

if(rising_edge clk)

q<=d;

end if;end process;

They give the exact same result, as i undersrand i dont have to use rising edge because it is already what triggered us into the process, and my professor said to us that q will keep updting if d changes ?

0

2 Answers 2

1

If we ignore the syntax errors, there are some subtle simulation differences with these two code snippets:

the first example:

process(clk)
begin
  if(clk=1) then
    q<=d;
  end if;
end process;

This process is triggered only a clk'event. A 'event occurs on any change in clk. If clk is declared as bit, then this will function the same as the 2nd code. But if its something with meta values, like a std_(u)logic, if it changes from 'U' to '1', or 'X' to '1', or anything else to '1', then q will be assigned from d.

In the second:

process(clk)
begin
  if rising_edge(clk) then
    q<=d;
  end if;
end process;

Here, again the process is only triggered on clk'event , but this time, because the rising_edge function is used, q is only assigned from d when clk changes from '0' -> '1' (or from 'L' to 'H' if clk is a std_(u)logic ).

The part your professor is talking about is synthesis. All synthesis tools generally ignore sensitvity lists, and hence will like transform the 1st code into a transparent latch, while the 2nd code becomes a register. And hence the first code will. pass through d when the clk is high. While the 2nd one will function like a DFF.

Sign up to request clarification or add additional context in comments.

1 Comment

Ignoring the sensitivity list can have the consequence of behavioral disparity between the original malformed RTL description and the post synthesis model.
1

Let us first fix the syntax errors in your two processes:

p1: process(clk)
begin
  if clk = '1' then
    q <= d;
  end if;
end process;

p2: process(clk)
begin
  if rising_edge(clk) then
    q <= d;
  end if;
end process;

In the first process q is assigned if and only if 1) there is an event (a value change) on clk, and 2) the new value of clk is '1'. So, the two processes are semantically equivalent if and only if rising_edge(clk) is true for all changes of clk with final value '1', and only these changes.

If the type of clk is bit it is the case and the two are semantically equivalent. Any VHDL simulator would behave the same. But see below for the difference between semantically equivalent and just equivalent.

If the type of clk is std_ulogic or std_logic, rising_edge(clk) is true for clk transitions from '0' or 'L' to '1' or 'H'. So the two processes are not semantically equivalent. In particular, a transition from 'X' (unknown value) or 'Z' (high impedance) or 'U' (uninitialized) to '1' is not considered as a rising edge, which makes sense. We could easily design a simulation environment that demonstrates the different behaviors.

But there is another aspect to consider: I used the term semantically equivalent and not just equivalent on purpose. Some logic synthesizers base D-flip-flop inference on syntax, not semantics. If you try, for instance, to synthesize process p1 where clk is of type bit with Vivado v2024.2 (64-bit) you will see in the logs:

WARNING: [Synth 8-614] signal 'd' is read in the process but is not in the sensitivity list
WARNING: [Synth 8-327] inferring latch for variable 'q_reg'

This is because Vivado expected one of the following syntaxes:

  • if clk'event and clk = '1' then
  • if rising_edge(clk) then

and did not consider the semantics, only the syntax. As a consequence it inferred a latch, instead of the D-flip-flop you expect, and that it would infer with process p2. This is why your teacher told you that q would keep updating when d changes. To be more accurate they should have told you "with some synthesizers, after synthesis, q would keep updating when d changes while clk = '1'". This is how a latch works: it is transparent on the enabling level of the clock.

So, if you want your design to be synthesized as a D-flip-flop, you must use the syntax that your synthesizer expects. And as rising_edge(clk) is common to bit, std_ulogic, std_logic, and all synthesizers support it, the best is to use that.

Note that if clk'event and clk = '1' then is also supported by all synthesizers I know but remember that it is not semantically equivalent to if rising_edge(clk) then. Here too you could easily design a simulation environment that demonstrates the different behaviors.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.