• No results found

Flip-flops

In document Digital System Design With VHDL (Page 134-143)

sequential logic blocks

Q, Qbar : out std_logic);

6.2 Flip-flops

6.2.1 Edge-triggered D flip-flop

In the previous chapter the principle of synchronous sequential design was described.

The main advantage of this approach to sequential design is that all changes of state occur at a clock edge. The clock edge is extremely short in comparison to the clock period and to propagation delays through combinational logic. In effect, a clock edge can be considered to be instantaneous. In VHDL, there are a number of ways to detect when a clock edge has occurred and hence to model an edge-triggered flip-flop.

The IEEE symbol for a positive edge-triggered D flip-flop is shown in Figure 6.3.

Again, the number 1 shows the dependency of D on C. The triangle at the clock input denotes edge-sensitive behaviour. An inversion circle, or its absence, shows sensitivity to a negative or positive edge, respectively.

The simplest VHDL model of a positive edge-triggered D flip-flop is given below.

library IEEE;

use IEEE.std_logic_1164.all;

120 VHDL models of sequential logic blocks

entity D_FF is

port (D, Clock : in std_logic;

Q : out std_logic);

end entity D_FF;

architecture behavioural of D_FF is begin

p0: process is begin

wait until (Clock = '1');

Q <= D;

end process p0;

end architecture behavioural;

This form of the process statement was first introduced in the last chapter. The process does not have a sensitivity list; instead it contains a wait statement.

A process may have either a sensitivity list or one or more wait statements, but not both. (A process could have neither a sensitivity list nor wait statements, in which case it will be continually re-evaluated. This is an error in VHDL.) The wait state-ment causes the process to suspend (i.e. to become inactive) until the condition speci-fied in the wait statement becomes true. In this case the condition is that Clock becomes logical 1. Once the condition becomes true, the next statement is executed, the process restarts and then waits until the next rising clock edge. There are other forms of the wait statement that we will meet later.

An alternative model of a positive edge-triggered D flip-flop is as follows:

architecture alternative of D_FF is begin

p0: process (Clock) is begin

if (Clock = '1') then Q <= D;

end if;

end process p0;

end architecture alternative;

The process is re-evaluated whenever Clock changes state. The if statement is then used to check that Clock has changed to a logical 1. This model is not exactly equivalent to the previous model. The following model is, however, exactly equivalent to the second model:

architecture equivalent of D_FF is begin

p0: process is begin

if (Clock = '1') then Q <= D;

end if;

Flip-flops 121

D Reset

Q 1D

C1 Clock

R

Set S

Figure 6.4 Positive edge-triggered D flip-flop with asynchronous reset and set.

wait on Clock;

end process p0;

end architecture equivalent;

A process with a sensitivity list is equivalent to a process with a wait on statement at the end of the process. The wait on form of a wait statement causes execution of the process to be suspended until there is a change in the signal (or signals) listed. It is important to understand that the first version of the flip-flop model differs from the second and third versions. At the beginning of a simulation, at time 0, each process in a VHDL description is executed as far as the first wait statement. Thus in the first model, the wait statement occurs at the beginning of the process, with the assignment statement following it. In the second and third versions, the assignment statement is before the wait statement, and thus would be executed at the start of a simulation if the if statement is true. In practice, the first and second models would both be inter-preted by a synthesis tool as positive edge-triggered flip-flops. The third model would simulate as a positive edge-triggered flip-flop, but would probably not be correctly interpreted by a synthesis tool.

Similarly, a negative edge-triggered flip-flop can be modelled by detecting a transi-tion to logical 0:

architecture neg_edge of D_FF is begin

p0: process is begin

wait until (Clock = '0');

Q <= D;

end process p0;

end architecture neg_edge;

6.2.2 Asynchronous set and reset

When power is first applied to a flip-flop its initial state is unpredictable. In many applications this is unacceptable, so flip-flops are provided with further inputs to set (or reset) their outputs to 1 or 0, as shown in Figure 6.4. Notice that the absence of any dependency on the clock implies asynchronous behaviour for R and S.

122 VHDL models of sequential logic blocks

These inputs should be used only to initialize a flip-flop. It is very bad practice to use these inputs to set the state of a flip-flop during normal system operation. The rea-son for this is that in synchronous systems, flip-flops change state only when clocked.

The set and reset inputs are asynchronous and hence cannot be guaranteed to change an output at a particular time. This can lead to all sorts of timing problems. In general, keep all designs strictly synchronous or follow a structured asynchronous design methodology.

A VHDL model of a flip-flop with an asynchronous reset must respond to changes in the clock and in the reset input. Therefore we must use a process with a sensitivity list that includes both these signals. The wait until and wait on forms of the flip-flop model cannot be written to include checks on both inputs, so we use an if statement. The process will be activated whenever Clock or Reset changes. If we make the reset active low, Q is forced to 0 while the reset is 0, irrespective of the state of the clock. Therefore the first test in the if statement must be made on the Reset signal:

if (Reset = '0') then Q <= '0';

If this signal is not asserted, we then need to check whether we have a rising edge on the clock. Note, however, that at this point, simply checking to see whether the clock is at 1 is not sufficient, because the process might have been activated by the Reset sig-nal changing to 1. Thus we have to check that the clock is at 1 and that it was a transi-tion on the Clock signal that activated the process. This can be done by checking the 'EVENT attribute of the Clock signal. This attribute is true only if a change has occurred to that signal at the current time.

elsif (Clock = '1' and Clock'EVENT) then Q <= D;

Another way to detect an edge is to check the 'STABLE attribute. This is true if the signal has not changed at the current time.

elsif (Clock = '1' and not Clock'STABLE) then Q <= D;

The entire flip-flop model is now shown below.

library IEEE;

use IEEE.std_logic_1164.all;

entity D_FF_R is

port (D, Clock, Reset : in std_logic;

Q : out std_logic);

end entity D_FF_R;

architecture behavioural of D_FF_R is begin

p0: process (Clock, Reset) is

Flip-flops 123

begin

if (Reset = '0') then Q <= '0';

elsif (Clock = '1' and Clock'EVENT) then Q <= D;

end if;

end process p0;

end architecture behavioural;

An asynchronous set can be described in a similar way (see Exercises).

It is possible for a flip-flop to have both an asynchronous set and reset. For example:

library IEEE;

use IEEE.std_logic_1164.all;

entity D_FF_RS is

port (D, Clock, Reset, Set : in std_logic;

Q : out std_logic);

end entity D_FF_RS;

architecture behavioural of D_FF_RS is begin

p0: process (Clock, Reset, Set) is begin

if (Set = '0') then Q <= '1';

elsif (Reset = '0') then Q <= '0';

elsif (Clock = '1' and Clock'EVENT) then Q <= D;

end if;

end process p0;

end architecture behavioural;

This may not correctly describe the behaviour of a flip-flop with asynchronous inputs because asserting both the asynchronous set and reset is usually considered an illegal operation. In this model, Q is forced to 1 if Set is 0, regardless of the Reset signal. Even if this model synthesizes correctly, we would still wish to check that this condition did not occur during a simulation. A technique to do this is described later in this chapter.

6.2.3 Rising_edgeand falling_edge

All these flip-flop models detect a transition to a given state. If the clock were declared to be of type BIT, the only transitions of the clock that would be possible are 0 to 1 and 1 to 0. With the std_logic type, there are nine logic states and hence eight possible transitions to any given state. The flip-flop models shown will trigger on, for instance, an H to 1 transition. This is not how a real flip-flop behaves. We can specify a true 0 to 1

124 VHDL models of sequential logic blocks

transition by checking both the current value of the clock and its last value. This is done using the 'LAST_VALUE attribute:

architecture true_edge of D_FF_R is begin

p0: process (Clock, Reset) is begin

if (Reset = '0') then Q <= '0';

elsif (Clock = '1' and

Clock'LAST_VALUE = '0' and Clock'EVENT) then Q <= D;

end if;

end process p0;

end architecture true_edge;

This has now defined a true 0 to 1 transition, but this form is not recognized by all syn-thesis tools. Further, an L to 1 (weak logic 0 to strong logic 1) transition would not be recognized in a simulation. The standard logic package simplifies all these cases by providing a rising_edge and a falling_edge function.

architecture r_edge of D_FF_R is begin

p0: process (Clock, Reset) is begin

if (Reset = '0') then Q <= '0';

elsif rising_edge(Clock) then Q <= D;

end if;

end process p0;

end architecture r_edge;

It is strongly suggested that these functions be used to detect clock edges.

6.2.4 Synchronous set and reset and clock enable

Flip-flops may have synchronous set and reset functions as well as, or instead of, asyn-chronous set or reset inputs. A synasyn-chronous set or reset takes effect only at a clock edge. Thus a VHDL model of such a function must include a check on the set or reset input after the clock edge has been checked. It is not necessary to include synchronous set or reset inputs in the process sensitivity list because the process is activated only at a clock edge. This is shown in IEEE notation in Figure 6.5. R is now shown to be dependent on C and is therefore synchronous.

architecture synch_reset of D_FF_R is begin

p0: process (Clock) is

Flip-flops 125

D Reset

Q 1D

C1 Clock

1R

Figure 6.5 Positive edge-triggered D flip-flop with synchronous reset.

D Enable

Q 2D

1C2 Clock

G1

Figure 6.6 Positive edge-triggered flip-flop with clock enable.

begin

if rising_edge(Clock) then if (Reset = '0') then

Q <= '0';

else Q <= D;

end if;

end if;

end process p0;

end architecture synch_reset;

Similarly, a flip-flop with a clock enable signal may be modelled with that signal checked after the edge detection. In Figure 6.6, the dependency notation shows that C is dependent on G, and D is dependent on (the edge-triggered behaviour of ) C.

library IEEE;

use IEEE.std_logic_1164.all;

entity D_FF_E is

port (D, Clock, Enable : in std_logic;

Q : out std_logic);

end entity D_FF_E;

architecture behavioural of D_FF_E is begin

p0: process (Clock) is begin

if rising_edge(Clock) then if (Enable = '1') then

126 VHDL models of sequential logic blocks

Q <= D;

end if;

end if;

end process p0;

end architecture behavioural;

A synthesis system is likely to interpret this as a flip-flop with a clock enable. The following model is likely to be interpreted differently, although it appears to have the same functionality:

architecture gated_clock of D_FF_E is signal ce : std_logic;

begin

ce <= Enable and Clock;

p0: process (ce) is begin

if rising_edge(ce) then Q <= D;

end if;

end process p0;

end architecture gated_clock;

Again, the D input is latched if Enable is true and there is a clock edge. This time, however, the clock signal passes through an AND gate and hence is delayed. The D input is also latched if the clock is true and there is a rising edge on the Enable sig-nal! This is another example of design that is not truly synchronous and that is therefore liable to timing problems. This style of design should generally be avoided, although for low-power applications the ability to turn off the clock inputs to flip-flops can be useful.

6.2.5 Timing and logic checks

In developing digital systems, we assume certain types of behaviour such as discrete logic levels. A further assumption, discussed in Chapter 12, is that only one input to a flip-flop can change at one time. For example, the D input to a flip-flop must have changed and be stable for a short period before the clock changes. Failure to observe this condition may result in an unpredictable output. In the worst case, the output of a flip-flop can exist in a metastable state somewhere between logical 1 and logical 0 for an indeterminate time. This unpredictability is not desirable. If we were verifying our designs by simulation, it would clearly be helpful if we were alerted to possible timing problems and to illegal combinations of inputs. VHDL provides the assert statement to generate warning messages. The assert statement is ignored by synthesis tools.

The form of an assert statement is as follows:

assert condition report message severity level;

Flip-flops 127

The condition is a Boolean expression that we normally expect to be true. If the con-dition is false the message in the report part is printed. The severity level may be NOTE, WARNING, ERROR or FAILURE. An error or failure will usually cause the sim-ulation to halt at that point. The report and/or the severity clause may be omitted.

It is also possible to omit the assert part, in which case the message in the report part will always be printed. Assert statements may be included in sequential code or in concurrent code. The difference is that a concurrent assert will be activated only when one of the signals in the condition clause changes, while the sequential assert will be evaluated whenever it is reached in a process or other sequential block.

In Section 6.2.2 it was noted that an asynchronous set and reset should not both be at logical 0. This condition could be verified by the following assert statement:

assert (Set = '1' or Reset = '1')

report "Set and Reset are both asserted"

severity WARNING;

Thus if both inputs are at 0, the message is printed. Because we are stating what we expect to be true, the logic may appear to be counter-intuitive. We could equally state the condition that we are checking for and invert it:

assert (not(Set = '0' and Reset = '0'))

If we wish to check that the D input has stabilized before the clock input changes, we can use a form of the 'STABLE attribute:

assert (not(Clk = '1' and Clk'EVENT and not D'STABLE(3 NS))) report "Setup time violation"

severity WARNING;

Thus, we expect that the condition that there has been a clock edge and D has not been stable for 3 ns is not normally true.

The hold time of a flip-flop is defined as the time after a clock edge for which a data input must be stable. This can be similarly defined:

assert (not(Clk = '1' and D'EVENT and not Clk'STABLE(5 NS))) report "Hold time violation"

severity WARNING;

The assert statement is passive, meaning that there is no signal assignment.

Passive processes and statements may be included in the entity part of a declaration. The advantage of doing this is that the check applies to all architectures and does not have to be restated for every architecture. A model of a D flip-flop with an asynchronous reset and set, a clock enable, setup time and asynchronous input checks and propagation delays is shown below.

library IEEE;

use IEEE.std_logic_1164.all;

128 VHDL models of sequential logic blocks

entity D_FF is

generic (CQ_Delay, SQ_Delay, RQ_Delay: DELAY_LENGTH :=

5 NS;

Setup: DELAY_LENGTH := 3 NS);

port (D, Clk, Set, Reset, Enable : in std_logic;

Q : out std_logic);

begin

assert (not(rising_edge(Clk) and not D'STABLE(Setup))) report "Setup time violation"

severity WARNING;

end entity D_FF;

architecture behavioural of D_FF is begin

p0: process (Clk, Set, Reset) is begin

assert (not(Set = '0' and Reset = '0')) report "Set and Reset are both asserted"

severity ERROR;

if Set = '0' then

Q <= '1' after SQ_Delay;

elsif Reset = '0' then Q <= '0' after RQ_Delay;

elsif rising_edge(Clk) then if (Enable = '1') then

Q <= D after CQ_Delay;

end if;

end if;

end process p0;

end architecture behavioural;

In document Digital System Design With VHDL (Page 134-143)