genericでモジュールをパラメタライズする

pp.29-31

genericでパラメタライズしておけば、別のモジュールで実体化するときに、そのgenericに別に値を割り当てることができる。

下のコードはほぼテキストのままである。48 MHzクロックをモジュロ48 Mのカウンターでカウントし、それがオーバーフローするたびに(すなわち1秒ごとに)、7セグに表示する値を1インクリメントする。同じようなコードはこれまで何度か実行してきたので難しいところはない。

seven_segment_pkg

library ieee;
use ieee.std_logic_1164.all;

package seven_segment_pkg is
    function int_to_seven_seg(digit: natural range 0 to 9) return std_logic_vector;
end package;

package body seven_segment_pkg is
    function int_to_seven_seg(digit: natural range 0 to 9) return std_logic_vector is
    begin
        case digit is
           --               "gfedabc" アノードコモン
            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 others => return "0111111"; -- ハイフン
        end case;
    end function;
end package body;

本体

library ieee;
use ieee.std_logic_1164.all;
use work.seven_segment_pkg.all;

entity slow_counter is
    generic(
        CLOCK_FREQ: natural := 48e6
    );
    port(
        clock, reset_n: in  std_logic;
        seven_seg     : out std_logic_vector(6 downto 0)
    );
end;

architecture rtl of slow_counter is
    signal digit: natural range 0 to 9;
begin
    process(clock, reset_n)
        constant COUNT_MAX: natural := CLOCK_FREQ - 1;
        variable count: natural range 0 to COUNT_MAX := 0;
    begin
        if reset_n = '0' then -- リセットはLo有意にした。
            count := 0;
            digit <= 0;
        elsif rising_edge(clock) then
            if count < COUNT_MAX then
                count := count + 1;
            else -- 48 MHzカウンターがオーバーフローしたら
                count := 0;
                if digit < 9 then
                    digit <= digit + 1; -- 7セグディスプレイを1インクリメントする。
                else
                    digit <= 0;
                end if;
            end if;
        end if;
    end process;
    seven_seg <= int_to_seven_seg(digit);
end;