今度はA、B、OUTの各レジスタとPC (pp.115-118)。『CPUの創りかた』のときと同じく、まず共通のカウンター兼レジスターを作っておく(このとき作った74161のようなものからリプルキャリーアウト機能を省いたもの)。それを4つまとめて実体化する。
共通のカウンター兼レジスター:
library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity counter_register is generic( NUM_BITS: natural := 4 ); port( clk : in std_logic; aclr_n: in std_logic; sload : in std_logic; d : in std_logic_vector(NUM_BITS-1 downto 0); ena_count: in std_logic; q: out std_logic_vector(NUM_BITS-1 downto 0) ); end entity; architecture rtl of counter_register is signal count: natural range 0 to 2**NUM_BITS-1; -- この変数をカウンターとして使う。 constant COUNT_MAX: natural := 2**NUM_BITS-1; -- カウンターのトップ値。 begin -- カウント値をそのまま出力する。 q <= std_logic_vector(to_unsigned(count, NUM_BITS)); process(all) begin -- !非同期リセット if aclr_n = '0' then count <= 0; elsif rising_edge(clk) then -- 同期ロード if sload then count <= to_integer(unsigned(d)); -- 同期カウント elsif ena_count then if count >= COUNT_MAX then count <= 0; else count <= count + 1; end if; end if; end if; end process; end architecture;
それ4つ組み合わせる:
library ieee; use ieee.std_logic_1164.all; entity registers is generic( NUM_BITS: natural := 4 ); port( inp: in std_logic_vector(NUM_BITS-1 downto 0); a_reg_ld: in std_logic; b_reg_ld: in std_logic; out_ld : in std_logic; pc_ld : in std_logic; clk_inside: in std_logic; aclr_n : in std_logic; pc_up: in std_logic; a_reg : out std_logic_vector(NUM_BITS-1 downto 0); b_reg : out std_logic_vector(NUM_BITS-1 downto 0); out_reg: out std_logic_vector(NUM_BITS-1 downto 0); pc : out std_logic_vector(NUM_BITS-1 downto 0) ); end entity; architecture rtl of registers is begin -- A_REGを実体化 a_register: entity work.counter_register generic map( NUM_BITS => NUM_BITS ) port map( clk => clk_inside, aclr_n => aclr_n, sload => a_reg_ld, d => inp, ena_count => '0', -- カウンターを無効化 q => a_reg ); -- B_REGを実体化 b_register: entity work.counter_register generic map( NUM_BITS => NUM_BITS ) port map( clk => clk_inside, aclr_n => aclr_n, sload => b_reg_ld, d => inp, ena_count => '0', -- カウンターを無効化 q => b_reg ); -- OUT_REGを実体化 out_register: entity work.counter_register generic map( NUM_BITS => NUM_BITS ) port map( clk => clk_inside, aclr_n => aclr_n, sload => out_ld, d => inp, ena_count => '0', -- カウンターを無効化 q => out_reg ); -- PCを実体化 program_counter: entity work.counter_register generic map( NUM_BITS => NUM_BITS ) port map( clk => clk_inside, aclr_n => aclr_n, sload => pc_ld, d => inp, ena_count => pc_up, -- カウンターを有効化 q => pc ); end architecture;