Lec5 Process.pptx
Lec5 Process.pptx
1
EN E O
CLK F Vcc
0
• All the VHDL constructs and statements seen so far
(assignments, logic operators, when/else, with/select)
apply to combinational logic and execute concurrently.
• To implement sequential logic, however, concurrent execution is
not appropriate – values change depending on control
signals (e.g. the clock) in a timed conditional sequence.
• To impose a sequence in the execution of VHDL code, the
instructions must be embedded into a process. A process is a
region of VHDL code within an architecture that executes
sequentially.
Sequential statements
Key word
Processes: format
List of signals that
this process is
sensitive to
label: PROCESS (sensitivity list)
All declarations
BEGIN
sequential statement 1;
sequential statement 2;
:
:
sequential statement n;
if x="0000" then
In a properly-written z <= a;
synthesizable process, if x<"0101" then
all if-then-else clauses z <= b;
else
are nested z <= c; BAD
end if;
Sequential statements
The case statement takes a different branch depending on
the value of a signal case S is
CASE object IS when "00" =>
O <= A;
WHEN value_1 => when "01" =>
-- sequential statements O <= B;
WHEN value_2 => when others =>
-- sequential statements null;
… end case;
WHEN OTHERS => Catch-all
-- sequential statements condition (good
END CASE; coding practice)
The keyword null is used when no action is to be taken
Note that the values tested can be of different formats:
when "00" => -- specific binary
E D Action
0 0 keep state (Q <= Q)
element: process
begin BEST
if (rising_edge(clk)) then […]
Clock D Qnext CK
D D Q
Rising edge 0 0
F D
Rising edge 1 1
CLK F Q
Non-Rising X Q
Example: posedge triggered D-type FF
entity posedgeD_FF is
port (CLK, D : in STD_LOGIC; Only CLK in sensitivity list
Q : out STD_LOGIC);
end posedgeD_FF;
Non-Rising X X Q Q
Example: posedge triggered D-type FF with synchronous reset
Only CLK in
DFF: process (CLK) sensitivity list
begin
if (rising_edge(CLK)) then Reset tested
if (RST='1') then immediately
Q <= ‘0’; after clock
else
Q <= D;
end if; Reset value –
end if; usually (but
end process DFF; not always) 0
The reset (clear) signal
• Asynchronous clear ONLY WHEN
NECESSARY
Clock D C Qnext CK
D D Q
Rising edge 0 0 0
F C
C Rising edge 1 0 1
CLK F Non-Rising X 0 Q
D
X X 1 0 Q
Example: posedge triggered D-type FF with asynchronous clear
CLK and CLR in
DFF: process (CLK,CLR) sensitivity list
begin
if (CLR='1') then Clear tested
Q <= ‘0’; immediately
else before clock
if (rising_edge(CLK)) then
Q <= D;
end if;
end if;
end process DFF;
The enable signal
• Clocks and clock distribution networks are one of the
most sensitive areas of digital circuit design. Usually,
complex devices rely on dedicated lines to distribute the
clock signal to all parts of a circuit with minimum delay
• As a consequence, it is very bad design practice to
apply any logic to a clock signal: all clocked elements in
a design should operate directly on the clock signal
• To control the operation of a clocked element (for
example, to make it memorize the input only at certain
times), an enable signal should always be used instead
of changing the clock
• Enable signals are always synchronous (the enable the
clock!) and have lower priority compared to reset
The enable signal
Clock D R E Qn CK
D D Q
E R
F Rising edge 0 0 1 0
R Rising edge 1 0 1 1 E
CLK F
Rising edge X 0 0 Q D
Rising edge X 1 X 0
Q
Non-Rising X X X Q
Example: posedge triggered D-type FF
with synchronous reset and enable Only CLK in
DFF: process (CLK) sensitivity list
begin
if (rising_edge(CLK)) then Enable tested
if (RST='1') then after clock
Q <= ‘0’; and reset
else Q <= Q is the default
if (EN = '1') then
behaviour (no need
Q <= D;
end if; for “else”)
end if;
end if;
end process DFF; NOTE THAT ALL “IF” STATEMENTS ARE NESTED!
1st year digital logic
Q
D D Q D D Q
D
RST R RST R
F F DFF1: process (CLK)
CLK F F begin
CLK2 if (rising_edge(CLK)) then
(100Mhz)
(50Mhz) if (RST = '1') then
CLK2 <= '0';
else
CLK2 <= not CLK2;
end if;
end if;
end process DFF;
entity D_FF is
port (CLK, Data_in, RST, EN : in STD_LOGIC;
Q : out STD_LOGIC);
end D_FF;
Only clock in sensitivity
architecture arch of D_FF is list (fully synchronous
begin process – nothing
DFF: process (CLK) happens unless there is a
begin rising edge in the clock)
if (rising_edge(CLK)) then
if (RST = '1') then
Q <= '0';
elsif (EN = '1') then
Q <= Data_in;
end if;
end if;
end process DFF;
end arch;
DFF with clear and no enable
entity D_FF is
port (CLK, Data_in, CLR : in STD_LOGIC;
Q : out STD_LOGIC);
end D_FF;
entity REG_8BIT is
port (CLK, RST, WEN : in STD_LOGIC;
Data: in STD_LOGIC_VECTOR(7 downto 0);
Q : out STD_LOGIC_VECTOR(7 downto 0));
end REG_8BIT;
A multi-bit sequential
architecture arch of REG_8BIT is component is
begin identical to a
REG8: process (CLK) single-bit one, except
begin it is applied to vectors
if (rising_edge(CLK)) then
if (RST = '1') then
Q <= (others => '0'); More on this
elsif (WEN = '1') then syntax later
Q <= Data;
end if;
end if;
end process REG8;
end arch;
Bidirectional 16-bit shift register with load
entity SREG_16BIT is
port (CLK,LD,SH,DIR,RST: in STD_LOGIC;
Data: in STD_LOGIC_VECTOR(15 downto 0);
Q : out STD_LOGIC_VECTOR(15 downto 0));
end SREG_16BIT;
architecture arch of SREG_16BIT is
signal Qint : STD_LOGIC_VECTOR(15 downto 0);
begin
SREG16: process
begin
if (rising_edge(CLK)) then
if (RST = '1') then
Qint <= (others => '0');
elsif (LD = '1') then Why do we
Qint <= Data; need this?
elsif (SH = '1') then
if (DIR = '1') then
Qint(15 downto 1) <= Qint(14 downto 0);
Qint(0) <= '0';
else
Qint(14 downto 0) <= Qint(15 downto 1);
Qint(15) <= '0';
end if;
end if;
end if;
end process SREG16;
Q <= Qint; STILL ALL “IF” STATEMENTS ARE NESTED!
end arch;
A note on coding style
The examples you have
seen are just that – entity design is
port (CLK, A, RST, EN : in STD_LOGIC;
examples. You don’t need O : out STD_LOGIC);
end design;
or normally want to use a
complete entity for every architecture arch of design is
signal Q : std_logic;
sequential component – begin
processes can be part of DFF: process (CLK)
an architecture together begin
if (rising_edge(CLK)) then
with combinational logic if (RST = '1') then
Q <= '0';
elsif (EN = '1') then
Q <= not Q;
end if;
end if;
Q0 end process DFF;
D D Q
RST RST O <= A when Q = '1' else '1';
F A
1
EN EN O end arch;
CLK F Vcc
0
A note on coding style
If you implement multiple
sequential elements in an entity design is
port (CLK, A, RST, EN : in STD_LOGIC;
architecture, you can use O : out STD_LOGIC);
end design;
a single process – if all the
elements have the same architecture arch of design is
signal Q0, Q1 : std_logic;
control signals (clock, begin
reset, enable) – BUT YOU DFF: process (CLK)
DON’T HAVE TO! begin
if (rising_edge(CLK)) then
if (RST = '1') then
Q0 Q0 <= '0';
D D Q Q1 <= '1';
RST RST elsif (EN = '1') then
F A Q0 <= not Q0;
1
EN EN O Q1 <= A;
CLK F end if;
0
end if;
A D D Q Q1 end process DFF;
=========================================================================
HDL Synthesis Report
Macro Statistics
# Latches :1
1-bit latch :1
=========================================================================
Synthesizable VHDL - Processes
• This can be fixed easily: • But multiplexers are
COMBINATIONAL LOGIC:
ok_mux: PROCESS (a,b,c,s) IS
BEGIN o <= a WHEN s = "00" ELSE
IF (s(0) = '0') THEN b WHEN s = "10" ELSE
IF (s(1) = '0') THEN c WHEN s = "11" ELSE
o <= a; a WHEN s = "01" ELSE
ELSE 'U';
o <= b;
END IF; • or:
ELSE
IF (s(1) = '1') THEN WITH s SELECT
o <= c; o <= a WHEN "00",
ELSE b WHEN "10",
o <= a; c WHEN "11",
END IF; a WHEN "01",
END IF; 'U' WHEN OTHERS;
END PROCESS;
Combinational vs sequential logic
NEVER USE PROCESSES FOR
COMBINATIONAL LOGIC!
This does not mean that there cannot be combinational logic
inside a process:
DFF: process (CLK)
begin
if (rising_edge(clk)) then
D Q if (RST = '1') then
A Q <= '0';
elsif (EN = '1') then
RST Q <= (not Q) and A;
end if;
CLK end if;
end process DFF;
The rule is simple: for any assignment inside a process, the
left-hand side should always be the output of a sequential
element (the right hand side, however, is fair game...)