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;