TITLE: Two Digit Hex Counter Code
AUTHOR: Chuck McManis
LAST UPDATE: 05-Apr-2001

Description

This is the solution I came up with for the HEX Counter problem. See Image 1 below for a drawing of the “logical” schematic of the result.

The specification called for an 8 bit counter that displayed its count on two hexadecimal displays. The input is again 24Mhz and the counter operates at 10Hz.

Things I learned from this project:


Schematic Drawing of the Solution

In the schematic above, the various logical parts are labeled as they are in the VHDL code. The CLOCK_10HZ part is “U1”, the HEX_DISPLAY parts are “U2” and “U3.” The process block that defines the counter is labeled “INCREMENT.”

Note that the BLANK and TEST inputs are not connected. In the VHDL code I had to use a bogus signal declaration in order to achieve that effect. With the WebPACK compiler (XST VHDL) you can just put the constant ‘0’ or ‘1’ in the port map and it does the right thing with them.

The Source Code

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity hex_counter is
    Port ( src_clk : in std_logic;
           dir : in std_logic;
           run : in std_logic;
           clr : in std_logic;
           display0 : out std_logic_vector(6 downto 0);
           display1 : out std_logic_vector(6 downto 0);
              digit : out std_logic_vector(7 downto 0));
end hex_counter;

architecture behavioral of hex_counter is

    component hex_display port (
        test, blank : in std_logic;
        data : in std_logic_vector(3 downto 0);
        segs : out std_logic_vector(6 downto 0));
    end component;

    component clock_10hz port (
        clk_in, reset : in std_logic;
        clk_out : out std_logic);
    end component;

    signal clk : std_logic;
    signal count : std_logic_vector(7 downto 0);
    -- bogus
    signal xx : std_logic;
    signal rotator : std_logic_vector(7 downto 0);

begin
    xx <= '0'; -- this is a "false" constant...
    -- create instances of the clock divider and displays, and then attach
    -- them to the signals we are using.
    u1: clock_10hz port map (clk_in => src_clk, clk_out => clk, reset => clr);
    u2: hex_display port map (test => xx, blank => xx,
            data => count(7 downto 4), segs => display0);
    u3: hex_display port map (test => xx, blank => xx,
            data => count(3 downto 0), segs => display1);

    disp: process (clk) is
    begin
        if (clr = '0') then
            rotator <= "00000001";
        elsif rising_edge(clk) then
            rotator <= rotator(6 downto 0) & rotator(7);
        end if;
    end process;

    digit <= rotator;

   increment: process (clk, clr, run, dir) is
    begin
        if (clr = '0') then
            count <= "00000000";
       elsif (rising_edge(clk) and run = '1') then
            if (dir = '1') then
                count <= count + "00000001";
            else
                count <= count - "00000001";
            end if;
        end if;
    end process;
end behavioral;

License

Creative Commons License

This work is licensed under a Creative Commons Attribution-NonCommercial 3.0 Unported License. You are free to play around with it and modify it but you are not licensed to use it for commercial purposes. Click the link above for more details on your rights under this license.