Файл: Digital design with CPLD applications and VHDL (R. Dueck, 2000).pdf

ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 13.06.2025

Просмотров: 8062

Скачиваний: 6

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.

404 C H A P T E R 9 • Counters and Shift Registers

Behavioral Description

The following lists the VHDL code for an 8-bit bidirectional counter with count enable, terminal count decoding, and asynchronous load and clear:

ENTITY pre_ct8a IS

PORT (

clk, count_ena

: IN

BIT;

clear, load, direction

: IN

BIT;

p

: IN

INTEGER RANGE 0 TO 255;

max_min

: OUT

BIT;

qd

: OUT

INTEGER RANGE 0 TO 255);

END pre_ct8a;

ARCHITECTURE a OF pre_ct8a IS

BEGIN

PROCESS (clk, clear, load)

VARIABLE cnt : INTEGER RANGE 0 TO 255;

BEGIN

IF (clear = ‘0’) THEN

—— Asynchronous clear

cnt := 0;

ELSIF (load = ‘1’ and clear = ‘1’) THEN —— Asynchronous load

cnt := p;

pre_ct8a.vhd

clk = ‘1’) THEN

= ‘1’ and direction = ‘0’) THEN

cnt := cnt - 1;

ELSIF (count_ena = ‘1’ and direction = ‘1’) THEN

cnt := cnt + 1;

END IF;

END IF;

END IF;

qd <= cnt;

—— Terminal count decoder

IF (cnt = 0 and direction = ‘0’) THEN

max_min <=

‘1’;

ELSIF (cnt = 255 and direction = ‘1’) THEN

max_min <=

‘1’;

ELSE

max_min <=

‘0’;

END IF;

END PROCESS;

END a;

The load and clear functions of this counter are asynchronous, so these identifiers are part of the sensitivity list of the PROCESS statement; the statements in the process will execute if there is a change on the clear, load, or clock inputs. Load and clear are checked by IF statements, independently of the clock. Since load and clear are checked first, they have precedence over the clock. Clear has precedence over load since load can only activate if clear is not active.

If clear and load are not asserted, the clock status is checked by a clause in an IF statement: ( IF (clk’EVENT and CLK = ‘1’) THEN). If this condition is true, then a count variable is incremented or decremented, depending on the states of a count enable input and a directional control input. If the count enable input is not asserted, the count is neither incremented nor decremented.


9.6 • Programming Presettable and Bidirectional Counters in VHDL

405

The count value is assigned to the counter outputs by the signal assignment statement (qd <= cnt;) after the clear, load, clock, count enable, and direction inputs have been evaluated. Possible results from the signal assignment are:

qd 0 (clear 0),

qd p (load 1 AND clear 1),

increment qd (count_ena 1 AND direction 1),

decrement qd (count_ena 1 AND direction 0), or

no change on qd (count_ena 0).

The terminal count is decoded by determining the count direction and value of the count variable. If the count is UP and the count value is maximum (25510 FFH) or the count is DOWN and the count value is minimum (0 00H), a terminal count decoder output called max_min goes HIGH.

The code for the same 8-bit counter, but with synchronous clear and load, is shown next.

ENTITY pre_ct8s IS

PORT (

clk, count_ena

: IN BIT;

clear, load, direction

: IN BIT;

p

: IN INTEGER RANGE 0 TO 255;

max_min

: OUT BIT;

qd

: OUT INTEGER RANGE 0 TO 255);

END pre_ct8s;

ARCHITECTURE a OF pre_ct8s IS

BEGIN

PROCESS (clk)

VARIABLE cnt : INTEGER RANGE 0 TO 255;

BEGIN

IF (clk’EVENT AND clk = ‘1’) THEN

pre_ct8s.vhd

cnt := p;

ELSIF (count_ena = ‘1’ and direction = ‘0’) THEN cnt := cnt - 1;

ELSIF (count_ena ‘1’ and direction = ‘1’) THEN cnt := cnt + 1;

END IF;

END IF;

qd <= cnt;

—— Terminal count decoder

IF (cnt = 0 and direction = ‘0’) THEN max_min <= ‘1’;

ELSIF (cnt = 255 and direction = ‘1’) THEN max_min <= ‘1’;

ELSE

max_min <= ‘0’; END IF;

END PROCESS;

END a;

The PROCESS statement in the synchronous counter has only one identifier in its sensitivity list—that of the clock input. Load and clear status are not evaluated until after the


406 C H A P T E R 9 • Counters and Shift Registers

pre_ct8a.scf

FIGURE 9.48

Simulation Detail of 8-bit VHDL Counter (Bidirectional with Terminal Count Detection)

process checks for a positive clock edge. Otherwise the code is the same as for the asynchronously loading counter.

Figure 9.48 shows a detail of a simulation of the asynchronously loading counter. It shows the point where the count rolls over from FFH to 00H and activates the max_min output. The directional output changes shortly after this point and shows the terminal count decoding for a DOWN count, the point where the counter rolls over from 00H to FFH. In the UP count, max_min is HIGH when the counter output is FFH, but not 00H. In the DOWN count, max_min goes HIGH when the counter output is 00H, but not FFH.

Figure 9.49 shows the operation of the asynchronous load and clear functions. Figure 9.50 show the synchronous load and clear. The inputs are identical for each simulation; each has two pairs of load pulses and a pair of clear pulses. The first pulse of each pair is arranged so that it immediately follows a positive clock edge; the second pulse of each pair immediately precedes a positive clock edge.

In the counter with asynchronous load and clear, these functions are activated by the first pulse of each pair and again on the second pulse. For the counter with synchronous load and clear, only the second pulse of each pair has an effect, since the load and clear functions must be active during or just prior to an active clock edge, in order to satisfy

FIGURE 9.49

Simulation Detail of 8-bit VHDL Counter with Asynchronous Load and Clear

9.6 • Programming Presettable and Bidirectional Counters in VHDL

407

FIGURE 9.50

Simulation Detail of 8-bit VHDL Counter with Synchronous Load and Clear

setup-time requirements of the counter flip-flops. The end of the load and clear pulse can correspond to the positive clock edge, as the flip-flop hold time is zero.

Also note that the counter with synchronous load and clear has no intermediate glitch states on its outputs. (The simulation for the asynchronously loading counter shows glitch states on output qd at 21.04 s, 21.10 s, 21.22 s, and 21.44 s. Refer to the section on Synchronous versus Asynchronous Circuits in Chapter 7 for further discussion of intermediate states in asynchronous circuits.)

Figures 9.51 and 9.52 show further simulation details for our two VHDL counters. Both show the priority of the load, clear, and count enable functions. Both diagrams show that load and clear are independent of count enable and that clear has precedence over load. Again note that the counter with synchronous load and clear is free of intermediate glitch states.

FIGURE 9.51

Simulation Detail of 8-bit VHDL

Counter Showing Priority of

Count Enable, Asynchronous

Load, and Asynchronous Clear

FIGURE 9.52

Simulation Detail of 8-bit VHDL

Counter Showing Priority of

Count Enable, Synchronous

Load, and Synchronous Clear


408 C H A P T E R 9 • Counters and Shift Registers

LPM Counters

Earlier in this chapter, we saw how a parameterized counter from the Library of Parameterized Modules (LPM) could be used as a simple 8-bit counter. The component lpm_counter has a number of other functions that can be implemented using specific ports and parameters. These functions are indicated in Table 9.13.

Table 9.13 Available Functions of an LPM counter

Function

Ports

Parameters

Description

Basic count operation

clock, q []

LPM_WIDTH

Output q[] increases by one with each positive clock edge.

LPM_WIDTH is the number of output bits.

Synchronous load

sload, data []

none

When sload 1, output q[] goes to the value at input data[]

on the next positive clock edge. data[] has the same width

as q[].

Synchronous clear

sclr

none

When sclr 1, output q[] goes to zero on positive clock

edge.

Synchronous set

sset

LPM_SVALUE

When sset 1, output goes to value of LPM_SVALUE on

positive clock edge. If LPM_SVALUE is not specified, q[]

goes to all 1s.

Asynchronous load

aload, data[]

none

Output goes to value at data[] when aload 1.

Asynchronous clear

aclr

none

Output goes to zero when aclr 1.

Asynchronous set

aset

LPM_AVALUE

Output goes to value of LPM_AVALUE when aset 1.

If LPM_AVALUE is not specified, outputs all go HIGH

when aset 1.

Directional control

updown

LPM_DIRECTION

Optional direction control. Default direction is UP. Only one

of updown and LPM_DIRECTION can be used.

updown 1 for UP count, updown 0 for DOWN count.

LPM_DIRECTION “UP”, “DOWN”, or “DEFAULT”

Count enable

cnt_en

none

When cnt_en 1, count proceeds upon positive clock edges.

No effect on other synchronous functions (sload, sclr, sset).

Defaults to “enabled” when not specified.

Clock enable

clk_en

none

All synchronous functions are enabled when clk_en 1.

Defaults to “enabled” when not specified.

Modulus control

none

LPM_MODULUS

Modulus of counter is set to value of LPM_MODULUS

Output decoding

eq[15..0]

none

Sixteen active-HIGH decoded outputs, one for each internal

(GDF or AHDL only;

counter value from 0 to 15.

not available in VHDL)

The only ports that are required by an LPM counter are clock, and one of q[] (counter outputs) or eq[] (decoder outputs). The only required parameter is LPM_WIDTH, which specifies the number of counter output bits. All other ports and parameters are optional, although certain ones must be used together. (For instance, ports sload and data[] are optional, but both must be used for the synchronous load function.) If unused, a port or parameter will be held at a default logic level.

To use any of the functions of an LPM component in a VHDL file, we use a component instantiation statement and specify the required parameters in a generic map and the ports in a port map.


9.6 •

Programming Presettable and Bidirectional Counters in VHDL

409

N O T E

The VHDL component declaration, shown below, indicates that all parameters

except LPM_WIDTH are defined as having type STRING, which requires

the parameter value to be written in double quotes, even if numeric. (e.g,

LPM_MODULUS => “12”). Since LPM_WIDTH is defined as type POSITIVE (i.e.,

any integer 0) it must be written without quotes (e.g., LPM_WIDTH => 8).

Default values of all ports and parameters are also included in the component decla-

ration (e.g.,

clk_en: IN STD_LOGIC := ‘1’; the default value of the clock en-

able input is ‘1’). The LPM component declaration can also be found in the

MAX PLUS II Help menu (Help; Megafunctions/LPM; lpm_counter).

VHDL Component Declaration for lpm_counter:

COMPONENT lpm_counter

GENERIC (LPM_WIDTH: POSITIVE;

LPM_MODULUS: STRING := “UNUSED”;

LPM_AVALUE: STRING:= “UNUSED”;

LPM_SVALUE: STRING := “UNUSED”;

LPM_DIRECTION: STRING := “UNUSED”;

LPM_TYPE: STRING := “L_COUNTER”;

LPM_PVALUE: STRING := “UNUSED”;

LPM_HINT : STRING := “UNUSED”);

PORT (data: IN STD_LOGIC_VECTOR (LPM_WIDTH-1 DOWNTO 0) := (OTHERS => ‘0’);

clock: IN STD_LOGIC;

cin: IN STD_LOGIC := ‘0’;

clk_en: IN STD_LOGIC := ‘1’;

cnt_en: IN STD_LOGIC := ‘1’;

updown: IN STD_LOGIC := ‘1’

sload: IN STD_LOGIC := ‘0’;

sset: IN STD_LOGIC := ‘0’;

sclr: IN STD_LOGIC := ‘0’;

aload: IN STD_LOGIC := ‘0’;

aset: IN STD_LOGIC := ‘0’;

aclr: IN STD_LOGIC := ‘0’;

cout: OUT STD_LOGIC;

q: OUT STD_LOGIC_VECTOR (LPM_WIDTH-1 DOWNTO 0) );

END COMPONENT;

EXAMPLE 9.8

Write a VHDL file for an 8-bit LPM counter with ports for the following functions: asyn-

chronous load, asynchronous clear, directional control, and count enable.

Solution The required VHDL file is shown below. Note that no behavioral descriptions are required for the functions, only a mapping from the defined port names to the entity inputs and outputs.

—— pre_lpm8

—— 8-bit presettable counter with asynchronous clear and load, —— count enable, and a directional control port

LIBRARY ieee;

USE ieee.std_logic_1164.ALL;

LIBRARY lpm;

USE lpm.lpm_components.ALL;