ALUをVHDLで書き換える

『CPUの創りかた』のときと同じくCPU1738も全部VHDLで書き換えてみる。また、トライステートバッファーで実現していたバス選択はマルチプレクサに置き換える。

まずはALU (pp.118-120)から。基本的には加減算器。0出力、Aスルー、Bスルー、-Bスルーの各機能も備える。

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity alu is
    generic(
        NUM_BITS: natural := 4
    );
    port(
        a: in std_logic_vector(NUM_BITS-1 downto 0);
        b: in std_logic_vector(NUM_BITS-1 downto 0);
        
        mux_a: in std_logic;
        mux_b: in std_logic;

        as        : in std_logic; -- when 0, add; when 1, sub;
        ld        : in std_logic;
        clk_inside: in std_logic;
        aclr_n    : in std_logic;
    
        add_sub: out std_logic_vector(NUM_BITS-1 downto 0);
        zero   : out std_logic;
        cout   : out std_logic
    );
end entity;

architecture rtl of alu is
    signal a_temp   : unsigned(NUM_BITS-1 downto 0);
    signal b_temp   : unsigned(NUM_BITS-1 downto 0);
    signal calc_temp: unsigned(NUM_BITS   downto 0);
begin

    a_temp <=
        (others => '0') when mux_a = '0' else -- mux_aが0ならオペランドaを強制的に0にし、
        unsigned(a);

    b_temp <=
        (others => '0') when mux_b = '0' else -- mux_bが0ならオペランドbを強制的に0にし、
        0-unsigned(b)   when as    = '1' else -- 引き算のときはオペランドbを2の補数にし、
        unsigned(b);
    
    calc_temp <= ('0' & a_temp) + b_temp; -- 1ビット拡張して和(差)を計算して、

    process(clk_inside)
    begin
        
        if aclr_n = '0' then
           -- 非同期クリアして、
            add_sub <= (others => '0');
        else
           -- 和(差)を非同期更新して、
            add_sub <= std_logic_vector(calc_temp)(NUM_BITS-1 downto 0);
        
            if rising_edge(clk_inside) then
                if ld then
                   -- キャリーアウトを同期更新して、
                    cout <= calc_temp(NUM_BITS);

                   -- ゼロフラグを同期更新する。
                    if calc_temp(NUM_BITS-1 downto 0) = 0 then
                        zero <= '1';
                    else
                        zero <= '0';
                    end if;

                end if;
            end if;

        end if;
    end process;
end architecture;