Sequential Circuits
Concurrent statements and sequential statements
The VHDL code of the 1-bit adder is shown below.
library IEEE;
use IEEE.std_logic_1164.all;
entity adder1bit is port (
a,b,cp: in std_logic;
s,c: out std_logic );
end adder;
architecture dflow of adder1bit is
signal ab,bb,cb std_logic;
begin
ab <= not a;
bb <= not b;
cb <= not c;
s <= (ab and bb and c) or (ab not b not cb) or (a not bb not cb) or (a not b not c);
c <= (a not b not cb) or (a not bb not c) or (a notd b);
end dflow;
For this circuit to work, all the connections specified must be active at the same time. That means, all the
statements must be activated at the same time. Therefore they are called concurrent statements. This is
different from ordinary programming languages where the statements of a code a executed one after the other
(sequentially).
The only exception to this concurrent processing in VHDL occurs within PROCESS statements. Within a
PROCESS statement, execution happens sequentially, but the process itself is executed in parallel with other
statements within the statement section.
The Process Statement
The general format of the process statement is as follows.
process [ ( sensitivity_list ) ]
process_declarative_part
begin
process_statement_part
end process [ process_label ] ;
The sensitivity list can contain one or more signals. The statements inside the process are activated only if a
transition occurs in a signal listed in the sensitivity list. A process which does not contain a sensitivity list is
called a non-sensitive process and a process that does contain a sensitivity list is called a sensitive process.
The process statement part consists of a series of sequential statements which represents a single action during
simulation.
Following is an example for a non-sensitive process.
process
begin
WAIT UNTIL (rising_edge(clock));
q <= d AFTER delay;
qb <= NOT(d) AFTER delay;
end process ;
In this case, The two signal assignments are made only after a rising edge of the clock signal occurs.
During a simulation, a process executes until a wait statement or the end of process is reached. Only the last
signal assignment inside a process to a given output is made.
For example,
c <= a AND b AFTER 0 ns;
1
c <= d OR e AFTER 10 ns;
would be equivalent to: c <= d OR e AFTER 10 ns;
The following is an example for a sensitive process.
process (a, b)
begin
c <= not(a and b) after 10 ns;
end process;
Every time a change (rising edge or a falling edge) occurs in either of the two signals listed, the statement c <=
NOT(a AND b) AFTER 10 ns; will be executed.
Note that, in a sensitive process, wait statements are not allowed.
D Flip-Flop
The D flip-flop is one of the simplest sequential circuits. For describing sequential circuits, we have to make use
of the process statement.
A VHDL code for a D flip-flop is shown here.
library IEEE;
use IEEE.std_logic_1164.all;
entity dff is port (
d,clk: in std_logic;
q: out std_logic );
end dff;
architecture rtl of dff is
begin
process(clk)
begin
if clk’event and clk = ’1’ then
q <= d;
end if;
end process;
end rtl;
A clk’event is any change change of the signal clk. If the signal clk has the value 1 after an event, the event
must be a rising edge.
Notes on Synthesis
It is important to remember a VHDL may have different behaviour during simulations and in synthesis. Following are a few such points to remember regarding synthesis:
• Sensitive processes do not synthesize well. Most synthesizers drop the sensitivity list.
• Use only one wait statement within a process, preferably at the top.
• Latches may or may not inferred by the synthesizer depending on the way the process is written.
The following code will result in a latch.
process(clk)
begin
if clk = ’1’ then
q <= d;
end if;
end process;
The following code will result in a register.
process(clk)
begin
2
if clk’event and clk = ’1’ then
q <= d;
end if;
end process;
The code below will produce a combinational circuit.
process(clk)
begin
if clk = ’1’ then
q <= d;
else
q <= ’0’;
end if;
end process;
State Machines
There are two types of state machines - Mealy and Moore. A state machine which uses only entry actions, so
that its output depends on the state, is called a Moore model. A state machine which uses input actions, so
that the output depends on the state and also on inputs, is called a Mealy model.
Mealy Model
Inputs
Combinational
State
Output
Circuit
Memory
Logic
(Next−State
Logic)
Outputs
clk
Clock
Next State
Output
=
f (Current State, Inputs)
= g(Current State, Inputs)
Moore Model
Inputs
Combinational
State
Output
Circuit
Memory
Logic
(Next−State
Logic)
Outputs
clk
Clock
Next State
Output
=
f (Current State, Inputs)
= g(Current State)
In both cases, a state machine can be modeled with three main components - Next State Logic implemented as
a combinational circuit, the State Memory and the Output Logic.
Design of a Mealy Machine
Consider the Mealy machine described by the state machine (with an input A and an output Z) shown below .
3
A=0
A=1
Z=1 if A=1
0 if A=0
ST1
Z=1 if A=0
0 if A=1
A=1
A=0
A=0
ST0
A=1
ST2
Z=1 if A=1
0 if A=0
A=1
ST3
A=0
Z=0 when A=0 or A=1
The behaviour of this machine can also be described by
a table as shown. In this table, the next states and the
value of the output Z are shown inside the boxes. The
current values are shown outside.
One way to implement this state machine in VHDL is to
go through the process that we discussed in MEL5101
to design a circuit with flip-flops and gates, and then to
implement that circuit in VHDL (data flow or structural
modeling).
However, because VHDL is capable of modeling behaviour, it is possible to model a state machine in a
much more convenient way. One possible VHDL code
is shown here.
First consider the two statements
type state_type is (ST0,ST1,ST2,ST3);
signal pstate, nstate: state_type;
The first statement here defines a new data type called
state_type with four possible values “ST0”, “ST1”, “ST2”
and “ST3”. (In VHDL, user defined data types are allowed. See section 2.2 of VHDL Cookbook for details).
In the second statement, two signals of type state_type
- pstate (to represent present state) and nstate (to represent the next state) - are defined. The ability to refer
to a state by name - ST0, ST1 etc. - is more convenient
than using a notation like 00, 01 etc.
In the architecture of this code, there are two process
statements. The first one which represents the state
memory is only sensitive to the clock. At every rising
edge of the clock, it changes from the present state to
the next state.
For any given state and input value A, the next state is
determined by the second process. This process is sensitive to the two signals A and pstate. Every time the
input A changes or the present state changes, this process is activated and the next state is evaluated. This
next state is used by the first process at the next rising
edge of the clock to change to a new state.
4
library IEEE;
use IEEE.std_logic_1164.all;
entity mealysm is port(
CLOCK, A: in std_logic;
Z: out std_logic);
end;
architecture smarch of mealysm is
type state_type is (ST0,ST1,ST2,ST3);
signal pstate, nstate: state_type;
begin
process(CLOCK)
begin
if CLOCK’event and CLOCK = ’1’ then
pstate <= nstate;
end if;
end process;
process (A, pstate)
begin
case pstate is
when ST0 =>
if A = ’1’ then
Z <= ’1’;
nstate <= ST3;
else Z <= ’0’;
end if;
when ST1 =>
if A = ’1’ then
Z <= ’0’;
nstate <= ST0;
else Z <= ’1’;
end if;
when ST2 =>
if A = ’1’ then
Z <= ’1’;
nstate <= ST1;
else Z <= ’0’;
end if;
when ST3 =>
Z <= ’0’;
if A = ’1’ then
nstate <= ST1;
else nstate <= ST2;
end if;
end case;
end process;
end smarch;
Design of a Moore Machine
In this case, let us consider a problem specified in words - not as a state diagram.
Design a clocked synchronous state machine with two inputs A and B and a single output Z that is 1 if
A had the same value at each of the two previous clock ticks or B has been 1 since the last time that the first
condition was true. Otherwise, the output should be 0.
The timing diagram below shows some possible situations with this circuit.
clock
A
B
Z
00
01
00
01
X0
In order to design the circuit, we must first identify the
00
states. One possible set of states we can use for this
01
purpose are:
INIT
INIT: Initial state
11
X0: Got A=0
10
X1: Got A=1
Y0: Got two equal, last one 0
Y1: Got two equal, last one 1
For this, we can make the following state transition table
and the state diagram.
Y0
10
10
11
11
00
01
X1
00
10
11
01
Y1
10
11
A VHDL code for this circuit is shown below. As before, there are two processes. The first one represents the
state memory and the second one represents the next state logic.
library IEEE;
use IEEE.std_logic_1164.all;
entity sm is port(
CLOCK, A, B: in std_logic;
Z: out std_logic);
end;
5
architecture smarch of sm is
type state_type is (INIT,X0,X1,Y0,Y1);
signal pstate, nstate: state_type;
begin
process(CLOCK)
begin
if CLOCK’event and CLOCK = ’1’ then
pstate <= nstate;
end if;
end process;
process (A, B, pstate)
begin
case pstate is
when INIT =>
if A = ’0’ then
nstate <= X0 ;
else nstate <= X1;
end if;
when X0 =>
if A = ’0’ then
nstate <= Y0;
else nstate <= X1;
end if;
when X1 =>
if A = ’0’ then
nstate <= X0;
elseif A = ’1’ and B = ’0’ then
nstate <= X1;
else nstate <= Y1;
end if;
when Y1 =>
if A = ’0’ and B = ’0’ then
nstate <= X0;
elseif A = ’0’ and B = ’1’ then
nstate <= Y0;
else nstate <= Y1;
end if;
when others =>
nstate <= INIT;
end case;
end process;
with pstate select
Z <= ’0’ when INIT|X0|X1,
’1’ when Y0|Y1,
’0’ when others;
end smarch;
The same state machine can also be designed without going through a state diagram. In this method, we
directly focus on the expected behaviour.
At any give time, the system can be in one of the three states - INIT, LOOKING (looking for the expected
pattern) and OK (the expected pattern found). In order to check whether A had the same value twice, the last
value of A is stored in the signal lastA.
When the system is in INIT, the next state is LOOKING, irrespective of the input values. When it is in
LOOKING, if A = lastA, the next state is OK. otherwise, next state is again LOOKING. When in state OK,
if B=1, again, the next state is OK, otherwise it should go to LOOKING.
architecture smarch2 of sm is
type state_type is (INIT,LOOKING,OK);
signal pstate, nstate: state_type;
signal lastA: std_logic;
begin
process(CLOCK)
begin
if CLOCK’event and CLOCK = ’1’ then
if RESET = ’1’ then
pstate <= INIT;
lastA <= ’0’;
else
pstate <= nstate;
lastA <= A;
end if;
end if;
end process;
process (A, B, lastA, pstate)
begin
case pstate is
when INIT => nstate <= LOOKING ;
when LOOKING => if A = lastA then snext
<= OK;
else nstate <= LOOKING;
end if;
when OK => if B = ’1’ then nstate <= OK;
elseif A = lastA then nstate <= OK;
else nstate <= LOOKING;
end if;
when others => nstate <= INIT;
end case;
end process;
with pstate select
Z <= ’1’ when OK,
’0’ when others;
end smarch2;
6