This website uses cookies. By using this site, you consent to the use of cookies. For more information, please take a look at our Privacy Policy.
Home > FPGA Technical Tutorials > Design Recipes for FPGAs Using Verilog and VHDL > Counters > Basic Binary Counter using VHDL

TABLE OF CONTENTS

Xilinx FPGA FPGA Forum

Basic Binary Counter using VHDL

FONT SIZE : AAA

The simplest counter to implement in many cases is the basic binary counter. The basic structure of a counter is a series of flip-flops (a register), that is controlled by a reset (to reset the counter to zero literally) and a clock signal used to increment the counter. The final signal is the counter output, the size of which is determined by the generic parameter n, which defines the size of the counter. The symbol for the counter is given in Figure 24.1. Notice that the reset is active low and the counter and reset inputs are given in a separate block of the symbol as defined in the IEEE standard format. 

From an FPGA implementation point of view, the value of generic n also defines the number of D type flip-flops required (usually a single LUT) and hence the usage of the resources in the FPGA. A simple implementation of such a counter is given here: 

1 library ieee;

2 use ieee.std_logic_1164.all;

3 use ieee.numeric_std.all;

4

5 entity counter is

6 generic (

7 n : integer := 4

8 );

9 port (

10 clk : in std_logic;

11 rst : in std_logic;

12 output : out std_logic_vector((n−1) downto 0)

13 );

14 end;

Simple binary counterpng

Figure 24.1 Simple binary counter.

15

16 architecture simple of counter is

17 begin

18 process(clk, rst)

19 variable count : unsigned((n−1) downto 0);

20 begin

21 if rst = ’0’ then

22 count := (others => ’0’);

23 elsif rising_edge(clk) then

24 count := count + 1;

25 end if;

26 output <= std_logic_vector(count);

27 end process;

28 end;

The important aspect of this approach to the counter VHDL is that this is effectively a state machine; however, we do not have to explicitly define the next state logic, as this will be taken care of by the synthesis software. This counter can now be tested using a simple test bench that resets the counter and then clocks the state machine until the counter flips round to the next counter round. The test bench is given as follows: 

1 library ieee;

2 use ieee.std_logic_1164.all;

3 use ieee.numeric_std.all;

4

5 entity CounterTest is

6 end CounterTest;

7

8 architecture stimulus of CounterTest is

9 signal rst : std_logic := ’0’;

10 signal clk : std_logic:=’0’;

11 signal count : std_logic_vector (3 downto 0);

12

13 component counter

14 port(

15 clk : in std_logic;

16 rst : in std_logic;

17 output : out std_logic_vector(3 downto 0)

18 );

19 end component;

20 for all : counter use entity work.counter ;

21

22 begin

23 DUT: counter port map(clk=>clk,rst=>rst,output=>count);

24 clk <= not clk after 1 us;

25 process

26 begin

27 rst<=’0’,’1’ after 2.5 us;

28 wait;

29 end process;

30 end;

Using this simple VHDL test bench, we reset the counter until 2.5µs and then the counter will count on the rising edge of the clock after 2µs (i.e., the counter is running at 500 kHz). 

If we dissect this model, there are several interesting features to notice. The first is that we need to define an internal variable count rather than simply increment the output variable q. The output variable q has been defined as a standard logic vector (std_logic_vector) and with it being defined as an output we cannot use it as the input variable to an equation. Therefore we need to define a local variable (in this case, count) to store the current value of the counter. 

The initial decision to make is whether to use a variable or a signal. In this case, we need an internal variable that we can effectively treat as a sequential signal, and also one that changes instantaneously, which immediately requires the use of a variable. If we chose a signal, then the changes would only take place when the cycle is resolved (i.e., the next time the process is activated). 

The second decision is what type of unit to use for the count variable. The output variable is a std_logic_vector type, which has the advantage of being an array of std_logic signals, and so we don’t need to specify the individual bits on a word; this is done automatically. The major disadvantage, however, is that the std_logic_vector does not support simple arithmetic operations, such as addition, directly. In this example, we want the counter to have a simple definition in VHDL and so the best compromise type that has the bitwise definition and also the arithmetic functionality would be the unsigned or signed type. In this case, we wish to have a direct mapping between the std_logic_vector bits and the counter bits, so the unsigned type is appropriate. Thus the declaration of the internal counter variable count is as follows: 

1 variable count : unsigned((n−1) downto 0); 

The final stage of the model is to assign the internal value of the count variable to the external std_logic_vector q. Luckily, the translation from unsigned to std_logic_vector is fairly direct, using the standard casting technique: 

Figure 24.2 Simple binary counter simulation in VHDL.

1 q <= std_logic_vector(count);
As the basic types of both q and count are consistent, this can be done directly. The resulting model simply counts up the binary values on the clock edge as specified, as is shown in Figure 24.2. 

  • XC3064XL-10VQ44C

    Manufacturer:Xilinx

  • Xilinx QFP-44
  • Product Categories:

    Lifecycle:Any -

    RoHS: -

  • XC3090-100PQ208C

    Manufacturer:Xilinx

  • FPGA XC3000 Family 6K Gates 320 Cells 100MHz 5V 208-Pin PQFP
  • Product Categories: Embedded - FPGAs (Field Programmable Gate Array)

    Lifecycle:Obsolete -

    RoHS: No RoHS

  • XC2V2000-4BG575C

    Manufacturer:Xilinx

  • FPGA Virtex-II Family 2M Gates 24192 Cells 650MHz 0.15um Technology 1.5V 575-Pin BGA
  • Product Categories: Industrial components

    Lifecycle:Obsolete -

    RoHS: No RoHS

  • XC2V2000-4FFG896C

    Manufacturer:Xilinx

  • FPGA Virtex-II Family 2M Gates 24192 Cells 650MHz 0.15um Technology 1.5V 896-Pin FCBGA
  • Product Categories: Embedded - FPGAs (Field Programmable Gate Array)

    Lifecycle:Obsolete -

    RoHS:

  • XC4003E-2PQ100C

    Manufacturer:Xilinx

  • FPGA XC4000E Family 3K Gates 238 Cells 0.35um Technology 5V 100-Pin PQFP EP
  • Product Categories: FPGAs (Field Programmable Gate Array)

    Lifecycle:Obsolete -

    RoHS: No RoHS

Need Help?

Support

If you have any questions about the product and related issues, Please contact us.