BCD出力タイマー

pp.303-305

00秒から59秒までカウントするタイマーを作る。

バイナリーカウンターでカウントしてからBCDに変換するのではなく、10進1桁ごとに4ビットBCDカウンターを設けて出力する。ここではアノードコモン1桁を2個使った。ダイナミック点灯はせずに個別にドライブした。

library ieee;
use ieee.std_logic_1164.all;

entity timer is
    generic(
        F_CLK: integer := 1000
    );
    port(
        clk, ena      : in  std_logic;
        digit1, digit2: out std_logic_vector(6 downto 0)
    );
end entity;

architecture rtl of timer is
    constant MODULO_0: natural := F_CLK;
    constant MODULO_1: natural :=    10;
    constant MODULO_2: natural :=     6;
    
    function int_to_ssd (input: integer) return std_logic_vector is
    begin
        case input is          -- gfedabc, anode common.
            when  0     => return "1000000";
            when  1     => return "1111100";
            when  2     => return "0100001";
            when  3     => return "0110000";
            when  4     => return "0011100";
            when  5     => return "0010010";
            when  6     => return "0000010";
            when  7     => return "1111000";
            when  8     => return "0000000";
            when  9     => return "0010000";
            when 10     => return "0001000";
            when 11     => return "0000110";
            when 12     => return "1000011";
            when 13     => return "0100100";
            when 14     => return "0000011";
            when 15     => return "0001011";
            when others => return "0111111";
        end case;
    end function;

begin
    process(clk)
        variable count0: natural range 0 to MODULO_0;
        variable count1: natural range 0 to MODULO_1;
        variable count2: natural range 0 to MODULO_2;
    begin
        if rising_edge(clk) and (ena='1')then

                count0 := count0 + 1;    -- クロックカウンターをインクリメントして、
                if count0 = MODULO_0 then  -- クロックカウンターがモジュロに達したら、
                    count0 := 0;            -- クロックカウンターをリセットすると同時に、
                    count1 := count1 + 1;     -- 1桁目カウンターをインクリメントして、
                    if count1 = MODULO_1 then -- 1桁目カウンターがモジュロに達したら、
                        count1 := 0;             -- 1桁目カウンターをリセットすると同時に、
                        count2 := count2 + 1;    -- 2桁目タウンターをインクリメントして、
                        if count2 = MODULO_2 then  -- 2桁目カウンターがモジュロに達したら、
                            count2 := 0;            -- 2桁目カウンターをリセットする。
                        end if;
                    end if;
                end if;

        end if;
        digit1 <= int_to_ssd(count1);
        digit2 <= int_to_ssd(count2);
    end process;
end architecture;